Subtrees hinzugefügt
7
Quellcodes/Alg_DS_Freecell/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
**/*.sh
|
||||
**/*.class
|
||||
**/*.ctxt
|
||||
repo.adoc
|
||||
repo_subtree.adoc
|
||||
/alt
|
||||
/hide
|
||||
257
Quellcodes/Alg_DS_Freecell/01_freecell_roh/FreecellFrame.java
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Das Fenster, in dem das Freecell-Spiel dargestellt wird.
|
||||
* Hier sollte nichts verändert werden.
|
||||
*
|
||||
* @version 10.10.2020
|
||||
* @author Rainer Helfrich
|
||||
*/
|
||||
public class FreecellFrame extends JFrame {
|
||||
|
||||
public FreecellFrame(FreecellGame g) {
|
||||
// Frame-Initialisierung
|
||||
super();
|
||||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
int frameWidth = 8*Karte.CARD_WIDTH+150;
|
||||
int frameHeight = 640+2*Karte.CARD_HEIGHT;
|
||||
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("Freecell");
|
||||
setResizable(false);
|
||||
Container cp = getContentPane();
|
||||
cp.setLayout(null);
|
||||
// Anfang Komponenten
|
||||
|
||||
JPanel jPanel1 = new FreecellPanel(g);
|
||||
jPanel1.setBounds(0, 0, frameWidth, frameHeight);
|
||||
jPanel1.setOpaque(true);
|
||||
cp.add(jPanel1);
|
||||
// Ende Komponenten
|
||||
|
||||
setVisible(true);
|
||||
} // end of public FreecellFrame
|
||||
|
||||
|
||||
|
||||
// Ende Methoden
|
||||
private class FreecellPanel extends JPanel implements MouseListener{
|
||||
|
||||
FreecellGame dasSpiel;
|
||||
|
||||
public FreecellPanel(FreecellGame g)
|
||||
{
|
||||
super( null, true);
|
||||
dasSpiel = g;
|
||||
this.addMouseListener(this);
|
||||
markiert = null;
|
||||
sourceArea = -1;
|
||||
sourceIndex = -1;
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
g.setColor(new Color(0, 100, 0));
|
||||
g.fillRect(0,0,getWidth(),getHeight());
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Karte k = dasSpiel.getKarte(FreecellGame.ZELLEN, i);
|
||||
if (k == null)
|
||||
{
|
||||
g.setColor(new Color(0, 80, 0));
|
||||
g.fillRoundRect(10+(Karte.CARD_WIDTH+10)*i, 20, Karte.CARD_WIDTH, Karte.CARD_HEIGHT, 8, 8);
|
||||
g.setColor(Color.BLACK);
|
||||
g.drawRoundRect(10+(Karte.CARD_WIDTH+10)*i, 20, Karte.CARD_WIDTH, Karte.CARD_HEIGHT, 8, 8);
|
||||
} // end of if
|
||||
else
|
||||
{
|
||||
k.zeichne(g, 10+(Karte.CARD_WIDTH+10)*i, 20);
|
||||
}
|
||||
} // end of for
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Karte k = dasSpiel.getKarte(FreecellGame.ABLAGESTAPEL, i);
|
||||
if (k == null)
|
||||
{
|
||||
g.setColor(new Color(0, 80, 0));
|
||||
g.fillRoundRect(4*Karte.CARD_WIDTH+90+(Karte.CARD_WIDTH+10)*i, 20, Karte.CARD_WIDTH, Karte.CARD_HEIGHT, 8, 8);
|
||||
g.setColor(Color.BLACK);
|
||||
g.drawRoundRect(4*Karte.CARD_WIDTH+90+(Karte.CARD_WIDTH+10)*i, 20, Karte.CARD_WIDTH, Karte.CARD_HEIGHT, 8, 8);
|
||||
} // end of if
|
||||
else
|
||||
{
|
||||
k.zeichne(g, 4*Karte.CARD_WIDTH+90+(Karte.CARD_WIDTH+10)*i, 20);
|
||||
}
|
||||
} // end of for
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int hoehe = dasSpiel.getStapelHoehe(i);
|
||||
for (int j = 0; j < hoehe; j++)
|
||||
{
|
||||
Karte k = dasSpiel.getKarteInStapel(i, hoehe-1-j);
|
||||
k.zeichne(g, 35+(Karte.CARD_WIDTH+10)*i, Karte.CARD_HEIGHT+55+j*30);
|
||||
}
|
||||
} // end of for
|
||||
}
|
||||
|
||||
Karte markiert;
|
||||
int sourceArea;
|
||||
int sourceIndex;
|
||||
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1)
|
||||
{
|
||||
int area = getArea(e.getPoint());
|
||||
if (area == FreecellGame.ABLAGESTAPEL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int index = getIndex(e.getPoint(), area);
|
||||
if (index == FreecellGame.KEINER)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (dasSpiel.schnellerZug(area, index))
|
||||
{
|
||||
if (markiert != null)
|
||||
{
|
||||
markiert.setMarkiert(false);
|
||||
markiert = null;
|
||||
}
|
||||
finishMove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void mouseEntered(MouseEvent e){
|
||||
}
|
||||
|
||||
public void mousePressed(MouseEvent e){
|
||||
}
|
||||
|
||||
|
||||
private int getArea(Point p)
|
||||
{
|
||||
if (p.getY() >= 20 && p.getY() <= Karte.CARD_HEIGHT+20)
|
||||
{
|
||||
if (p.getX() >= 10 && p.getX() <= Karte.CARD_WIDTH*4+40)
|
||||
{
|
||||
return FreecellGame.ZELLEN;
|
||||
} // end of if
|
||||
if (p.getX() >= Karte.CARD_WIDTH*4+90 && p.getY() <= Karte.CARD_WIDTH*8+120)
|
||||
{
|
||||
return FreecellGame.ABLAGESTAPEL;
|
||||
} // end of if
|
||||
} // end of if
|
||||
if (p.getY() >= Karte.CARD_HEIGHT+55 && p.getX() >= 35 && p.getX() <= Karte.CARD_WIDTH*8+105)
|
||||
{
|
||||
return FreecellGame.KASKADEN;
|
||||
}
|
||||
return FreecellGame.KEINER;
|
||||
}
|
||||
|
||||
private int getIndex(Point p, int area)
|
||||
{
|
||||
if (area < 0)
|
||||
{
|
||||
return FreecellGame.KEINER;
|
||||
}
|
||||
int x = (int)p.getX();
|
||||
if (area == FreecellGame.ZELLEN)
|
||||
{
|
||||
x -= 10;
|
||||
} // end of if
|
||||
if (area == FreecellGame.ABLAGESTAPEL)
|
||||
{
|
||||
x -= 4*Karte.CARD_WIDTH+90;
|
||||
} // end of if
|
||||
if (area == FreecellGame.KASKADEN)
|
||||
{
|
||||
x -= 35;
|
||||
} // end of if
|
||||
if (x % (Karte.CARD_WIDTH+10) < Karte.CARD_WIDTH)
|
||||
{
|
||||
return x / (Karte.CARD_WIDTH+10);
|
||||
} // end of if
|
||||
return FreecellGame.KEINER;
|
||||
}
|
||||
|
||||
public void mouseReleased(MouseEvent e)
|
||||
{
|
||||
int area = getArea(e.getPoint());
|
||||
int index = getIndex(e.getPoint(), area);
|
||||
if (area == FreecellGame.KEINER || index == FreecellGame.KEINER) {
|
||||
if (markiert != null)
|
||||
markiert.setMarkiert(false);
|
||||
markiert = null;
|
||||
} // end of if
|
||||
else if (markiert == null)
|
||||
{
|
||||
if (area == FreecellGame.ZELLEN || area == FreecellGame.KASKADEN)
|
||||
{
|
||||
markiert = dasSpiel.getKarte(area, index);
|
||||
}
|
||||
if (markiert != null)
|
||||
{
|
||||
markiert.setMarkiert(true);
|
||||
sourceArea = area;
|
||||
sourceIndex = index;
|
||||
} // end of if
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sourceArea == area && sourceIndex == index ||
|
||||
dasSpiel.verschiebe(sourceArea, sourceIndex, area, index))
|
||||
{
|
||||
markiert.setMarkiert(false);
|
||||
markiert = null;
|
||||
}
|
||||
}
|
||||
finishMove();
|
||||
}
|
||||
|
||||
private void finishMove()
|
||||
{
|
||||
if (markiert != null)
|
||||
{
|
||||
repaint();
|
||||
return;
|
||||
}
|
||||
while(true)
|
||||
{
|
||||
paintImmediately(0, 0, getWidth(), getHeight());
|
||||
if (dasSpiel.automatischerZug())
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(300);
|
||||
}
|
||||
catch(Exception x)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dasSpiel.istGewonnen())
|
||||
{
|
||||
JOptionPane.showMessageDialog(null,"Gewonnen!","Spiel beendet", JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // end of class FreecellFrame
|
||||
191
Quellcodes/Alg_DS_Freecell/01_freecell_roh/FreecellGame.java
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Das Spielfeld selbst
|
||||
*
|
||||
* @author Rainer Helfrich
|
||||
* @version Oktober 2020
|
||||
*/
|
||||
public class FreecellGame
|
||||
{
|
||||
/**
|
||||
* Die vier Zellen oben links
|
||||
*/
|
||||
private Karte[] zellen;
|
||||
|
||||
/**
|
||||
* Die vier Stapel oben rechts
|
||||
*/
|
||||
private Stack<Karte>[] ablagestapel;
|
||||
|
||||
/**
|
||||
* Die acht Stapel unten, auf denen die Karten zu Beginn liegen
|
||||
*/
|
||||
private Stack<Karte>[] kaskaden;
|
||||
|
||||
/**
|
||||
* Konstanten, die für die verschiedenen Ablegebereiche stehen.
|
||||
*/
|
||||
public static final int ZELLEN = 0;
|
||||
public static final int ABLAGESTAPEL = 1;
|
||||
public static final int KASKADEN = 2;
|
||||
public static final int KEINER = -1;
|
||||
|
||||
/**
|
||||
* Erzeugt ein neues Spiel mit einer zufälligen Ausgangssituation.
|
||||
*/
|
||||
public FreecellGame()
|
||||
{
|
||||
this(new Random());
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein neues Spiel mit einer vorgegebenen Nummer.
|
||||
* Ein Spiel mit einer bestimmten Nummer beginnt immer in der gleichen Ausgangssituation.
|
||||
* @param nummer Legt fest, welche Ausgangssituation verwendet wird.
|
||||
*/
|
||||
public FreecellGame(int nummer)
|
||||
{
|
||||
this(new Random(nummer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein neues Spiel
|
||||
* @param r Der Zufallsgenerator, der zum zufälligen Füllen der Kaskaden verwendet wird.
|
||||
*/
|
||||
private FreecellGame(Random r)
|
||||
{
|
||||
zellen = new Karte[4];
|
||||
ablagestapel = new Stack[4];
|
||||
kaskaden = new Stack[8];
|
||||
ArrayList<Integer> zahlen = new ArrayList<Integer>(52);
|
||||
for (int i = 0; i < 52; i++) {
|
||||
zahlen.add(i);
|
||||
}
|
||||
//# TODO: Erzeugen Sie die Stacks für den Ablagestapel und die Kaskaden
|
||||
|
||||
//# Ende TODO
|
||||
for (int i = 0; i < kaskaden.length; i++)
|
||||
{
|
||||
for (int j = 0; j < ((i < 4) ? 7 : 6); j++) {
|
||||
int rnd = r.nextInt(zahlen.size());
|
||||
Karte k = new Karte(zahlen.get(rnd));
|
||||
zahlen.remove(rnd);
|
||||
if (kaskaden[i] != null)
|
||||
{
|
||||
kaskaden[i].push(k);
|
||||
}
|
||||
}
|
||||
}
|
||||
new FreecellFrame(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt die oberste Karte aus dem angegebenen Bereich zurück
|
||||
* @param bereich Kann ZELLEN, ABLAGESTAPEL oder KASKADEN sein.
|
||||
* @param index Kann 0 bis 7 (für Kaskaden) bzw. 0 bis 3 (andere Bereiche) sein. Gibt an, welches Feld des Bereichs gewünscht wird.
|
||||
* @return Die oberste Karte, sofern eine dort liegt. null sonst.
|
||||
*/
|
||||
public Karte getKarte(int bereich, int index)
|
||||
{
|
||||
//# TODO: Sorgen Sie dafür, dass die (oberste) Karte aus dem gewünschten Bereich zurückgegeben wird.
|
||||
//# Wenn ein Stapel leer ist, soll null zurückgegeben werden.
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt die Höhe der Kaskade mit der gegebenen Nummer zurück
|
||||
* @param index Kann 0 bis 7 sein. Gibt an, welche Kaskade gewünscht wird.
|
||||
* @return Die Höhe der Kaskade.
|
||||
*/
|
||||
public int getStapelHoehe(int index)
|
||||
{
|
||||
//# TODO: Lassen Sie zurückgeben, wie hoch der Stapel der Kaskade mit der Nummer index ist.
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt die n-te Karte von oben in der Kaskade mit der Nummer index zurück.
|
||||
* Die Parameter sind immer in gültigen Bereichen, wenn die Methode von FreecellFrame aufgerufen wird.
|
||||
* @param index Kann 0 bis 7 sein. Gibt an, welche Kaskade gewünscht wird.
|
||||
* @param n Kann 0 bis getStapelHoehe(index)-1 sein. Gibt an, welche Karte darin gewünscht wird.
|
||||
* @return Die gewünschte Karte
|
||||
*/
|
||||
public Karte getKarteInStapel(int index, int n)
|
||||
{
|
||||
//# TODO: Lassen Sie die n-te Karte aus der Kaskade mit der Nummer index zurückgeben.
|
||||
//# n ist dabei von oben gezählt, d.h. die oberste Karte hat den Index 0.
|
||||
//# n ist immer ein gültiger Index, d.h. die Zahl liegt zwischen 0 und Höhe-1
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt zurück, ob das Spiel gewonnen ist.
|
||||
* @return true, wenn das Spiel gewonnen ist; false sonst
|
||||
*/
|
||||
public boolean istGewonnen()
|
||||
{
|
||||
//# TODO: Lassen Sie zurückgeben, ob das Spiel gewonnen ist.
|
||||
//# Das Spiel ist gewonnen, wenn die Zellen keine Karte enthalten und alle Kaskaden leer sind.
|
||||
//# Umgekehrt: Falls eine Zelle oder eine Kaskade noch eine Karte enthält, ist das Spiel noch nicht gewonnen.
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verschiebt eine Karte
|
||||
* @param vonBereich Kann ZELLEN oder KASKADEN sein. Gibt an, <b>aus</b> welchem Bereich die Karte verschoben wird.
|
||||
* @param vonIndex Kann 0 bis 7 (für Kaskaden) bzw. 0 bis 3 (für Zellen) sein. Gibt an, <b>von</b> welchem Feld des Bereichs die Karte verschoben wird.
|
||||
* @param nachBereich Kann ZELLEN, ABLAGESTAPEL oder KASKADEN sein. Gibt an, <b>zu</b> welchem Bereich die Karte verschoben wird.
|
||||
* @param nachIndex Kann 0 bis 7 (für Kaskaden) bzw. 0 bis 3 (andere Bereiche) sein. Gibt an, <b>zu</b> welchem Feld des Bereichs die Karte verschoben wird.
|
||||
* @return true, wenn die Verschiebung gültig und erfolgreich war; false sonst
|
||||
*/
|
||||
public boolean verschiebe(int vonBereich, int vonIndex, int nachBereich, int nachIndex)
|
||||
{
|
||||
//# TODO: Verschieben Sie eine Karte.
|
||||
//# vonBereich kann dabei ZELLEN oder KASKADEN sein, vonIndex ist ein jeweils gültiger Index (0 bis 3 für Zellen, 0 bis 7 für Kaskaden)
|
||||
//# nachBereich kann ZELLEN, KASKADEN oder ABLAGESTAPEL sein, nachIndex ist ein jeweils gültiger Index
|
||||
//# Sorgen Sie dafür, dass die Karten an Ihrem Ursprungsort auch entfernt wird!
|
||||
//# Geben Sie true zurück, wenn die Verschiebung gültig und erfolgreich war, sonst false
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Führt einen automatischen Zug aus, wenn dies möglich ist.
|
||||
* @return true, wenn ein automatischer Zug möglich war; false sonst
|
||||
*/
|
||||
public boolean automatischerZug()
|
||||
{
|
||||
//# TODO: (optional) Lassen Sie einen automatischen Zug ausführen.
|
||||
//# Eine Karte kann automatisch von einer Zelle oder einer Kaskade auf einen Ablagestapel gelegt werden, wenn...
|
||||
//# - sie ein As oder eine 2 ist oder
|
||||
//# - ihr Wert um höchstens 2 größer ist als die niederwertigste Karte auf allen Ablagestapeln
|
||||
//# Geben Sie true zurück, wenn ein automatischer Zug möglich war, sonst false.
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Führt einen schnellen Zug aus, wenn dies möglich ist.
|
||||
* @param bereich Kann ZELLEN oder KASKADEN sein. Gibt an, <b>aus</b> welchem Bereich die Karte verschoben wird.
|
||||
* @param index Kann 0 bis 7 (für Kaskaden) bzw. 0 bis 3 (für Zellen) sein. Gibt an, <b>von</b> welchem Feld des Bereichs die Karte verschoben wird.
|
||||
* @return true, wenn ein schneller Zug möglich war; false sonst
|
||||
*/
|
||||
public boolean schnellerZug(int bereich, int index)
|
||||
{
|
||||
//# TODO: (optional) Lassen Sie einen "schnellen Zug" ausführen. "Schnelle Züge" werden durch einen Doppelklick ausgeführt.
|
||||
//# Ein schneller Zug verschiebt die Karte
|
||||
//# - von einer Kaskade auf eine freie Zelle oder
|
||||
//# - von einer Zelle auf einen passenden Ablagestapel
|
||||
//# bereich kann dabei ZELLEN oder KASKADEN sein, index ist ein jeweils gültiger Index (0 bis 3 für Zellen, 0 bis 7 für Kaskaden)
|
||||
//# Geben Sie true zurück, wenn ein schneller Zug möglich war, sonst false.
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
122
Quellcodes/Alg_DS_Freecell/01_freecell_roh/Karte.java
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Die Klasse Karte repräsentiert eine Karte im Spiel
|
||||
*
|
||||
* @author Rainer Helfrich
|
||||
* @version Oktober 2020
|
||||
*/
|
||||
public class Karte
|
||||
{
|
||||
/**
|
||||
* Konstanten für die vier Kartenfarben
|
||||
*/
|
||||
public static final int PIK = 0;
|
||||
public static final int KREUZ = 1;
|
||||
public static final int HERZ = 2;
|
||||
public static final int KARO = 3;
|
||||
|
||||
/**
|
||||
* Konstanten für die Maße der Karte
|
||||
*/
|
||||
public static final int CARD_WIDTH = 100;
|
||||
public static final int CARD_HEIGHT = 150;
|
||||
|
||||
final private int farbe;
|
||||
final private int wert;
|
||||
private BufferedImage image;
|
||||
private boolean markiert;
|
||||
|
||||
/**
|
||||
* Erzeugt eine neue Karte
|
||||
* @param nummer Das als Zahl codierte Bild der Karte
|
||||
*/
|
||||
public Karte(int nummer)
|
||||
{
|
||||
final String[] suits = { "spades", "clubs", "hearts", "diamonds"};
|
||||
farbe = nummer / 13;
|
||||
wert = nummer % 13 + 1;
|
||||
markiert = false;
|
||||
String path = "";
|
||||
try
|
||||
{
|
||||
path = "img/"+String.format("%02d", wert)+"_of_"+suits[farbe]+".png";
|
||||
image = ImageIO.read(new File(path));
|
||||
}catch(Exception x){
|
||||
System.out.println(path);
|
||||
System.out.println(x.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet die Karte 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)
|
||||
{
|
||||
if (image != null) {
|
||||
g.drawImage(image, x, y, CARD_WIDTH, CARD_HEIGHT, null);
|
||||
} // end of if
|
||||
else
|
||||
{
|
||||
g.setColor(Color.RED);
|
||||
g.fillRoundRect(x, y, CARD_WIDTH, CARD_HEIGHT, 8, 8);
|
||||
}
|
||||
g.setColor(markiert ? Color.BLUE : Color.BLACK);
|
||||
((Graphics2D)g).setStroke(new BasicStroke(markiert ? 5 : 1));
|
||||
g.drawRoundRect(x, y, CARD_WIDTH, CARD_HEIGHT, 8, 8);
|
||||
((Graphics2D)g).setStroke(new BasicStroke(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt an, ob die Karte vom Spieler markiert (angeklickt) wurde
|
||||
*/
|
||||
public boolean getMarkiert()
|
||||
{
|
||||
return markiert;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt die Karte auf markiert/unmarkiert
|
||||
* @param b true = markiert; false = unmarkiert
|
||||
*/
|
||||
public void setMarkiert(boolean b)
|
||||
{
|
||||
markiert = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt den Zahlwert der Karte zurück
|
||||
* @return Der Zahlwert der Karte (1 = As, 2-10, 11 = Bube, 12 = Dame, 13 = König)
|
||||
*/
|
||||
public int getWert()
|
||||
{
|
||||
return wert;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt die Farbe der Karte zurück
|
||||
* @return Einer der Werte PIK, KREUZ, HERZ, KARO
|
||||
*/
|
||||
public int getFarbe()
|
||||
{
|
||||
return farbe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt zurück, ob es sich um eine rote Karte (Herz oder Karo) handelt
|
||||
* @return true für eine rote Karte, false für eine schwarze
|
||||
*/
|
||||
public boolean istRot()
|
||||
{
|
||||
return farbe == HERZ || farbe == KARO;
|
||||
}
|
||||
}
|
||||
8
Quellcodes/Alg_DS_Freecell/01_freecell_roh/README.TXT
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
PROJEKTBEZEICHNUNG: Freecell
|
||||
PROJEKTZWECK: Implementieren Sie die Patience Freecell
|
||||
VERSION oder DATUM: Oktober 2020
|
||||
WIE IST DAS PROJEKT ZU STARTEN: Erzeugen Sie ein neues Objekt vom Typ FreecellGame (mit dem int-Parameter kann man steuern, welche Ausgangssituation erzeugt werden soll; lässt man ihn weg, ist die Ausgangssituation zufällig)
|
||||
AUTOR(EN): Rainer Helfrich, ZPG Informatik
|
||||
|
||||
Quelle der Spielkarten-Bilder:
|
||||
https://commons.wikimedia.org/wiki/File:English_pattern_playing_cards_deck.svg (Public Domain)
|
||||
32
Quellcodes/Alg_DS_Freecell/01_freecell_roh/Stack.java
Normal 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();
|
||||
}
|
||||
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/01_of_clubs.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/01_of_hearts.png
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/01_of_spades.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/02_of_clubs.png
Normal file
|
After Width: | Height: | Size: 6 KiB |
|
After Width: | Height: | Size: 7 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/02_of_hearts.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/02_of_spades.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/03_of_clubs.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 7.8 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/03_of_hearts.png
Normal file
|
After Width: | Height: | Size: 8.8 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/03_of_spades.png
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/04_of_clubs.png
Normal file
|
After Width: | Height: | Size: 6 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/04_of_hearts.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/04_of_spades.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/05_of_clubs.png
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 8.2 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/05_of_hearts.png
Normal file
|
After Width: | Height: | Size: 8.7 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/05_of_spades.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/06_of_clubs.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
|
After Width: | Height: | Size: 8.1 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/06_of_hearts.png
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/06_of_spades.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/07_of_clubs.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/07_of_hearts.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/07_of_spades.png
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/08_of_clubs.png
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 10 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/08_of_hearts.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/08_of_spades.png
Normal file
|
After Width: | Height: | Size: 9 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/09_of_clubs.png
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 9.8 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/09_of_hearts.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/09_of_spades.png
Normal file
|
After Width: | Height: | Size: 8.7 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/10_of_clubs.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 11 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/10_of_hearts.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/10_of_spades.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/11_of_clubs.png
Normal file
|
After Width: | Height: | Size: 97 KiB |
|
After Width: | Height: | Size: 93 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/11_of_hearts.png
Normal file
|
After Width: | Height: | Size: 96 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/11_of_spades.png
Normal file
|
After Width: | Height: | Size: 89 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/12_of_clubs.png
Normal file
|
After Width: | Height: | Size: 101 KiB |
|
After Width: | Height: | Size: 93 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/12_of_hearts.png
Normal file
|
After Width: | Height: | Size: 102 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/12_of_spades.png
Normal file
|
After Width: | Height: | Size: 102 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/13_of_clubs.png
Normal file
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 96 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/13_of_hearts.png
Normal file
|
After Width: | Height: | Size: 99 KiB |
BIN
Quellcodes/Alg_DS_Freecell/01_freecell_roh/img/13_of_spades.png
Normal file
|
After Width: | Height: | Size: 96 KiB |
|
|
@ -0,0 +1,3 @@
|
|||
Quelle: https://commons.wikimedia.org/wiki/File:English_pattern_playing_cards_deck.svg
|
||||
Public Domain
|
||||
Modifikationen von Rainer Helfrich (in Einzelbilder zerlegt)
|
||||
68
Quellcodes/Alg_DS_Freecell/01_freecell_roh/package.bluej
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
#BlueJ package file
|
||||
dependency1.from=FreecellFrame
|
||||
dependency1.to=FreecellGame
|
||||
dependency1.type=UsesDependency
|
||||
dependency2.from=FreecellFrame
|
||||
dependency2.to=Karte
|
||||
dependency2.type=UsesDependency
|
||||
dependency3.from=FreecellGame
|
||||
dependency3.to=Karte
|
||||
dependency3.type=UsesDependency
|
||||
dependency4.from=FreecellGame
|
||||
dependency4.to=Stack
|
||||
dependency4.type=UsesDependency
|
||||
dependency5.from=FreecellGame
|
||||
dependency5.to=FreecellFrame
|
||||
dependency5.type=UsesDependency
|
||||
editor.fx.0.height=0
|
||||
editor.fx.0.width=0
|
||||
editor.fx.0.x=0
|
||||
editor.fx.0.y=0
|
||||
objectbench.height=93
|
||||
objectbench.width=760
|
||||
package.divider.horizontal=0.6
|
||||
package.divider.vertical=0.8
|
||||
package.editor.height=393
|
||||
package.editor.width=649
|
||||
package.editor.x=340
|
||||
package.editor.y=126
|
||||
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=FreecellFrame
|
||||
target1.showInterface=false
|
||||
target1.type=ClassTarget
|
||||
target1.width=110
|
||||
target1.x=130
|
||||
target1.y=20
|
||||
target2.height=50
|
||||
target2.name=Karte
|
||||
target2.showInterface=false
|
||||
target2.type=ClassTarget
|
||||
target2.width=80
|
||||
target2.x=400
|
||||
target2.y=90
|
||||
target3.height=50
|
||||
target3.name=FreecellGame
|
||||
target3.showInterface=false
|
||||
target3.type=ClassTarget
|
||||
target3.width=110
|
||||
target3.x=240
|
||||
target3.y=190
|
||||
target4.height=50
|
||||
target4.name=Stack
|
||||
target4.showInterface=false
|
||||
target4.type=AbstractTarget
|
||||
target4.width=80
|
||||
target4.x=400
|
||||
target4.y=20
|
||||
101
Quellcodes/Alg_DS_Freecell/02_freecell_loes/ArrayStack.java
Normal 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();
|
||||
}
|
||||
}
|
||||
257
Quellcodes/Alg_DS_Freecell/02_freecell_loes/FreecellFrame.java
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Das Fenster, in dem das Freecell-Spiel dargestellt wird.
|
||||
* Hier sollte nichts verändert werden.
|
||||
*
|
||||
* @version 10.10.2020
|
||||
* @author Rainer Helfrich
|
||||
*/
|
||||
public class FreecellFrame extends JFrame {
|
||||
|
||||
public FreecellFrame(FreecellGame g) {
|
||||
// Frame-Initialisierung
|
||||
super();
|
||||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
int frameWidth = 8*Karte.CARD_WIDTH+150;
|
||||
int frameHeight = 640+2*Karte.CARD_HEIGHT;
|
||||
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("Freecell");
|
||||
setResizable(false);
|
||||
Container cp = getContentPane();
|
||||
cp.setLayout(null);
|
||||
// Anfang Komponenten
|
||||
|
||||
JPanel jPanel1 = new FreecellPanel(g);
|
||||
jPanel1.setBounds(0, 0, frameWidth, frameHeight);
|
||||
jPanel1.setOpaque(true);
|
||||
cp.add(jPanel1);
|
||||
// Ende Komponenten
|
||||
|
||||
setVisible(true);
|
||||
} // end of public FreecellFrame
|
||||
|
||||
|
||||
|
||||
// Ende Methoden
|
||||
private class FreecellPanel extends JPanel implements MouseListener{
|
||||
|
||||
FreecellGame dasSpiel;
|
||||
|
||||
public FreecellPanel(FreecellGame g)
|
||||
{
|
||||
super( null, true);
|
||||
dasSpiel = g;
|
||||
this.addMouseListener(this);
|
||||
markiert = null;
|
||||
sourceArea = -1;
|
||||
sourceIndex = -1;
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
g.setColor(new Color(0, 100, 0));
|
||||
g.fillRect(0,0,getWidth(),getHeight());
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Karte k = dasSpiel.getKarte(FreecellGame.ZELLEN, i);
|
||||
if (k == null)
|
||||
{
|
||||
g.setColor(new Color(0, 80, 0));
|
||||
g.fillRoundRect(10+(Karte.CARD_WIDTH+10)*i, 20, Karte.CARD_WIDTH, Karte.CARD_HEIGHT, 8, 8);
|
||||
g.setColor(Color.BLACK);
|
||||
g.drawRoundRect(10+(Karte.CARD_WIDTH+10)*i, 20, Karte.CARD_WIDTH, Karte.CARD_HEIGHT, 8, 8);
|
||||
} // end of if
|
||||
else
|
||||
{
|
||||
k.zeichne(g, 10+(Karte.CARD_WIDTH+10)*i, 20);
|
||||
}
|
||||
} // end of for
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Karte k = dasSpiel.getKarte(FreecellGame.ABLAGESTAPEL, i);
|
||||
if (k == null)
|
||||
{
|
||||
g.setColor(new Color(0, 80, 0));
|
||||
g.fillRoundRect(4*Karte.CARD_WIDTH+90+(Karte.CARD_WIDTH+10)*i, 20, Karte.CARD_WIDTH, Karte.CARD_HEIGHT, 8, 8);
|
||||
g.setColor(Color.BLACK);
|
||||
g.drawRoundRect(4*Karte.CARD_WIDTH+90+(Karte.CARD_WIDTH+10)*i, 20, Karte.CARD_WIDTH, Karte.CARD_HEIGHT, 8, 8);
|
||||
} // end of if
|
||||
else
|
||||
{
|
||||
k.zeichne(g, 4*Karte.CARD_WIDTH+90+(Karte.CARD_WIDTH+10)*i, 20);
|
||||
}
|
||||
} // end of for
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int hoehe = dasSpiel.getStapelHoehe(i);
|
||||
for (int j = 0; j < hoehe; j++)
|
||||
{
|
||||
Karte k = dasSpiel.getKarteInStapel(i, hoehe-1-j);
|
||||
k.zeichne(g, 35+(Karte.CARD_WIDTH+10)*i, Karte.CARD_HEIGHT+55+j*30);
|
||||
}
|
||||
} // end of for
|
||||
}
|
||||
|
||||
Karte markiert;
|
||||
int sourceArea;
|
||||
int sourceIndex;
|
||||
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1)
|
||||
{
|
||||
int area = getArea(e.getPoint());
|
||||
if (area == FreecellGame.ABLAGESTAPEL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int index = getIndex(e.getPoint(), area);
|
||||
if (index == FreecellGame.KEINER)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (dasSpiel.schnellerZug(area, index))
|
||||
{
|
||||
if (markiert != null)
|
||||
{
|
||||
markiert.setMarkiert(false);
|
||||
markiert = null;
|
||||
}
|
||||
finishMove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void mouseEntered(MouseEvent e){
|
||||
}
|
||||
|
||||
public void mousePressed(MouseEvent e){
|
||||
}
|
||||
|
||||
|
||||
private int getArea(Point p)
|
||||
{
|
||||
if (p.getY() >= 20 && p.getY() <= Karte.CARD_HEIGHT+20)
|
||||
{
|
||||
if (p.getX() >= 10 && p.getX() <= Karte.CARD_WIDTH*4+40)
|
||||
{
|
||||
return FreecellGame.ZELLEN;
|
||||
} // end of if
|
||||
if (p.getX() >= Karte.CARD_WIDTH*4+90 && p.getY() <= Karte.CARD_WIDTH*8+120)
|
||||
{
|
||||
return FreecellGame.ABLAGESTAPEL;
|
||||
} // end of if
|
||||
} // end of if
|
||||
if (p.getY() >= Karte.CARD_HEIGHT+55 && p.getX() >= 35 && p.getX() <= Karte.CARD_WIDTH*8+105)
|
||||
{
|
||||
return FreecellGame.KASKADEN;
|
||||
}
|
||||
return FreecellGame.KEINER;
|
||||
}
|
||||
|
||||
private int getIndex(Point p, int area)
|
||||
{
|
||||
if (area < 0)
|
||||
{
|
||||
return FreecellGame.KEINER;
|
||||
}
|
||||
int x = (int)p.getX();
|
||||
if (area == FreecellGame.ZELLEN)
|
||||
{
|
||||
x -= 10;
|
||||
} // end of if
|
||||
if (area == FreecellGame.ABLAGESTAPEL)
|
||||
{
|
||||
x -= 4*Karte.CARD_WIDTH+90;
|
||||
} // end of if
|
||||
if (area == FreecellGame.KASKADEN)
|
||||
{
|
||||
x -= 35;
|
||||
} // end of if
|
||||
if (x % (Karte.CARD_WIDTH+10) < Karte.CARD_WIDTH)
|
||||
{
|
||||
return x / (Karte.CARD_WIDTH+10);
|
||||
} // end of if
|
||||
return FreecellGame.KEINER;
|
||||
}
|
||||
|
||||
public void mouseReleased(MouseEvent e)
|
||||
{
|
||||
int area = getArea(e.getPoint());
|
||||
int index = getIndex(e.getPoint(), area);
|
||||
if (area == FreecellGame.KEINER || index == FreecellGame.KEINER) {
|
||||
if (markiert != null)
|
||||
markiert.setMarkiert(false);
|
||||
markiert = null;
|
||||
} // end of if
|
||||
else if (markiert == null)
|
||||
{
|
||||
if (area == FreecellGame.ZELLEN || area == FreecellGame.KASKADEN)
|
||||
{
|
||||
markiert = dasSpiel.getKarte(area, index);
|
||||
}
|
||||
if (markiert != null)
|
||||
{
|
||||
markiert.setMarkiert(true);
|
||||
sourceArea = area;
|
||||
sourceIndex = index;
|
||||
} // end of if
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sourceArea == area && sourceIndex == index ||
|
||||
dasSpiel.verschiebe(sourceArea, sourceIndex, area, index))
|
||||
{
|
||||
markiert.setMarkiert(false);
|
||||
markiert = null;
|
||||
}
|
||||
}
|
||||
finishMove();
|
||||
}
|
||||
|
||||
private void finishMove()
|
||||
{
|
||||
if (markiert != null)
|
||||
{
|
||||
repaint();
|
||||
return;
|
||||
}
|
||||
while(true)
|
||||
{
|
||||
paintImmediately(0, 0, getWidth(), getHeight());
|
||||
if (dasSpiel.automatischerZug())
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(300);
|
||||
}
|
||||
catch(Exception x)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dasSpiel.istGewonnen())
|
||||
{
|
||||
JOptionPane.showMessageDialog(null,"Gewonnen!","Spiel beendet", JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // end of class FreecellFrame
|
||||
378
Quellcodes/Alg_DS_Freecell/02_freecell_loes/FreecellGame.java
Normal file
|
|
@ -0,0 +1,378 @@
|
|||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Das Spielfeld selbst
|
||||
*
|
||||
* @author Rainer Helfrich
|
||||
* @version Oktober 2020
|
||||
*/
|
||||
public class FreecellGame
|
||||
{
|
||||
/**
|
||||
* Die vier Zellen oben links
|
||||
*/
|
||||
private Karte[] zellen;
|
||||
|
||||
/**
|
||||
* Die vier Stapel oben rechts
|
||||
*/
|
||||
private Stack<Karte>[] ablagestapel;
|
||||
|
||||
/**
|
||||
* Die acht Stapel unten, auf denen die Karten zu Beginn liegen
|
||||
*/
|
||||
private Stack<Karte>[] kaskaden;
|
||||
|
||||
/**
|
||||
* Konstanten, die für die verschiedenen Ablegebereiche stehen.
|
||||
*/
|
||||
public static final int ZELLEN = 0;
|
||||
public static final int ABLAGESTAPEL = 1;
|
||||
public static final int KASKADEN = 2;
|
||||
public static final int KEINER = -1;
|
||||
|
||||
/**
|
||||
* Erzeugt ein neues Spiel mit einer zufälligen Ausgangssituation.
|
||||
*/
|
||||
public FreecellGame()
|
||||
{
|
||||
this(new Random());
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein neues Spiel mit einer vorgegebenen Nummer.
|
||||
* Ein Spiel mit einer bestimmten Nummer beginnt immer in der gleichen Ausgangssituation.
|
||||
* @param nummer Legt fest, welche Ausgangssituation verwendet wird.
|
||||
*/
|
||||
public FreecellGame(int nummer)
|
||||
{
|
||||
this(new Random(nummer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein neues Spiel
|
||||
* @param r Der Zufallsgenerator, der zum zufälligen Füllen der Kaskaden verwendet wird.
|
||||
*/
|
||||
private FreecellGame(Random r)
|
||||
{
|
||||
zellen = new Karte[4];
|
||||
ablagestapel = new Stack[4];
|
||||
kaskaden = new Stack[8];
|
||||
ArrayList<Integer> zahlen = new ArrayList<Integer>(52);
|
||||
for (int i = 0; i < 52; i++) {
|
||||
zahlen.add(i);
|
||||
}
|
||||
//# TODO: Erzeugen Sie die Stacks für den Ablagestapel und die Kaskaden
|
||||
for (int i = 0; i < ablagestapel.length; i++) {
|
||||
ablagestapel[i] = new ArrayStack<Karte>();
|
||||
}
|
||||
for (int i = 0; i < kaskaden.length; i++) {
|
||||
kaskaden[i] = new ArrayStack<Karte>();
|
||||
}
|
||||
//# Ende TODO
|
||||
for (int i = 0; i < kaskaden.length; i++)
|
||||
{
|
||||
for (int j = 0; j < ((i < 4) ? 7 : 6); j++) {
|
||||
int rnd = r.nextInt(zahlen.size());
|
||||
Karte k = new Karte(zahlen.get(rnd));
|
||||
zahlen.remove(rnd);
|
||||
if (kaskaden[i] != null)
|
||||
{
|
||||
kaskaden[i].push(k);
|
||||
}
|
||||
}
|
||||
}
|
||||
new FreecellFrame(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt die oberste Karte aus dem angegebenen Bereich zurück
|
||||
* @param bereich Kann ZELLEN, ABLAGESTAPEL oder KASKADEN sein.
|
||||
* @param index Kann 0 bis 7 (für Kaskaden) bzw. 0 bis 3 (andere Bereiche) sein. Gibt an, welches Feld des Bereichs gewünscht wird.
|
||||
* @return Die oberste Karte, sofern eine dort liegt. null sonst.
|
||||
*/
|
||||
public Karte getKarte(int bereich, int index)
|
||||
{
|
||||
//# TODO: Sorgen Sie dafür, dass die (oberste) Karte aus dem gewünschten Bereich zurückgegeben wird.
|
||||
//# Wenn ein Stapel leer ist, soll null zurückgegeben werden.
|
||||
if (bereich == ZELLEN)
|
||||
{
|
||||
return zellen[index];
|
||||
}
|
||||
if (bereich == KASKADEN && !kaskaden[index].isEmpty())
|
||||
{
|
||||
return kaskaden[index].top();
|
||||
}
|
||||
if (bereich == ABLAGESTAPEL && !ablagestapel[index].isEmpty())
|
||||
{
|
||||
return ablagestapel[index].top();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt die Höhe der Kaskade mit der gegebenen Nummer zurück
|
||||
* @param index Kann 0 bis 7 sein. Gibt an, welche Kaskade gewünscht wird.
|
||||
* @return Die Höhe der Kaskade.
|
||||
*/
|
||||
public int getStapelHoehe(int index)
|
||||
{
|
||||
//# TODO: Lassen Sie zurückgeben, wie hoch der Stapel der Kaskade mit der Nummer index ist.
|
||||
int size = 0;
|
||||
Stack<Karte> temp = new ArrayStack<Karte>();
|
||||
Stack<Karte> s = kaskaden[index];
|
||||
while(!s.isEmpty())
|
||||
{
|
||||
temp.push(s.pop());
|
||||
size++;
|
||||
}
|
||||
while(!temp.isEmpty())
|
||||
{
|
||||
s.push(temp.pop());
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt die n-te Karte von oben in der Kaskade mit der Nummer index zurück.
|
||||
* Die Parameter sind immer in gültigen Bereichen, wenn die Methode von FreecellFrame aufgerufen wird.
|
||||
* @param index Kann 0 bis 7 sein. Gibt an, welche Kaskade gewünscht wird.
|
||||
* @param n Kann 0 bis getStapelHoehe(index)-1 sein. Gibt an, welche Karte darin gewünscht wird.
|
||||
* @return Die gewünschte Karte
|
||||
*/
|
||||
public Karte getKarteInStapel(int index, int n)
|
||||
{
|
||||
//# TODO: Lassen Sie die n-te Karte aus der Kaskade mit der Nummer index zurückgeben.
|
||||
//# n ist dabei von oben gezählt, d.h. die oberste Karte hat den Index 0.
|
||||
//# n ist immer ein gültiger Index, d.h. die Zahl liegt zwischen 0 und Höhe-1
|
||||
|
||||
Stack<Karte> temp = new ArrayStack<Karte>();
|
||||
Stack<Karte> s = kaskaden[index];
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
temp.push(s.pop());
|
||||
}
|
||||
Karte k = s.top();
|
||||
while(!temp.isEmpty())
|
||||
{
|
||||
s.push(temp.pop());
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt zurück, ob das Spiel gewonnen ist.
|
||||
* @return true, wenn das Spiel gewonnen ist; false sonst
|
||||
*/
|
||||
public boolean istGewonnen()
|
||||
{
|
||||
//# TODO: Lassen Sie zurückgeben, ob das Spiel gewonnen ist.
|
||||
//# Das Spiel ist gewonnen, wenn die Zellen keine Karte enthalten und alle Kaskaden leer sind.
|
||||
//# Umgekehrt: Falls eine Zelle oder eine Kaskade noch eine Karte enthält, ist das Spiel noch nicht gewonnen.
|
||||
for (Karte k : zellen)
|
||||
{
|
||||
if (k != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (Stack<Karte> s : kaskaden)
|
||||
{
|
||||
if (!s.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verschiebt eine Karte
|
||||
* @param vonBereich Kann ZELLEN oder KASKADEN sein. Gibt an, <b>aus</b> welchem Bereich die Karte verschoben wird.
|
||||
* @param vonIndex Kann 0 bis 7 (für Kaskaden) bzw. 0 bis 3 (für Zellen) sein. Gibt an, <b>von</b> welchem Feld des Bereichs die Karte verschoben wird.
|
||||
* @param nachBereich Kann ZELLEN, ABLAGESTAPEL oder KASKADEN sein. Gibt an, <b>zu</b> welchem Bereich die Karte verschoben wird.
|
||||
* @param nachIndex Kann 0 bis 7 (für Kaskaden) bzw. 0 bis 3 (andere Bereiche) sein. Gibt an, <b>zu</b> welchem Feld des Bereichs die Karte verschoben wird.
|
||||
* @return true, wenn die Verschiebung gültig und erfolgreich war; false sonst
|
||||
*/
|
||||
public boolean verschiebe(int vonBereich, int vonIndex, int nachBereich, int nachIndex)
|
||||
{
|
||||
//# TODO: Verschieben Sie eine Karte.
|
||||
//# vonBereich kann dabei ZELLEN oder KASKADEN sein, vonIndex ist ein jeweils gültiger Index (0 bis 3 für Zellen, 0 bis 7 für Kaskaden)
|
||||
//# nachBereich kann ZELLEN, KASKADEN oder ABLAGESTAPEL sein, nachIndex ist ein jeweils gültiger Index
|
||||
//# Sorgen Sie dafür, dass die Karten an Ihrem Ursprungsort auch entfernt wird!
|
||||
//# Geben Sie true zurück, wenn die Verschiebung gültig und erfolgreich war, sonst false
|
||||
Karte k = null;
|
||||
if (vonBereich == ZELLEN)
|
||||
{
|
||||
k = zellen[vonIndex];
|
||||
}
|
||||
else if (vonBereich == KASKADEN && !kaskaden[vonIndex].isEmpty())
|
||||
{
|
||||
k = kaskaden[vonIndex].top();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
boolean erfolg = false;
|
||||
if (nachBereich == ZELLEN)
|
||||
{
|
||||
erfolg = (zellen[nachIndex] == null);
|
||||
if (erfolg)
|
||||
{
|
||||
zellen[nachIndex] = k;
|
||||
}
|
||||
}
|
||||
if (nachBereich == KASKADEN)
|
||||
{
|
||||
if (kaskaden[nachIndex].isEmpty())
|
||||
{
|
||||
erfolg = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Karte kk = kaskaden[nachIndex].top();
|
||||
erfolg = (kk.getWert() == k.getWert()+1 && kk.istRot() != k.istRot());
|
||||
}
|
||||
if (erfolg)
|
||||
{
|
||||
kaskaden[nachIndex].push(k);
|
||||
}
|
||||
}
|
||||
if (nachBereich == ABLAGESTAPEL)
|
||||
{
|
||||
if (ablagestapel[nachIndex].isEmpty())
|
||||
{
|
||||
erfolg = (k.getWert() == 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Karte kk = ablagestapel[nachIndex].top();
|
||||
erfolg = (kk.getFarbe() == k.getFarbe() && kk.getWert() == k.getWert()-1);
|
||||
}
|
||||
if (erfolg)
|
||||
{
|
||||
ablagestapel[nachIndex].push(k);
|
||||
}
|
||||
}
|
||||
if (erfolg)
|
||||
{
|
||||
if (vonBereich == ZELLEN)
|
||||
{
|
||||
zellen[vonIndex] = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
kaskaden[vonIndex].pop();
|
||||
}
|
||||
}
|
||||
return erfolg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Führt einen automatischen Zug aus, wenn dies möglich ist.
|
||||
* @return true, wenn ein automatischer Zug möglich war; false sonst
|
||||
*/
|
||||
public boolean automatischerZug()
|
||||
{
|
||||
//# TODO: (optional) Lassen Sie einen automatischen Zug ausführen.
|
||||
//# Eine Karte kann automatisch von einer Zelle oder einer Kaskade auf einen Ablagestapel gelegt werden, wenn...
|
||||
//# - sie ein As oder eine 2 ist oder
|
||||
//# - ihr Wert um höchstens 2 größer ist als die niederwertigste Karte auf allen Ablagestapeln
|
||||
//# Geben Sie true zurück, wenn ein automatischer Zug möglich war, sonst false.
|
||||
|
||||
int min = 15;
|
||||
for (Stack<Karte> s : ablagestapel)
|
||||
{
|
||||
if (s.isEmpty())
|
||||
{
|
||||
min = 0;
|
||||
break;
|
||||
}
|
||||
if (s.top().getWert() < min)
|
||||
{
|
||||
min = s.top().getWert();
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < zellen.length; i++)
|
||||
{
|
||||
if (zellen[i] != null && zellen[i].getWert() <= min+2 && verschiebeAutomatisch(zellen[i]))
|
||||
{
|
||||
zellen[i] = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (Stack<Karte> s : kaskaden)
|
||||
{
|
||||
if (!s.isEmpty() && s.top().getWert() <= min+2 && verschiebeAutomatisch(s.top()))
|
||||
{
|
||||
s.pop();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean verschiebeAutomatisch(Karte k)
|
||||
{
|
||||
if (k.getWert() == 1)
|
||||
{
|
||||
for (Stack<Karte> s: ablagestapel)
|
||||
{
|
||||
if (s.isEmpty())
|
||||
{
|
||||
s.push(k);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (Stack<Karte> s: ablagestapel)
|
||||
{
|
||||
if (!s.isEmpty() && s.top().getFarbe() == k.getFarbe() && s.top().getWert()+1 == k.getWert())
|
||||
{
|
||||
s.push(k);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Führt einen schnellen Zug aus, wenn dies möglich ist.
|
||||
* @param bereich Kann ZELLEN oder KASKADEN sein. Gibt an, <b>aus</b> welchem Bereich die Karte verschoben wird.
|
||||
* @param index Kann 0 bis 7 (für Kaskaden) bzw. 0 bis 3 (für Zellen) sein. Gibt an, <b>von</b> welchem Feld des Bereichs die Karte verschoben wird.
|
||||
* @return true, wenn ein schneller Zug möglich war; false sonst
|
||||
*/
|
||||
public boolean schnellerZug(int bereich, int index)
|
||||
{
|
||||
//# TODO: (optional) Lassen Sie einen "schnellen Zug" ausführen. "Schnelle Züge" werden durch einen Doppelklick ausgeführt.
|
||||
//# Ein schneller Zug verschiebt die Karte
|
||||
//# - von einer Kaskade auf eine freie Zelle oder
|
||||
//# - von einer Zelle auf einen passenden Ablagestapel
|
||||
//# bereich kann dabei ZELLEN oder KASKADEN sein, index ist ein jeweils gültiger Index (0 bis 3 für Zellen, 0 bis 7 für Kaskaden)
|
||||
//# Geben Sie true zurück, wenn ein schneller Zug möglich war, sonst false.
|
||||
if (bereich == ZELLEN && zellen[index] != null)
|
||||
{
|
||||
Karte k = zellen[index];
|
||||
zellen[index] = null;
|
||||
return verschiebeAutomatisch(k);
|
||||
}
|
||||
if (bereich == KASKADEN && !kaskaden[index].isEmpty())
|
||||
{
|
||||
for (int i = 0; i < zellen.length; i++)
|
||||
{
|
||||
if (zellen[i] == null)
|
||||
{
|
||||
zellen[i] = kaskaden[index].pop();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
116
Quellcodes/Alg_DS_Freecell/02_freecell_loes/Karte.java
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class Karte
|
||||
{
|
||||
/**
|
||||
* Konstanten für die vier Kartenfarben
|
||||
*/
|
||||
public static final int PIK = 0;
|
||||
public static final int KREUZ = 1;
|
||||
public static final int HERZ = 2;
|
||||
public static final int KARO = 3;
|
||||
|
||||
/**
|
||||
* Konstanten für die Maße der Karte
|
||||
*/
|
||||
public static final int CARD_WIDTH = 100;
|
||||
public static final int CARD_HEIGHT = 150;
|
||||
|
||||
final private int farbe;
|
||||
final private int wert;
|
||||
private BufferedImage image;
|
||||
private boolean markiert;
|
||||
|
||||
/**
|
||||
* Erzeugt eine neue Karte
|
||||
* @param nummer Das als Zahl codierte Bild der Karte
|
||||
*/
|
||||
public Karte(int nummer)
|
||||
{
|
||||
final String[] suits = { "spades", "clubs", "hearts", "diamonds"};
|
||||
farbe = nummer / 13;
|
||||
wert = nummer % 13 + 1;
|
||||
markiert = false;
|
||||
String path = "";
|
||||
try
|
||||
{
|
||||
path = "img/"+String.format("%02d", wert)+"_of_"+suits[farbe]+".png";
|
||||
image = ImageIO.read(new File(path));
|
||||
}catch(Exception x){
|
||||
System.out.println(path);
|
||||
System.out.println(x.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet die Karte 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)
|
||||
{
|
||||
if (image != null) {
|
||||
g.drawImage(image, x, y, CARD_WIDTH, CARD_HEIGHT, null);
|
||||
} // end of if
|
||||
else
|
||||
{
|
||||
g.setColor(Color.RED);
|
||||
g.fillRoundRect(x, y, CARD_WIDTH, CARD_HEIGHT, 8, 8);
|
||||
}
|
||||
g.setColor(markiert ? Color.BLUE : Color.BLACK);
|
||||
((Graphics2D)g).setStroke(new BasicStroke(markiert ? 5 : 1));
|
||||
g.drawRoundRect(x, y, CARD_WIDTH, CARD_HEIGHT, 8, 8);
|
||||
((Graphics2D)g).setStroke(new BasicStroke(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt an, ob die Karte vom Spieler markiert (angeklickt) wurde
|
||||
*/
|
||||
public boolean getMarkiert()
|
||||
{
|
||||
return markiert;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt die Karte auf markiert/unmarkiert
|
||||
* @param b true = markiert; false = unmarkiert
|
||||
*/
|
||||
public void setMarkiert(boolean b)
|
||||
{
|
||||
markiert = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt den Zahlwert der Karte zurück
|
||||
* @return Der Zahlwert der Karte (1 = As, 2-10, 11 = Bube, 12 = Dame, 13 = König)
|
||||
*/
|
||||
public int getWert()
|
||||
{
|
||||
return wert;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt die Farbe der Karte zurück
|
||||
* @return Einer der Werte PIK, KREUZ, HERZ, KARO
|
||||
*/
|
||||
public int getFarbe()
|
||||
{
|
||||
return farbe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt zurück, ob es sich um eine rote Karte (Herz oder Karo) handelt
|
||||
* @return true für eine rote Karte, false für eine schwarze
|
||||
*/
|
||||
public boolean istRot()
|
||||
{
|
||||
return farbe == HERZ || farbe == KARO;
|
||||
}
|
||||
}
|
||||
8
Quellcodes/Alg_DS_Freecell/02_freecell_loes/README.TXT
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
PROJEKTBEZEICHNUNG: Freecell
|
||||
PROJEKTZWECK: Implementieren Sie die Patience Freecell
|
||||
VERSION oder DATUM: Oktober 2020
|
||||
WIE IST DAS PROJEKT ZU STARTEN: Erzeugen Sie ein neues Objekt vom Typ FreecellGame (mit dem int-Parameter kann man steuern, welche Ausgangssituation erzeugt werden soll; lässt man ihn weg, ist die Ausgangssituation zufällig)
|
||||
AUTOR(EN): Rainer Helfrich, ZPG Informatik
|
||||
|
||||
Quelle der Spielkarten-Bilder:
|
||||
https://commons.wikimedia.org/wiki/File:English_pattern_playing_cards_deck.svg (Public Domain)
|
||||
32
Quellcodes/Alg_DS_Freecell/02_freecell_loes/Stack.java
Normal 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();
|
||||
}
|
||||
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/01_of_clubs.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/01_of_hearts.png
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/01_of_spades.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/02_of_clubs.png
Normal file
|
After Width: | Height: | Size: 6 KiB |
|
After Width: | Height: | Size: 7 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/02_of_hearts.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/02_of_spades.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/03_of_clubs.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 7.8 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/03_of_hearts.png
Normal file
|
After Width: | Height: | Size: 8.8 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/03_of_spades.png
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/04_of_clubs.png
Normal file
|
After Width: | Height: | Size: 6 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/04_of_hearts.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/04_of_spades.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/05_of_clubs.png
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 8.2 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/05_of_hearts.png
Normal file
|
After Width: | Height: | Size: 8.7 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/05_of_spades.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/06_of_clubs.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
|
After Width: | Height: | Size: 8.1 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/06_of_hearts.png
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/06_of_spades.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/07_of_clubs.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/07_of_hearts.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/07_of_spades.png
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/08_of_clubs.png
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 10 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/08_of_hearts.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/08_of_spades.png
Normal file
|
After Width: | Height: | Size: 9 KiB |
BIN
Quellcodes/Alg_DS_Freecell/02_freecell_loes/img/09_of_clubs.png
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 9.8 KiB |