Subtrees hinzugefügt

This commit is contained in:
Dirk Zechnall 2025-01-05 21:22:02 +01:00
parent 155d0786a6
commit 3cc08a2004
443 changed files with 131415 additions and 0 deletions

7
Quellcodes/Alg_DS_Hanoi/.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
**/*.sh
**/*.class
**/*.ctxt
repo.adoc
repo_subtree.adoc
/alt
/hide

View file

@ -0,0 +1,141 @@
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
/**
* Das Fenster, in dem das Hanoi-Spiel dargestellt wird.
* Hier sollte nichts verändert werden.
*
* @version 10.10.2020
* @author Rainer Helfrich
*/
public class HanoiFrame extends JFrame {
JPanel jPanel1;
public HanoiFrame(HanoiGame g) {
// Frame-Initialisierung
super();
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
int frameWidth = 900;
int frameHeight = 500;
setSize(frameWidth, frameHeight);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
int x = (d.width - getSize().width) / 2;
int y = (d.height - getSize().height) / 2;
setLocation(x, y);
setTitle("Türme von Hanoi");
setResizable(false);
Container cp = getContentPane();
cp.setLayout(null);
// Anfang Komponenten
jPanel1 = new HanoiPanel(g);
jPanel1.setBounds(0, 0, frameWidth, frameHeight);
jPanel1.setOpaque(true);
cp.add(jPanel1);
// Ende Komponenten
setVisible(true);
} // end of public FreecellFrame
public void neuZeichnen()
{
jPanel1.paintImmediately(0, 0, getWidth(), getHeight());
try
{
Thread.sleep(100);
}
catch(Exception x)
{
}
}
// Ende Methoden
private class HanoiPanel extends JPanel implements MouseListener{
HanoiGame dasSpiel;
Scheibe markiert;
int fromStack;
public HanoiPanel(HanoiGame g)
{
super( null, true);
dasSpiel = g;
addMouseListener(this);
markiert = null;
}
public void paint(Graphics g) {
g.setColor(new Color(180, 180, 180));
g.fillRect(0,0,getWidth(),getHeight());
g.setColor(Color.BLACK);
g.fillRect(10, getHeight()-100, 840, 20);
for (int i = 0; i < 3; i++)
{
g.setColor(Color.BLACK);
g.fillRect(145+i*280, 60, 10, getHeight()-160);
int hoehe = dasSpiel.getTurmHoehe(i);
hoehe--;
int baseY = getHeight()-120-20*hoehe;
while(hoehe >= 0)
{
Scheibe s = dasSpiel.getNteScheibe(i, hoehe);
int y = baseY + 20*hoehe;
if (markiert == s)
{
y = 30;
}
s.zeichne(g, 150+280*i, y);
hoehe--;
}
}
}
public void mouseExited(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e){
}
public void mousePressed(MouseEvent e){
}
private int getArea(Point p)
{
return (int)p.getX()/(getWidth()/3);
}
public void mouseReleased(MouseEvent e)
{
int stack = getArea(e.getPoint());
if (markiert == null)
{
if (dasSpiel.getTurmHoehe(stack) > 0)
{
markiert = dasSpiel.getNteScheibe(stack, 0);
fromStack = stack;
repaint();
}
}
else
{
if (fromStack == stack || dasSpiel.bewegeScheibe(fromStack, stack))
{
markiert = null;
}
repaint();
}
}
}
}

View file

