"Grundkurs Programmieren in Java - Band 1 (3. Auflage, 2006)"
2001-2007, Carl Hanser Verlag

Lösungsvorschlag zu Aufgabe 12.3 (Version 4.0)

(c) 2001-2007 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() );
  }


Screenshot

Quelltexte:
AchtdamenEngine.java
AchtdamenGui.java