Greetings,
The second part of the article defines two groups of methods. One method that
is able to read an entire Sudoku board and a couple of methods that can write
such a board, using a nice format.
We want a method that can read from a
Reader stream and initialize the
board accordingly. It would be very convenient if we could read a text file
with content as shown in the example board as shown in th first part of this
article.
Basically we want to read 81 digits or dots; a dot and a '0' both describe an
empty cell, while the digits 1 ... 9 describe a filled cell. Here goes:
-
public boolean read(Reader r) {
-
-
int i= 0, j= 0; // the first position of the board
-
-
try {
-
// keep on reading characters:
-
for (int x; (x= r.read()) != -1; ) {
-
// skip it if not a digit nor a dot
-
if (!(Character.isDigit(x) || x == '.')) continue;
-
-
// is it a digit 1 ... 9?
-
if (!(x == '0' || x == '.'))
-
setValue(i, j, x-'0');
-
-
// position i,j at next position, return when done
-
if ((j= (j+1)%9) == 0)
-
if (++i == 9) return true;
-
}
-
}
-
catch (IOException ioe) { }
-
-
// something went wrong
-
return false;
-
}
The next group of methods can print a board given a
Writer. It prints
the board using the same format as shown in the example board shown in the
first part of the article:
-
-
// print a horizontal separator line
-
private void printHorizontal(PrintWriter p) {
-
p.println("+-------+-------+-------+");
-
}
-
-
// print a little vertical line
-
private void printVertical(PrintWriter p) {
-
p.print("| ");
-
}
-
-
// print the Sudoku board
-
public void print(Writer w) {
-
-
PrintWriter p= new PrintWriter(w);
-
-
for (int i= 0; i < rows.length; i++) {
-
if (i%3 == 0) printHorizontal(p);
-
for (int j= 0; j < columns.length; j++) {
-
if (j%3 == 0) printVertical(p);
-
p.print(board[i][j]+" ");
-
}
-
printVertical(p);
-
p.println();
-
}
-
printHorizontal(p);
-
p.flush();
-
}
Note that both the read method and the write method do not close the character
streams; the Reader and Writer were passed in as a parameter so the caller of
these methods is responsible for closing the streams. The read method does
catch IOExceptions and simply returns false; all that the caller knows is that
a board could not be read for some reason, i.e. an IOException was thrown or
the content of the Reader didn't make up a valid board configuration.
Now we have all the primitive methods to manipulate a Sudoku board: we can
test and set a value anywhere on the board, we can reset a cell again, we
can initialize and entire board given a Reader and finally we can print the
Sudoku board given a Writer.
The third and last part of the article shows the actual Sudoku solver. All
methods shown above are part of a 'Sudoku' class. The solver method will also
be a member method. See you in part three of this article.
kind regards,
Jos