@ -0,0 +1,93 @@
/**
* Das Spielfeld selbst
*
* @author Rainer Helfrich
* @version Oktober 2020
*/
public class HanoiGame
{
/**
* Das Array hat drei Elemente und stellt die drei Scheibenstapel dar.
*/
private Stack<Scheibe>[] stapel;
/**
* Verweis auf das Fenster-Objekt.
*/
HanoiFrame derFrame;
/**
* Erzeugt ein neues Spiel mit 7 Scheiben
*/
public HanoiGame()
{
this(7);
}
/**
* Erzeugt ein neues Spiel, die Anzahl der Scheiben kann zwischen 1 und 14 liegen.
* @param groesse Die Höhe des Stapels
*/
public HanoiGame(int groesse)
{
if (groesse > 14)
{
groesse = 14;
}
if (groesse < 1)
{
groesse = 1;
}
stapel = new Stack[3];
//# TODO: Initialisieren Sie die Stacks im Array
//# Ende TODO
while(stapel[0] != null && groesse > 0)
{
stapel[0].push(new Scheibe(groesse));
groesse--;
}
derFrame = new HanoiFrame(this);
}
/**
* Gibt die Höhe des Turms zurück
* @param t Welcher Turm wird abgefragt? 0 = links, 1 = mitte, 2 = rechts
* @return Höhe des gefragten Turmes
*/
public int getTurmHoehe(int t)
{
//# TODO: Geben Sie die Höhe des Stapels mit der Nummer t zurück
return 0;
}
/**
* Gibt die n-te Scheibe auf Turm t zurück. n wird von oben gezählt, d.h. n = 0 ist die oberste Scheibe.
* @param t Die Nummer des Turmes (0 = links, 1 = mitte, 2 = rechts)
* @param n Die Nummer der Scheibe (0 <= n < getTurmHoehe(t))
* @return Die gewünschte Scheibe
*/
public Scheibe getNteScheibe(int t, int n)
{
//# TODO: Geben Sie die n-te Scheibe vom Turm mit der Nummer t zurück
//# n und t sind immer gültige Werte.
return null;
}
/**
* Verschiebt eine Scheibe von einem Turm auf den anderen, falls der Zug erlaubt ist
* @param von Die Nummer des Turms (0 = links, 1 = mitte, 2 = rechts), von dem weggezogen wird
* @param nach Die Nummer des Turms (0 = links, 1 = mitte, 2 = rechts), auf den hingezogen wird
* @return true, wenn der Zug erlaubt war; false sonst
*/
public boolean bewegeScheibe(int von, int nach)
{
//# TODO: Verschieben Sie die oberste Scheibe vom Turm "von" auf den Turm "nach"
//# Geben Sie true zurück, wenn die Aktion erlaubt ist
//# Wenn sie nicht erlaubt ist, soll false zurückgegeben werden und nichts verändert werden.
return false;
}
}

View file

@ -0,0 +1,5 @@
PROJEKTBEZEICHNUNG: Türme von Hanoi
PROJEKTZWECK: Implementieren Sie das Spiel "Die Türme von Hanoi"
VERSION oder DATUM: Oktober 2020
WIE IST DAS PROJEKT ZU STARTEN: Erzeugen Sie ein neues Objekt vom Typ "HanoiGame"
AUTOR(EN): Rainer Helfrich, ZPG Informatik

View file

@ -0,0 +1,55 @@
import javax.swing.*;
import java.awt.*;
/**
* Repräsentiert eine Scheibe im Spiel "Die Türme von Hanoi"
*
* @author Rainer Helfrich
* @version Oktober 2020
*/
public class Scheibe
{
final private Color farbe;
final private int groesse;
/**
* Erzeugt eine neue Scheibe in der gewünschten Größe.
* Sollte nicht direkt aufgerufen werden!
* @param groesse Die Größe der Scheibe (1 bis 14)
*/
public Scheibe(int groesse)
{
Color[] farben =
{
Color.BLACK,
Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW,
Color.CYAN, Color.MAGENTA, Color.ORANGE, Color.PINK,
Color.GRAY, new Color(0x6B8E23), new Color(0x4682B4), new Color(0x9ACD32),
new Color(0xBA55D3), new Color(0x228B22)
};
this.groesse = groesse;
farbe = farben[groesse];
}
/**
* Zeichnet die Scheibe an der Position (x,y) auf das Graphics-Objekt g.
* Sollte nicht direkt aufgerufen werden.
* @param g Das Graphics-Objekt, auf das gezeichnet wird
* @param x Die x-Koordinate der oberen linken Ecke
* @param y Die y-Koordinate der oberen linken Ecke
*/
public void zeichne(Graphics g, int x, int y)
{
g.setColor(farbe);
g.fillRect(x-groesse*10, y, 20*groesse, 15);
}
/**
* Gibt die Größe der Scheibe zurück
* @return Die Größe der Scheibe (0 bis 14)
*/
public int getGroesse()
{
return groesse;
}
}

View file

@ -0,0 +1,32 @@
/**
* Abstrakte Basisklasse für Stacks
*
* @author Rainer Helfrich
* @version Oktober 2020
*/
public abstract class Stack<T>
{
/**
* Gibt zurück, ob der Stack leer ist
* @return true, wenn der Stack leer ist; false sonst
*/
public abstract boolean isEmpty();
/**
* Legt ein neues Element auf den Stack
* @param x Das neue Element
*/
public abstract void push(T x);
/**
* Entfernt das oberste Element vom Stack (falls der Stack nicht leer ist) und gibt es zurück
* @return Das bisherige oberste Element
*/
public abstract T pop();
/**
* Gibt das oberste Element des Stacks zurück (falls der Stack nicht leer ist)
* @return Das oberste Element
*/
public abstract T top();
}

View file

