"Grundkurs Programmieren in Java - Band 1 (3. Auflage, 2006)"
2001-2006, Carl Hanser Verlag
Lösungsvorschlag zu Aufgabe 12.3 (Version 3.0)
(c) 2001-2006 D. Ratz, J. Scheffler, D. Seese, J. Wiesenberger
Wir benennen die Klasse AchtdamenAlle aus Aufgabe 7.4 in AchtdamenEngine um
und ändern sie so ab, dass sie in der ausgabe-Methode eine zulässige Spielfigurenkombination
nicht auf die Konsole schreibt, sondern in einem dreidimensionalen boolean-Feld loesung
abspeichert. Da wir wissen, dass es 92 Lösungen gibt, reservieren wir entsprechend viel Platz:
public static boolean[][][] loesung = new boolean[92][][]; // fuer alle 92 Loesungen
In der Methode ausgabe wird eine lokale 8x8-Matrix erzeugt, in der ein Element
genau dann auf true gesetzt wird, wenn sich an dieser Position eine Dame befindet:
public static void ausgabe(int[] brett) {
boolean[][] feld;
feld = new boolean[8][8];
for (int i=0; i < 8; i++) // Anzahl der Zeilen
for (int j=0; j < 8; j++) // Anzahl der Spalten
if (i == brett[j])
feld[i][j] = true;
else
feld[i][j] = false;
loesung[anzLoesungen] = feld; // aktuelle Loesung im globalen feld speichern
anzLoesungen++;
}
Damit man die Berechnung von einer anderen Klasse bequem starten kann, schreiben
wir (anstelle der main-Methode) noch die Methode invoke:
public static void invoke () {
int[] feld = {0,0,0,0,0,0,0,0}; // Initialisiere das Spielfeld
setze(feld,0); // Starte die Suche am linken Rand
}
Nachdem diese Methode mit
AchtdamenEngine.invoke();
aufgerufen ist, steht unter dem Bezeichner
AchtdamenEngine.loesung
das dreidimensionale boolean-Feld mit alle 92 Lösungen bereit, wobei
der erste Index die Nummer der Lösung ist, der zweite Index die Zeilen-Nr.
der jeweiligen Lösung und der dritte Index die Spalten-Nr. angibt.
Jetzt brauchen wir noch eine Klasse, die das Interface Prog1Tools.GameModel
implementiert: wir beginnen diese Klasse wie folgt:
public class AchtdamenGui implements GameModel {
private int aktNr = 0;
// Default-Konstruktor
public AchtdamenGui () {
AchtdamenEngine.invoke(); // alle Loesungen berechnen und in boolean-array 'loesung' speichern
}
// ...
}
Im Konstruktor rufen wir die invoke-Methode auf, damit der Gui zur Laufzeit alle Lösungen zur
Verfügung stehen.
Da die einzelnen Buttons in diesem Fall nur zur passiven Darstellung dienen, schreiben wir eine leere
buttonPressed-Methode:
public void buttonPressed(int row, int col) {}
Da ein Schachbrett aus 8x8-Felder besteht, schreiben wir weiter:
public int columns () {
return 8;
}
public int rows () {
return 8;
}
Mit dem Feuer-Button soll immer zur nächsten Lösung weitergeschaltet werden:
public void firePressed() {
if ( aktNr != AchtdamenEngine.loesung.length - 1 )
aktNr++;
}
Wir legen noch die Beschriftung der Titel-Leiste und des Feuer-Buttons fest:
public String getFireLabel() {
return "Nächste bitte!";
}
public String getGameName() {
return "Achtdamenproblem";
}
Im Textfenster wollen wir immer anzeigen, welche Nummer die gerade angezeigte Lösung hat:
public String getMessages() {
if (aktNr < 92)
return "Lösung Nr: " + (aktNr + 1) ;
else
return "Lösung Nr: 91 - Letzte Lösung!";
}
Es fehlt noch die Darstellung einer Lösung mittels der Buttons:
public char getContent( int row, int col ) {
if (AchtdamenEngine.loesung[aktNr][row][col])
return 'D';
else
return ' ';
}
Unsere Klasse AchtdamenGui soll auch gleichzeitig ausführbar sein, braucht
also noch eine main-Methode:
public static void main (String[] args) {
new GameEngine(new AchtdamenGui() );
}
Quelltexte:
AchtdamenEngine.java
AchtdamenGui.java