161 lines
4.3 KiB
Java
161 lines
4.3 KiB
Java
import javax.swing.*;
|
||
import java.awt.*;
|
||
import java.util.Stack;
|
||
|
||
/**
|
||
* Startpunkt der Anwendung zur Visualisierung der Türme von Hanoi.
|
||
*/
|
||
public class HanoiVisualizer {
|
||
|
||
/**
|
||
* Hauptmethode – startet die grafische Anwendung.
|
||
* @param args Kommandozeilenargumente
|
||
*/
|
||
public static void main(String[] args) {
|
||
int n = Integer.parseInt(JOptionPane.showInputDialog("Anzahl der Scheiben:"));
|
||
SwingUtilities.invokeLater(() -> {
|
||
HanoiFrame frame = new HanoiFrame(n);
|
||
frame.setVisible(true);
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* JFrame-Fenster zur Darstellung der Türme von Hanoi.
|
||
*/
|
||
class HanoiFrame extends JFrame {
|
||
|
||
private final HanoiPanel panel;
|
||
|
||
/**
|
||
* Konstruktor für das Hauptfenster.
|
||
* @param numDisks Anzahl der Scheiben
|
||
*/
|
||
public HanoiFrame(int numDisks) {
|
||
setTitle("Türme von Hanoi - n Scheiben");
|
||
setSize(900, 500);
|
||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||
setLocationRelativeTo(null);
|
||
|
||
panel = new HanoiPanel(numDisks);
|
||
add(panel);
|
||
new Thread(panel::solve).start();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Panel zur grafischen Darstellung der Türme und Animation.
|
||
*/
|
||
class HanoiPanel extends JPanel {
|
||
|
||
private final Stack<Integer>[] towers;
|
||
private final int numDisks;
|
||
|
||
/**
|
||
* Konstruktor – initialisiert die Türme.
|
||
* @param numDisks Anzahl der Scheiben
|
||
*/
|
||
public HanoiPanel(int numDisks) {
|
||
this.numDisks = numDisks;
|
||
towers = new Stack[3];
|
||
for (int i = 0; i < 3; i++) {
|
||
towers[i] = new Stack<>();
|
||
}
|
||
for (int i = numDisks; i >= 1; i--) {
|
||
towers[0].push(i);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Startet die Lösung des Hanoi-Problems.
|
||
*/
|
||
public void solve() {
|
||
try {
|
||
hanoi(numDisks, 0, 2, 1);
|
||
} catch (InterruptedException e) {
|
||
e.printStackTrace();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Rekursive Methode zur Lösung des Hanoi-Problems.
|
||
*
|
||
* @param n Anzahl der zu bewegenden Scheiben
|
||
* @param from Index des Quellturms (0–2)
|
||
* @param to Index des Zielturms (0–2)
|
||
* @param aux Index des Hilfsturms (0–2)
|
||
*/
|
||
private void hanoi(int n, int from, int to, int aux) throws InterruptedException {
|
||
if (n == 1) {
|
||
moveDisk(from, to);
|
||
} else {
|
||
hanoi(n - 1, from, aux, to);
|
||
moveDisk(from, to);
|
||
hanoi(n - 1, aux, to, from);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Verschiebt eine einzelne Scheibe von einem Turm zu einem anderen.
|
||
*
|
||
* @param from Quell-Turm
|
||
* @param to Ziel-Turm
|
||
* @throws InterruptedException für Animation
|
||
*/
|
||
private void moveDisk(int from, int to) throws InterruptedException {
|
||
int disk = towers[from].pop();
|
||
towers[to].push(disk);
|
||
repaint();
|
||
Thread.sleep(500); // Wartezeit für Animation
|
||
}
|
||
|
||
@Override
|
||
protected void paintComponent(Graphics g) {
|
||
super.paintComponent(g);
|
||
drawTowers(g);
|
||
}
|
||
|
||
/**
|
||
* Zeichnet die drei Türme und ihre jeweiligen Scheiben.
|
||
*
|
||
* @param g Grafikobjekt
|
||
*/
|
||
private void drawTowers(Graphics g) {
|
||
int width = getWidth();
|
||
int height = getHeight();
|
||
|
||
int towerWidth = 20;
|
||
int towerHeight = 250;
|
||
|
||
int baseY = height - 50;
|
||
int[] xPositions = {
|
||
width / 4,
|
||
width / 2,
|
||
3 * width / 4
|
||
};
|
||
|
||
// Türme zeichnen
|
||
g.setColor(Color.DARK_GRAY);
|
||
for (int x : xPositions) {
|
||
g.fillRect(x - towerWidth / 2, baseY - towerHeight, towerWidth, towerHeight);
|
||
}
|
||
|
||
// Scheiben zeichnen
|
||
for (int i = 0; i < 3; i++) {
|
||
Stack<Integer> tower = towers[i];
|
||
for (int j = 0; j < tower.size(); j++) {
|
||
int disk = tower.get(j);
|
||
int diskWidth = 30 + disk * 20;
|
||
int diskHeight = 20;
|
||
int x = xPositions[i] - diskWidth / 2;
|
||
int y = baseY - (j + 1) * diskHeight;
|
||
|
||
g.setColor(Color.getHSBColor(disk * 0.1f, 0.6f, 0.9f));
|
||
g.fillRoundRect(x, y, diskWidth, diskHeight, 10, 10);
|
||
g.setColor(Color.BLACK);
|
||
g.drawRoundRect(x, y, diskWidth, diskHeight, 10, 10);
|
||
}
|
||
}
|
||
}
|
||
}
|