@ -0,0 +1,68 @@
#BlueJ package file
dependency1.from=HanoiGame
dependency1.to=HanoiFrame
dependency1.type=UsesDependency
dependency2.from=HanoiGame
dependency2.to=Stack
dependency2.type=UsesDependency
dependency3.from=HanoiGame
dependency3.to=Scheibe
dependency3.type=UsesDependency
dependency4.from=HanoiFrame
dependency4.to=HanoiGame
dependency4.type=UsesDependency
dependency5.from=HanoiFrame
dependency5.to=Scheibe
dependency5.type=UsesDependency
editor.fx.0.height=739
editor.fx.0.width=816
editor.fx.0.x=92
editor.fx.0.y=102
objectbench.height=183
objectbench.width=760
package.divider.horizontal=0.6
package.divider.vertical=0.62
package.editor.height=303
package.editor.width=649
package.editor.x=59
package.editor.y=200
package.frame.height=600
package.frame.width=800
package.numDependencies=5
package.numTargets=4
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.height=58
readme.name=@README
readme.width=47
readme.x=10
readme.y=10
target1.height=50
target1.name=HanoiGame
target1.showInterface=false
target1.type=ClassTarget
target1.width=110
target1.x=210
target1.y=190
target2.height=50
target2.name=Scheibe
target2.showInterface=false
target2.type=ClassTarget
target2.width=80
target2.x=10
target2.y=110
target3.height=50
target3.name=HanoiFrame
target3.showInterface=false
target3.type=ClassTarget
target3.width=110
target3.x=110
target3.y=20
target4.height=50
target4.name=Stack
target4.showInterface=false
target4.type=AbstractTarget
target4.width=80
target4.x=400
target4.y=20

View file

@ -0,0 +1,101 @@
/**
* Ein Stack basierend auf einem Array
*
* @author Rainer Helfrich
* @version Oktober 2020
*/
public class ArrayStack<T> extends Stack<T>
{
/**
* Enthält die Nutzdaten
*/
private Object[] daten;
/**
* Die Zahl gibt an, wie viele Elemente auf dem Stack liegen und damit auch,
* wie viele Werte im Datenarray gültig sind.
*/
private int anzahl;
/**
* Erzeugt einen neuen leeren Stack
*/
public ArrayStack()
{
daten = new Object[10];
anzahl = 0;
}
/**
* Gibt das oberste Element des Stacks zurück (falls der Stack nicht leer ist)
* @return Das oberste Element
*/
public T top()
{
if (!isEmpty())
{
return (T)daten[anzahl-1];
}
return null;
}
/**
* Entfernt das oberste Element vom Stack (falls der Stack nicht leer ist) und gibt es zurück
* @return Das bisherige oberste Element
*/
public T pop()
{
if (!isEmpty())
{
anzahl--;
return (T)daten[anzahl];
}
return null;
}
/**
* Legt ein neues Element auf den Stack
* @param x Das neue Element
*/
public void push(T wert)
{
if (anzahl == daten.length)
{
Object[] tmp = new Object[2*daten.length];
System.arraycopy(daten, 0, tmp, 0, daten.length);
daten = tmp;
}
daten[anzahl] = wert;
anzahl++;
}
/**
* Gibt zurück, ob der Stack leer ist
* @return true, wenn der Stack leer ist; false sonst
*/
public boolean isEmpty()
{
return anzahl == 0;
}
/**
* Gibt den Stack in String-Form aus.
* @return Die String-Repräsentation des Stacks
*/
@Override
public String toString()
{
StringBuilder b = new StringBuilder();
b.append("[ ");
for (int i = 0; i < anzahl; i++)
{
if (i > 0)
{
b.append(", ");
}
b.append(daten[i]);
}
b.append(" <");
return b.toString();
}
}

View file

