EigeneBeispiele/HanoiVisualizer.java

161 lines
4.3 KiB
Java
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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 (02)
* @param to Index des Zielturms (02)
* @param aux Index des Hilfsturms (02)
*/
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);
}
}
}
}