151 lines
3.2 KiB
Java
151 lines
3.2 KiB
Java
|
import java.util.*;
|
||
|
import javax.swing.*;
|
||
|
|
||
|
import java.io.IOException;
|
||
|
import java.io.FileReader;
|
||
|
import java.io.Reader;
|
||
|
|
||
|
class Sudoku {
|
||
|
|
||
|
int[] fieldValues = new int[81];
|
||
|
int[] emptyFields;
|
||
|
int currentField;
|
||
|
|
||
|
void printField() {
|
||
|
String fieldOut = "";
|
||
|
int i;
|
||
|
for(i=0; i<81; i++) {
|
||
|
if(i%27 == 0 && i>0) {
|
||
|
fieldOut += "\n---------------------\n";
|
||
|
}
|
||
|
else if(i%9 == 0) {
|
||
|
fieldOut += "\n";
|
||
|
}
|
||
|
else if(i%3 == 0) {
|
||
|
fieldOut += "| ";
|
||
|
}
|
||
|
if(fieldValues[i] != 0) {
|
||
|
fieldOut += fieldValues[i] + " ";
|
||
|
}
|
||
|
else {
|
||
|
fieldOut += " ";
|
||
|
}
|
||
|
}
|
||
|
System.out.println(fieldOut);
|
||
|
}
|
||
|
|
||
|
/** Function asks for an file name which
|
||
|
* should contain a sudoku and this sudoku
|
||
|
* into fieldValues, Empty fields should
|
||
|
* be marked by a '0'
|
||
|
*/
|
||
|
void loadFieldFromFile() {
|
||
|
String fileName = "";
|
||
|
Reader reader = null;
|
||
|
int i = 0;
|
||
|
|
||
|
fileName = JOptionPane.showInputDialog( "Enter filename" );
|
||
|
System.out.println(fileName);
|
||
|
|
||
|
try
|
||
|
{
|
||
|
reader = new FileReader (fileName);
|
||
|
for ( int c; ( c = reader.read() ) != -1; ) {
|
||
|
int v = 0;
|
||
|
v = c - (int) '0';
|
||
|
if( v >= 0 && v <= 9 ) {
|
||
|
fieldValues[i] = v;
|
||
|
i++;
|
||
|
}
|
||
|
if( i > 80 ) break;
|
||
|
}
|
||
|
}
|
||
|
catch ( IOException e) {
|
||
|
System.err.println( "Could not open file " + fileName );
|
||
|
return;
|
||
|
}
|
||
|
finally {
|
||
|
try { reader.close(); } catch ( Exception e ) { e.printStackTrace(); }
|
||
|
}
|
||
|
|
||
|
System.out.println("File loaded");
|
||
|
}
|
||
|
|
||
|
/** Function checks if "number" may be inserted
|
||
|
* in field "index"
|
||
|
*/
|
||
|
boolean isNumberAllowed(int number, int index) {
|
||
|
int i = 0, j = 0;
|
||
|
/* check col */
|
||
|
for(i=index%9; i<81; i+=9) {
|
||
|
if(fieldValues[i] == number)
|
||
|
return false;
|
||
|
}
|
||
|
/* check row */
|
||
|
for(i=index/9*9; i<(index/9*9+9); i++) {
|
||
|
if(fieldValues[i] == number)
|
||
|
return false;
|
||
|
}
|
||
|
/* check field */
|
||
|
int lu = (index/9/3*27) + (index%9/3*3); //first index of field
|
||
|
for(j = 0; j<3; j++) {
|
||
|
for(i = lu+(j*9); i<lu+(j*9)+3; i++) {
|
||
|
if(fieldValues[i] == number)
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/** Function trys to solve the current sudoku
|
||
|
* using backtracking algorithm
|
||
|
*/
|
||
|
void solveSudoku() {
|
||
|
currentField = 0;
|
||
|
stepAhead();
|
||
|
}
|
||
|
|
||
|
boolean stepAhead() {
|
||
|
if(currentField==81) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if(fieldValues[currentField] != 0) {
|
||
|
currentField++;
|
||
|
if(stepAhead()) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
for(int i = 1; i<=9; i++) {
|
||
|
if(isNumberAllowed(i, currentField)) {
|
||
|
fieldValues[currentField] = i;
|
||
|
currentField++;
|
||
|
if(stepAhead())
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
fieldValues[currentField] = 0;
|
||
|
}
|
||
|
currentField--;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
/** This class is to test the
|
||
|
* Sudoku class and it's functions
|
||
|
*/
|
||
|
class SudokuDemo {
|
||
|
public static void main(String[] args) {
|
||
|
System.out.println("Sudoku demo loading...");
|
||
|
Sudoku s = new Sudoku();
|
||
|
s.loadFieldFromFile();
|
||
|
s.printField();
|
||
|
//s.testAllowed();
|
||
|
s.solveSudoku();
|
||
|
s.printField();
|
||
|
}
|
||
|
}
|