@ -0,0 +1,141 @@
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
/**
* Das Fenster, in dem das Hanoi-Spiel dargestellt wird.
* Hier sollte nichts verändert werden.
*
* @version 10.10.2020
* @author Rainer Helfrich
*/
public class HanoiFrame extends JFrame {
JPanel jPanel1;
public HanoiFrame(HanoiGame g) {
// Frame-Initialisierung
super();
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
int frameWidth = 900;
int frameHeight = 500;
setSize(frameWidth, frameHeight);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
int x = (d.width - getSize().width) / 2;
int y = (d.height - getSize().height) / 2;
setLocation(x, y);
setTitle("Türme von Hanoi");
setResizable(false);
Container cp = getContentPane();
cp.setLayout(null);
// Anfang Komponenten
jPanel1 = new HanoiPanel(g);
jPanel1.setBounds(0, 0, frameWidth, frameHeight);
jPanel1.setOpaque(true);
cp.add(jPanel1);
// Ende Komponenten
setVisible(true);
} // end of public FreecellFrame
public void neuZeichnen()
{
jPanel1.paintImmediately(0, 0, getWidth(), getHeight());
try
{
Thread.sleep(100);
}
catch(Exception x)
{
}
}
// Ende Methoden
private class HanoiPanel extends JPanel implements MouseListener{
HanoiGame dasSpiel;
Scheibe markiert;
int fromStack;
public HanoiPanel(HanoiGame g)
{
super( null, true);
dasSpiel = g;
addMouseListener(this);
markiert = null;
}
public void paint(Graphics g) {
g.setColor(new Color(180, 180, 180));
g.fillRect(0,0,getWidth(),getHeight());
g.setColor(Color.BLACK);
g.fillRect(10, getHeight()-100, 840, 20);
for (int i = 0; i < 3; i++)
{
g.setColor(Color.BLACK);
g.fillRect(145+i*280, 60, 10, getHeight()-160);
int hoehe = dasSpiel.getTurmHoehe(i);
hoehe--;
int baseY = getHeight()-120-20*hoehe;
while(hoehe >= 0)
{
Scheibe s = dasSpiel.getNteScheibe(i, hoehe);
int y = baseY + 20*hoehe;
if (markiert == s)
{
y = 30;
}
s.zeichne(g, 150+280*i, y);
hoehe--;
}
}
}
public void mouseExited(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e){
}
public void mousePressed(MouseEvent e){
}
private int getArea(Point p)
{
return (int)p.getX()/(getWidth()/3);
}
public void mouseReleased(MouseEvent e)
{
int stack = getArea(e.getPoint());
if (markiert == null)
{
if (dasSpiel.getTurmHoehe(stack) > 0)
{
markiert = dasSpiel.getNteScheibe(stack, 0);
fromStack = stack;
repaint();
}
}
else
{
if (fromStack == stack || dasSpiel.bewegeScheibe(fromStack, stack))
{
markiert = null;
}
repaint();
}
}
}
}

View file

@ -0,0 +1,116 @@
/**
* Das Spielfeld selbst
*
* @author Rainer Helfrich
* @version Oktober 2020
*/
public class HanoiGame
{
/**
* Das Array hat drei Elemente und stellt die drei Scheibenstapel dar.
*/
private Stack<Scheibe>[] stapel;
/**
* Verweis auf das Fenster-Objekt.
*/
HanoiFrame derFrame;
/**
* Erzeugt ein neues Spiel mit 7 Scheiben
*/
public HanoiGame()
{
this(7);
}
/**
* Erzeugt ein neues Spiel, die Anzahl der Scheiben kann zwischen 1 und 14 liegen.
* @param groesse Die Höhe des Stapels
*/
public HanoiGame(int groesse)
{
if (groesse > 14)
{
groesse = 14;
}
if (groesse < 1)
{
groesse = 1;
}
stapel = new Stack[3];
for (int i = 0; i < 3; i++)
{
stapel[i] = new ArrayStack<Scheibe>();
}
while(groesse > 0)
{
stapel[0].push(new Scheibe(groesse));
groesse--;
}
derFrame = new HanoiFrame(this);
}
/**
* Gibt die Höhe des Turms zurück
* @param t Welcher Turm wird abgefragt? 0 = links, 1 = mitte, 2 = rechts
* @return Höhe des gefragten Turmes
*/
public int getTurmHoehe(int index)
{
Stack<Scheibe> tmp = new ArrayStack<Scheibe>();
int size = 0;
while(!stapel[index].isEmpty())
{
tmp.push(stapel[index].pop());
size++;
}
while(!tmp.isEmpty())
{
stapel[index].push(tmp.pop());
}
return size;
}
/**
* Gibt die n-te Scheibe auf Turm t zurück. n wird von oben gezählt, d.h. n = 0 ist die oberste Scheibe.
* @param t Die Nummer des Turmes (0 = links, 1 = mitte, 2 = rechts)
* @param n Die Nummer der Scheibe (0 <= n < getTurmHoehe(t))
* @return Die gewünschte Scheibe
*/
public Scheibe getNteScheibe(int turm, int index)
{
Stack<Scheibe> tmp = new ArrayStack<Scheibe>();
for (int i = 0; i < index; i++)
{
tmp.push(stapel[turm].pop());
}
Scheibe s = stapel[turm].top();
while(!tmp.isEmpty())
{
stapel[turm].push(tmp.pop());
}
return s;
}
/**
* Verschiebt eine Scheibe von einem Turm auf den anderen, falls der Zug erlaubt ist
* @param von Die Nummer des Turms (0 = links, 1 = mitte, 2 = rechts), von dem weggezogen wird
* @param nach Die Nummer des Turms (0 = links, 1 = mitte, 2 = rechts), auf den hingezogen wird
* @return true, wenn der Zug erlaubt war; false sonst
*/
public boolean bewegeScheibe(int von, int nach)
{
if (stapel[von].isEmpty())
{
return false;
}
Scheibe s = stapel[von].top();
if (stapel[nach].isEmpty() || stapel[nach].top().getGroesse() > s.getGroesse())
{
stapel[nach].push(stapel[von].pop());
return true;
}
return false;
}
}

View file

