O método renderHanoi() deve mover os discos, limpando-os dos VBoxes e adicionando-os novamente na nova ordem após cada movimento ser feito, mas parece que nada é mostrado a menos que seja o último movimento, o que torna tudo bastante inútil .
Tentei diferentes métodos de criação de atrasos, como Thread.sleep, Platform.runLater, etc. Nenhum deles parece funcionar. Como faço para resolver isso?
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());
}
}