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[] 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 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); } } } }