@ -0,0 +1,5 @@
PROJEKTBEZEICHNUNG: Türme von Hanoi
PROJEKTZWECK: Implementieren Sie das Spiel "Die Türme von Hanoi"
VERSION oder DATUM: Oktober 2020
WIE IST DAS PROJEKT ZU STARTEN: Erzeugen Sie ein neues Objekt vom Typ "HanoiGame"
AUTOR(EN): Rainer Helfrich, ZPG Informatik

View file

@ -0,0 +1,55 @@
import javax.swing.*;
import java.awt.*;
/**
* Repräsentiert eine Scheibe im Spiel "Die Türme von Hanoi"
*
* @author Rainer Helfrich
* @version Oktober 2020
*/
public class Scheibe
{
final private Color farbe;
final private int groesse;
/**
* Erzeugt eine neue Scheibe in der gewünschten Größe.
* Sollte nicht direkt aufgerufen werden!
* @param groesse Die Größe der Scheibe (1 bis 14)
*/
public Scheibe(int groesse)
{
Color[] farben =
{
Color.BLACK,
Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW,
Color.CYAN, Color.MAGENTA, Color.ORANGE, Color.PINK,
Color.GRAY, new Color(0x6B8E23), new Color(0x4682B4), new Color(0x9ACD32),
new Color(0xBA55D3), new Color(0x228B22)
};
this.groesse = groesse;
farbe = farben[groesse];
}
/**
* Zeichnet die Scheibe an der Position (x,y) auf das Graphics-Objekt g.
* Sollte nicht direkt aufgerufen werden.
* @param g Das Graphics-Objekt, auf das gezeichnet wird
* @param x Die x-Koordinate der oberen linken Ecke
* @param y Die y-Koordinate der oberen linken Ecke
*/
public void zeichne(Graphics g, int x, int y)
{
g.setColor(farbe);
g.fillRect(x-groesse*10, y, 20*groesse, 15);
}
/**
* Gibt die Größe der Scheibe zurück
* @return Die Größe der Scheibe (0 bis 14)
*/
public int getGroesse()
{
return groesse;
}
}

View file

@ -0,0 +1,32 @@
/**
* Abstrakte Basisklasse für Stacks
*
* @author Rainer Helfrich
* @version Oktober 2020
*/
public abstract class Stack<T>
{
/**
* Gibt zurück, ob der Stack leer ist
* @return true, wenn der Stack leer ist; false sonst
*/
public abstract boolean isEmpty();
/**
* Legt ein neues Element auf den Stack
* @param x Das neue Element
*/
public abstract void push(T x);
/**
* Entfernt das oberste Element vom Stack (falls der Stack nicht leer ist) und gibt es zurück
* @return Das bisherige oberste Element
*/
public abstract T pop();
/**
* Gibt das oberste Element des Stacks zurück (falls der Stack nicht leer ist)
* @return Das oberste Element
*/
public abstract T top();
}

View file

@ -0,0 +1,78 @@
#BlueJ package file
dependency1.from=HanoiFrame
dependency1.to=HanoiGame
dependency1.type=UsesDependency
dependency2.from=HanoiFrame
dependency2.to=Scheibe
dependency2.type=UsesDependency
dependency3.from=HanoiGame
dependency3.to=HanoiFrame
dependency3.type=UsesDependency
dependency4.from=HanoiGame
dependency4.to=Stack
dependency4.type=UsesDependency
dependency5.from=HanoiGame
dependency5.to=ArrayStack
dependency5.type=UsesDependency
dependency6.from=HanoiGame
dependency6.to=Scheibe
dependency6.type=UsesDependency
editor.fx.0.height=763
editor.fx.0.width=816
editor.fx.0.x=974
editor.fx.0.y=70
objectbench.height=183
objectbench.width=760
package.divider.horizontal=0.6
package.divider.vertical=0.62
package.editor.height=303
package.editor.width=649
package.editor.x=940
package.editor.y=268
package.frame.height=600
package.frame.width=800
package.numDependencies=6
package.numTargets=5
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.height=58
readme.name=@README
readme.width=47
readme.x=10
readme.y=10
target1.height=50
target1.name=HanoiGame
target1.showInterface=false
target1.type=ClassTarget
target1.width=110
target1.x=210
target1.y=190
target2.height=50
target2.name=Scheibe
target2.showInterface=false
target2.type=ClassTarget
target2.width=80
target2.x=10
target2.y=110
target3.height=50
target3.name=HanoiFrame
target3.showInterface=false
target3.type=ClassTarget
target3.width=110
target3.x=110
target3.y=20
target4.height=50
target4.name=ArrayStack
target4.showInterface=false
target4.type=ClassTarget
target4.width=120
target4.x=380
target4.y=140
target5.height=50
target5.name=Stack
target5.showInterface=false
target5.type=AbstractTarget
target5.width=80
target5.x=400
target5.y=20

