public class Sudoku { int[][] field; // zweidimensionales Array für das Spielfeld. boolean[][] filledFromStart; // Korrespondierendes Array, welches angibt, // ob ein Feld schon von Anfang an gefüllt ist. int line, column; // Variablen für die aktuelle Zeile und Spalte. boolean finished; // Gibt an, ob wir fertig sind public static void main(String[] args) { int[][] initialState = new int[9][9]; // Fülle das Array für die Startfelder, leere Felder bleiben auf 0 gesetzt. initialState[0][0] = 8; initialState[0][2] = 9; initialState[0][3] = 2; initialState[0][8] = 3; initialState[1][0] = 7; initialState[1][4] = 9; initialState[1][5] = 3; initialState[2][4] = 6; initialState[2][5] = 1; initialState[3][0] = 1; initialState[3][2] = 4; initialState[3][7] = 8; initialState[4][2] = 3; initialState[4][6] = 2; initialState[5][1] = 6; initialState[5][6] = 3; initialState[5][8] = 4; initialState[6][3] = 4; initialState[6][4] = 5; initialState[7][4] = 8; initialState[7][5] = 2; initialState[7][8] = 7; initialState[8][0] = 3; initialState[8][5] = 7; initialState[8][6] = 4; initialState[8][8] = 9; // Erzeuge die Sudoku-Instanz und löse das Sudoku Sudoku sudoku = new Sudoku(initialState); sudoku.solveSudoku(); } /** * Konstruktor zum Erstellen eines Sudokus mit der initiellen Belegung * im übergebenen Array initialState. Leere Felder sind mit 0 zu belegen. */ public Sudoku(int[][] initialState) { field = new int[9][9]; // initialisiere die Arrays filledFromStart = new boolean[9][9]; // Initialisiere das Spielfeld mit dem Ausgangsstatus for (int i=0; i<9; i++) { for (int j=0; j<9; j++) { field[i][j] = initialState[i][j]; filledFromStart[i][j] = (initialState[i][j] != 0); // leeres Feld = 0 } } } /** * Lösung durch Backtracking */ public void solveSudoku() { finished = false; line = column = 0; // Beginne in der linken oberen Ecke if (filledFromStart[line][column]) // Wenn dieses Feld bereits gefüllt war nextFreeField(); // gehe zum nächsten freien Feld while (!finished) { // Wenn im aktuellen Feld noch nicht alle Ziffern ausprobiert wurden // probiere die nächsthöhere Ziffer und, wenn keine Bedingung verletzt // ist, gehe zum nächsten freien Feld weiter for(int k = field[line][column]; k<10; k++) { field[line][column] = k; if (conditionsOK(line, column)) { break; } // ansonsten lösche dieses Feld und gehe zurück zum letzten Feld // (das kein Startfeld war) else { field[line][column] = 0; lastFreeField(); } } } // Gib die Lösung aus outputSolution(); } /** * Gibt an, ob die Eintragung im Feld (i, j) alle Bedingungen erfüllt. */ private boolean conditionsOK(int i, int j) { boolean ok = true; // Erste Bedingung: keine doppelte Zahl in Zeile i for(int k=0; k < 9; k++) { if (field[i][k] == field[i][j]) ok = false; } // Zweite Bedingung: keine doppelte Zahl in Spalte j for(int k=0; k < 9; k++) { if (field[k][j] == field[i][j]) ok = false; } // Dritte Bedingung: keine doppelte Zahl im 3x3 Quadrat, das (i, j) enthält int top = i - (i % 3); int left = j - (j % 3); for(int k = top; k < 3; k++) { for(int l = left; l < 3; l++) { if(field[k][l] == field[i][j] && ( k != i || l != j )) ok = false; } } return ok; } /** * Gehe zum nächsten freien Feld */ private void nextFreeField() { column++; if (column > 8) { column = 0; line++; } if (line > 8) finished = true; else if (filledFromStart[line][column]) nextFreeField(); } /** * Gehe zurück zum letzten Feld, das nicht zu Beginn gefüllt war */ private void lastFreeField() { column--; if (column < 0) { column = 8; line--; } if (filledFromStart[line][column]) lastFreeField(); } /** * Gib die Lösung aus */ private void outputSolution() { System.out.println(); for (int i=0; i<9; i++) { for (int j=0; j<9; j++) { System.out.print(" " + field[i][j]); } System.out.println(); } } }