renderHanoi() 方法应该移动磁盘,方法是从 VBox 中清除磁盘,然后在每次移动后以新顺序再次添加它们,但似乎没有显示任何内容,除非它是最后一个移动,这使得一切都毫无意义。
我尝试了不同的创建延迟的方法,如 Thread.sleep、Platform.runLater 等。它们似乎都不起作用。我该如何解决这个问题?
import java.util.Arrays;
import java.util.Random;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class App extends Application {
@Override
public void start(Stage stage) {
HBox platform = new HBox();
VBox[] towerBoxes = new VBox[] { new VBox(), new VBox(), new VBox()};
platform.getChildren().addAll(Arrays.asList(towerBoxes));
Hanoi testing = new Hanoi(10);
testing.towerBoxes = towerBoxes;
var scene = new Scene(platform, 640, 480);
stage.setScene(scene);
stage.show();
testing.solve();
}
public static void main(String[] args) {
launch();
}
}
class Tower {
private int sp = 0;
private Rectangle[] disks;
Tower(int n) {
disks = new Rectangle[n];
}
public void push(Rectangle entry) {
if (sp < disks.length)
disks[sp++] = entry;
else
System.err.println(this + ".push(" + entry + ") failed, stack is full");
}
public Rectangle pop() {
if (sp > 0)
return disks[--sp];
else {
System.err.println(this + ".pop() failed, stack is empty");
return null;
}
}
public boolean hasEntry() {
return sp > 0;
}
@Override
public Tower clone() {
Tower copy = new Tower(disks.length);
copy.sp = this.sp;
copy.disks = this.disks.clone();
return copy;
}
}
class Hanoi {
Tower src;
Tower aux;
Tower dest;
int n;
public VBox[] towerBoxes;
public Hanoi(int n) {
src = new Tower(n);
aux = new Tower(n);
dest = new Tower(n);
this.n = n;
for (int i = 0; i < n; i++) {
Rectangle disk = new Rectangle(30 + 20 * i, 10);
Color diskColor = generateRandomColor();
disk.setFill(diskColor);
disk.setStroke(diskColor);
src.push(disk);
}
}
private static Color generateRandomColor() {
Random random = new Random();
double red = random.nextDouble();
double green = random.nextDouble();
double blue = random.nextDouble();
return new Color(red, green, blue, 1.0);
}
private void solve(int n, Tower src, Tower aux, Tower dest) {
if (n < 1) {
return;
}
solve(n-1, src, dest, aux);
dest.push(src.pop());
System.out.println(n);
solve(n-1, aux, src, dest);
}
public void solve() {
renderHanoi();
timer.start();
solve(n, src, aux, dest);
}
AnimationTimer timer = new AnimationTimer() {
@Override
public void handle(long now) {
renderHanoi(); // Update UI after each frame
}
};
private void renderHanoi() {
for (VBox towerBox:towerBoxes)
towerBox.getChildren().clear();
Tower[] towersCopy = new Tower[]{src.clone(), aux.clone(), dest.clone()};
for (int i = 0; i < 3; i++)
while (towersCopy[i].hasEntry())
towerBoxes[i].getChildren().add(towersCopy[i].pop());
}
}