View file

@ -0,0 +1,101 @@
/**
* Ein Stack basierend auf einem Array
*
* @author Rainer Helfrich
* @version Oktober 2020
*/
public class ArrayStack<T> extends Stack<T>
{
/**
* Enthält die Nutzdaten
*/
private Object[] daten;
/**
* Die Zahl gibt an, wie viele Elemente auf dem Stack liegen und damit auch,
* wie viele Werte im Datenarray gültig sind.
*/
private int anzahl;
/**
* Erzeugt einen neuen leeren Stack
*/
public ArrayStack()
{
daten = new Object[10];
anzahl = 0;
}
/**
* Gibt das oberste Element des Stacks zurück (falls der Stack nicht leer ist)
* @return Das oberste Element
*/
public T top()
{
if (!isEmpty())
{
return (T)daten[anzahl-1];
}
return null;
}
/**
* Entfernt das oberste Element vom Stack (falls der Stack nicht leer ist) und gibt es zurück
* @return Das bisherige oberste Element
*/
public T pop()
{
if (!isEmpty())
{
anzahl--;
return (T)daten[anzahl];
}
return null;
}
/**
* Legt ein neues Element auf den Stack
* @param x Das neue Element
*/
public void push(T wert)
{
if (anzahl == daten.length)
{
Object[] tmp = new Object[2*daten.length];
System.arraycopy(daten, 0, tmp, 0, daten.length);
daten = tmp;
}
daten[anzahl] = wert;
anzahl++;
}
/**
* Gibt zurück, ob der Stack leer ist
* @return true, wenn der Stack leer ist; false sonst
*/
public boolean isEmpty()
{
return anzahl == 0;
}
/**
* Gibt den Stack in String-Form aus.
* @return Die String-Repräsentation des Stacks
*/
@Override
public String toString()
{
StringBuilder b = new StringBuilder();
b.append("[ ");
for (int i = 0; i < anzahl; i++)
{
if (i > 0)
{
b.append(", ");
}
b.append(daten[i]);
}
b.append(" <");
return b.toString();
}
}

View file

@ -0,0 +1,141 @@
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
/**
* Das Fenster, in dem das Hanoi-Spiel dargestellt wird.
* Hier sollte nichts verändert werden.
*
* @version 10.10.2020
* @author Rainer Helfrich
*/
public class HanoiFrame extends JFrame {
JPanel jPanel1;
public HanoiFrame(HanoiGame g) {
// Frame-Initialisierung
super();
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
int frameWidth = 900;
int frameHeight = 500;
setSize(frameWidth, frameHeight);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
int x = (d.width - getSize().width) / 2;
int y = (d.height - getSize().height) / 2;
setLocation(x, y);
setTitle("Türme von Hanoi");
setResizable(false);
Container cp = getContentPane();
cp.setLayout(null);
// Anfang Komponenten
jPanel1 = new HanoiPanel(g);
jPanel1.setBounds(0, 0, frameWidth, frameHeight);
jPanel1.setOpaque(true);
cp.add(jPanel1);
// Ende Komponenten
setVisible(true);
} // end of public FreecellFrame
public void neuZeichnen()
{
jPanel1.paintImmediately(0, 0, getWidth(), getHeight());
try
{
Thread.sleep(100);
}
catch(Exception x)
{
}
}
// Ende Methoden
private class HanoiPanel extends JPanel implements MouseListener{
HanoiGame dasSpiel;
Scheibe markiert;
int fromStack;
public HanoiPanel(HanoiGame g)
{
super( null, true);
dasSpiel = g;
addMouseListener(this);
markiert = null;
}
public void paint(Graphics g) {
g.setColor(new Color(180, 180, 180));
g.fillRect(0,0,getWidth(),getHeight());
g.setColor(Color.BLACK);
g.fillRect(10, getHeight()-100, 840, 20);
for (int i = 0; i < 3; i++)
{
g.setColor(Color.BLACK);
g.fillRect(145+i*280, 60, 10, getHeight()-160);
int hoehe = dasSpiel.getTurmHoehe(i);
hoehe--;
int baseY = getHeight()-120-20*hoehe;
while(hoehe >= 0)
{
Scheibe s = dasSpiel.getNteScheibe(i, hoehe);
int y = baseY + 20*hoehe;
if (markiert == s)
{
y = 30;
}
s.zeichne(g, 150+280*i, y);
hoehe--;
}
}
}
public void mouseExited(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e){
}
public void mousePressed(MouseEvent e){
}
private int getArea(Point p)
{
return (int)p.getX()/(getWidth()/3);
}
public void mouseReleased(MouseEvent e)
{
int stack = getArea(e.getPoint());
if (markiert == null)
{
if (dasSpiel.getTurmHoehe(stack) > 0)
{
markiert = dasSpiel.getNteScheibe(stack, 0);
fromStack = stack;
repaint();
}
}
else
{
if (fromStack == stack || dasSpiel.bewegeScheibe(fromStack, stack))
{
markiert = null;
}
repaint();
}
}
}
}

