public class DameSpiel extends MiniJava { private int nrRows, nrColumns; // Board dimensions private boolean[][] board = null; // true = queen, false = empty private boolean whiteToMove; // Whose turn it is private String white, black; // Players' names //TODO Mehr Attribute? //TODO Weitere Methoden? /** * Der Konstruktor registriert Spielernamen fuer Weiss und Schwarz. * * @param white Name des als 'Weiss' bezeichneten Spielers * @param black Name des als 'Schwarz' bezeichneten Spielers */ public DameSpiel(String white, String black){ // TODO 04 this.white = white; this.black = black; } /** * Gibt das Spielbrett aus. */ private void printBoard(){ for (int j = board[0].length - 1; j >= 0; j--) { System.out.print("\n " + (1 + j)); for (int i = 0; i < board.length; i++) { System.out.print(board[i][j] ? " X" : " -"); } } System.out.print("\n "); for (int i = 1; i <= board.length; i++) { System.out.print(" " + i); } System.out.println("\n" + (whiteToMove ? white : black) + " ist am Zug."); } /** * Initialisiert das Spielbrett ueberall mit false. * Dazu wird (ggf. neuer) Speicher allokiert. */ private void initBoard() { /* TODO 01 * Diesmal vertauscht: * Erste Dimension entspricht der Breite (Spalten bzw. x), * zweite Dimension entspricht der Länge/Höhe (Zeilen bzw. y). */ board = new boolean[nrColumns][nrRows]; for (int x = 0; x < board.length; x++) for (int y = 0; y < board[x].length; y++) board[x][y] = false; } /** * Ermittelt die Groesse des Spielbretts gemaess den Spielregeln. * Das Ergebnis der Abfrage wird in den Attributen nrRows und nrColumns abgelegt. */ private void determineBoardSize() { /* TODO 02 */ write("Willkommen zum Spiel \"Kampf der Damen\". Zunächst bestimmt ihr " + "die Spielfeldmaße."); nrColumns = readInt(white + " bestimmt die Breite des Spielfeldes. Wie groß soll " + "das Spielfeld sein (5-8)?"); while (nrColumns < 5 || nrColumns > 8) // -> ungültige Eingabe nrColumns = readInt("Diese Eingabe ist ungültig. Gib für die Breite des " + "Spielfelds eine Zahl zwischen 5 und 8 (jeweils inklusive) " + "ein."); nrRows = readInt(black + " bestimmt die Länge/Höhe des Spielfeldes. Wie groß " + "soll das Spielfeld sein (" + (nrColumns-1) + "-" + (nrColumns+1) + ")?"); while (nrRows < nrColumns-1 || nrRows > nrColumns+1) // -> ungültige Eingabe nrRows = readInt("Diese Eingabe ist ungültig. Gib für die Breite des " + "Spielfelds eine Zahl zwischen " + (nrColumns-1) + " und " + (nrColumns+1) + " (jeweils inklusive) ein."); } /** * Ermittelt, wer anfaengt zu ziehen. * Das Ergebnis der Abfrage wird im Attribut whiteToMove abgelegt. */ private void determineFirstPlayer() { /* TODO 03 * Diesmal eine andere Möglichkeit, ohne Code-Duplikate einzulesen :) */ while (true) { // -> wird mit return verlassen String eingabe = readString(white + " bestimmt, wer das Spiel beginnt " + "(w = weiß, s = schwarz):"); if (eingabe.length() == 1) { char wahl = eingabe.charAt(0); // eingegebenes Zeichen zwischenspeichern if (wahl == 'w' || wahl == 's') { whiteToMove = (wahl == 'w'); // mal drüber nachdenken! return; } } // else: write("Bitte gib einen gültigen Wert ('w' oder 's') ein. Das Spiel " + "kann im später abgebrochen werden (falls erwünscht)."); } } /** * Fuehrt den Zug aus. * * @param move der auszufuehrende Zug! */ private void applyMove(int move){ /* TODO 05 * Den Zug bekommen wir nach dem beschriebenen Schema übergeben, d. h. * hier erfolgt KEINE Zuweisung an move (sonst würden wir den Parameter * ja ÜBERSCHREIBEN! move haben wir gegeben (von der aufrufenden Methode)). * move=23 steht bspw. für den Wunsch, eine Dame (Spielfigur) auf das * Feld in Spalte 2 (x), Zeile 3 (y) zu stellen. Wir nehmen an, dass move * gültig und möglich ist, müssen das dann dafür in der Hauptmethode prüfen. */ board[move/10-1][move%10-1] = true; } /** * Gibt true zurück, falls der angegebene Zug (in Form von x und y, wobei wir * bei 0 anfangen zu zählen!) gültig und möglich ist. */ private boolean zugGueltig(int spalte, int zeile) { // x = spalte = eingabe/10 // ungültige Eingabe if (spalte < 0 || zeile < 0 || spalte >= nrColumns || zeile >= nrRows) return false; int x, y; // Zeile prüfen: for (x = 0; x < nrColumns; x++) if (board[x][zeile]) return false; // Spalte prüfen: for (y = 0; y < nrRows; y++) if (board[spalte][y]) return false; // Diagonalen prüfen (am einfachsten in jede Richtung separat) // (alternativ mit Formeln; aus dieser Lösung der Einfachheit wegen entfernt) x = spalte; y = zeile; while (x < nrColumns && y < nrRows) // nach "unten" rechts if (board[x++][y++]) return false; x = spalte; y = zeile; while (x >= 0 && y < nrRows) // nach "unten" links if (board[x--][y++]) return false; x = spalte; y = zeile; while (x < nrColumns && y >= 0) // nach "oben" rechts if (board[x++][y--]) return false; x = spalte; y = zeile; while (x >= 0 && y >= 0) // nach "oben" links if (board[x--][y--]) return false; return true; } /** * Gibt true zurück, wenn kein Zug mehr möglich ist. */ private boolean spielende() { for (int x = 0; x < nrColumns; x++) for (int y = 0; y < nrRows; y++) if (zugGueltig(x, y)) return false; return true; } /** * Startet die Hauptschleife des Spiels * mit der Abfrage nach Zuegen. * Die Schleife wird durch Eingabe von -1 beendet. */ private void mainLoop() { /* TODO 06 */ while (!spielende()) { int eingabe = readInt((whiteToMove ? white : black) + " ist am Zug. Wohin möchtest du eine Dame setzen (xy)?"); if (eingabe == -1) return; // -> Spiel beenden if (zugGueltig(eingabe/10-1, eingabe%10-1)) { applyMove(eingabe); whiteToMove = !whiteToMove; // Spielerwechsel (true -> false, false -> true) printBoard(); } else { write("Dieser Zug ist ungültig bzw. nicht möglich."); } } } /** * Informiert die Benutzerin ueber den Ausgang des Spiels. * Speziell: Wer hat gewonnen (Weiss oder Schwarz)? */ private void reportWinner(){ /* TODO 07 */ write("Spieler " + (whiteToMove ? black : white) + " gewinnt."); } /** * Startet das Spiel. */ public void startGame(){ determineBoardSize(); initBoard(); determineFirstPlayer(); printBoard(); mainLoop(); reportWinner(); } public static void main(String[] args) { DameSpiel ds = new DameSpiel("Weiß", "Schwarz"); ds.startGame(); } }