View file

@ -0,0 +1,154 @@
/**
* Das Spielfeld selbst
*
* @author Rainer Helfrich
* @version Oktober 2020
*/
public class HanoiGame
{
/**
* Das Array hat drei Elemente und stellt die drei Scheibenstapel dar.
*/
private Stack<Scheibe>[] stapel;
/**
* Verweis auf das Fenster-Objekt.
*/
HanoiFrame derFrame;
/**
* Erzeugt ein neues Spiel mit 7 Scheiben
*/
public HanoiGame()
{
this(7);
}
/**
* Erzeugt ein neues Spiel, die Anzahl der Scheiben kann zwischen 1 und 14 liegen.
* @param groesse Die Höhe des Stapels
*/
public HanoiGame(int groesse)
{
if (groesse > 14)
{
groesse = 14;
}
if (groesse < 1)
{
groesse = 1;
}
stapel = new Stack[3];
for (int i = 0; i < 3; i++)
{
stapel[i] = new ArrayStack<Scheibe>();
}
while(groesse > 0)
{
stapel[0].push(new Scheibe(groesse));
groesse--;
}
derFrame = new HanoiFrame(this);
}
/**
* Gibt die Höhe des Turms zurück
* @param t Welcher Turm wird abgefragt? 0 = links, 1 = mitte, 2 = rechts
* @return Höhe des gefragten Turmes
*/
public int getTurmHoehe(int index)
{
Stack<Scheibe> tmp = new ArrayStack<Scheibe>();
int size = 0;
while(!stapel[index].isEmpty())
{
tmp.push(stapel[index].pop());
size++;
}
while(!tmp.isEmpty())
{
stapel[index].push(tmp.pop());
}
return size;
}
/**
* Gibt die n-te Scheibe auf Turm t zurück. n wird von oben gezählt, d.h. n = 0 ist die oberste Scheibe.
* @param t Die Nummer des Turmes (0 = links, 1 = mitte, 2 = rechts)
* @param n Die Nummer der Scheibe (0 <= n < getTurmHoehe(t))
* @return Die gewünschte Scheibe
*/
public Scheibe getNteScheibe(int turm, int index)
{
Stack<Scheibe> tmp = new ArrayStack<Scheibe>();
for (int i = 0; i < index; i++)
{
tmp.push(stapel[turm].pop());
}
Scheibe s = stapel[turm].top();
while(!tmp.isEmpty())
{
stapel[turm].push(tmp.pop());
}
return s;
}
/**
* Verschiebt eine Scheibe von einem Turm auf den anderen, falls der Zug erlaubt ist
* @param von Die Nummer des Turms (0 = links, 1 = mitte, 2 = rechts), von dem weggezogen wird
* @param nach Die Nummer des Turms (0 = links, 1 = mitte, 2 = rechts), auf den hingezogen wird
* @return true, wenn der Zug erlaubt war; false sonst
*/
public boolean bewegeScheibe(int von, int nach)
{
if (stapel[von].isEmpty())
{
return false;
}
Scheibe s = stapel[von].top();
if (stapel[nach].isEmpty() || stapel[nach].top().getGroesse() > s.getGroesse())
{
stapel[nach].push(stapel[von].pop());
return true;
}
return false;
}
/**
* Löst das Hanoi-Problem
*/
public void loese()
{
int n = getTurmHoehe(0);
if (getTurmHoehe(1) != 0 || getTurmHoehe(2) != 0)
{
System.out.println("Fehler: Nicht im Ausgangszustand");
}
else
{
loese(n, 0, 2, 1);
}
}
/**
* Löst das Hanoi-Problem rekursiv
* @param anzahl Die Anzahl der zu verschiebenden Scheiben
* @param von Die Nummer des Ausgangsstapels
* @param nach Die Nummer des Zielstapels
* @param ueber Die Nummer des Hilfsstapels
*/
private void loese(int anzahl, int von, int nach, int ueber)
{
if (anzahl > 1)
{
loese(anzahl-1, von, ueber, nach);
}
bewegeScheibe(von, nach);
derFrame.neuZeichnen();
if (anzahl > 1)
{
loese(anzahl-1, ueber, nach, von);
}
}
}

View file

@ -0,0 +1,5 @@
PROJEKTBEZEICHNUNG: Türme von Hanoi automatisch
PROJEKTZWECK: Implementieren Sie eine automatische Lösung für das Spiel "Die Türme von Hanoi"
VERSION oder DATUM: Oktober 2020
WIE IST DAS PROJEKT ZU STARTEN: Erzeugen Sie ein neues Objekt vom Typ "HanoiGame"
AUTOR(EN): Rainer Helfrich, ZPG Informatik

View file

@ -0,0 +1,55 @@
import javax.swing.*;
import java.awt.*;
/**
* Repräsentiert eine Scheibe im Spiel "Die Türme von Hanoi"
*
* @author Rainer Helfrich
* @version Oktober 2020
*/
public class Scheibe
{
final private Color farbe;
final private int groesse;
/**
* Erzeugt eine neue Scheibe in der gewünschten Größe.
* Sollte nicht direkt aufgerufen werden!
* @param groesse Die Größe der Scheibe (1 bis 14)
*/
public Scheibe(int groesse)
{
Color[] farben =
{
Color.BLACK,
Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW,
Color.CYAN, Color.MAGENTA, Color.ORANGE, Color.PINK,
Color.GRAY, new Color(0x6B8E23), new Color(0x4682B4), new Color(0x9ACD32),
new Color(0xBA55D3), new Color(0x228B22)
};
this.groesse = groesse;
farbe = farben[groesse];
}
/**
* Zeichnet die Scheibe an der Position (x,y) auf das Graphics-Objekt g.
* Sollte nicht direkt aufgerufen werden.
* @param g Das Graphics-Objekt, auf das gezeichnet wird
* @param x Die x-Koordinate der oberen linken Ecke
* @param y Die y-Koordinate der oberen linken Ecke
*/
public void zeichne(Graphics g, int x, int y)
{
g.setColor(farbe);
g.fillRect(x-groesse*10, y, 20*groesse, 15);
}
/**
* Gibt die Größe der Scheibe zurück
* @return Die Größe der Scheibe (0 bis 14)
*/
public int getGroesse()
{
return groesse;
}
}

View file

@ -0,0 +1,32 @@
/**
* Abstrakte Basisklasse für Stacks
*
* @author Rainer Helfrich
* @version Oktober 2020
*/
public abstract class Stack<T>
{
/**
* Gibt zurück, ob der Stack leer ist
* @return true, wenn der Stack leer ist; false sonst
*/
public abstract boolean isEmpty();
/**
* Legt ein neues Element auf den Stack
* @param x Das neue Element
*/
public abstract void push(T x);
/**
* Entfernt das oberste Element vom Stack (falls der Stack nicht leer ist) und gibt es zurück
* @return Das bisherige oberste Element
*/
public abstract T pop();
/**
* Gibt das oberste Element des Stacks zurück (falls der Stack nicht leer ist)
* @return Das oberste Element
*/
public abstract T top();
}

View file

@ -0,0 +1,78 @@
#BlueJ package file
dependency1.from=HanoiFrame
dependency1.to=HanoiGame
dependency1.type=UsesDependency
dependency2.from=HanoiFrame
dependency2.to=Scheibe
dependency2.type=UsesDependency
dependency3.from=HanoiGame
dependency3.to=HanoiFrame
dependency3.type=UsesDependency
dependency4.from=HanoiGame
dependency4.to=Stack
dependency4.type=UsesDependency
dependency5.from=HanoiGame
dependency5.to=ArrayStack
dependency5.type=UsesDependency
dependency6.from=HanoiGame
dependency6.to=Scheibe
dependency6.type=UsesDependency
editor.fx.0.height=739
editor.fx.0.width=1124
editor.fx.0.x=552
editor.fx.0.y=100
objectbench.height=183
objectbench.width=760
package.divider.horizontal=0.6
package.divider.vertical=0.62
package.editor.height=303
package.editor.width=649
package.editor.x=848
package.editor.y=277
package.frame.height=600
package.frame.width=800
package.numDependencies=6
package.numTargets=5
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.height=58
readme.name=@README
readme.width=47
readme.x=10
readme.y=10
target1.height=50
target1.name=HanoiGame
target1.showInterface=false
target1.type=ClassTarget
target1.width=110
target1.x=210
target1.y=190
target2.height=50
target2.name=Scheibe
target2.showInterface=false
target2.type=ClassTarget
target2.width=80
target2.x=10
target2.y=110
target3.height=50
target3.name=HanoiFrame
target3.showInterface=false
target3.type=ClassTarget
target3.width=110
target3.x=110
target3.y=20
target4.height=50
target4.name=ArrayStack
target4.showInterface=false
target4.type=ClassTarget
target4.width=120
target4.x=380
target4.y=140
target5.height=50
target5.name=Stack
target5.showInterface=false
target5.type=AbstractTarget
target5.width=80
target5.x=400
target5.y=20

View file

@ -0,0 +1,11 @@
= Material :
|===
|Zuordnung|
|Klassenstufe|
|Bildungsplanbezug |
|Werkzeug|
|Autoren|
|===
== Inhalt