i'm currently working on a sudoku solver in javascript which i want to visualize on a canvas with p5.js, but am having some trouble with the algorithm. it generates numbers and guesses correctly, but when it finds that a solution is not viable, it does not properly work backward to the beginning to try again. here is my board object:
var x = "#";
function Board (d) {
if (d) { this.data = d; }
else { this.data = [ [5, 3, x, x, 7, x, x, x, x],
[6, x, x, 1, 9, 5, x, x, x],
[x, 9, 8, x, x, x, x, 6, x],
[8, x, x, x, 6, x, x, x, 3],
[4, x, x, 8, x, 3, x, x, 1],
[7, x, x, x, 2, x, x, x, 6],
[x, 6, x, x, x, x, 2, 8, x],
[x, x, x, 4, 1, 9, x, x, 5],
[x, x, x, x, 8, x, x, 7, 9] ]; }
this.rows = 9;
this.columns = 9;
this.size = WIDTH / this.columns;
}
Board.prototype.print = function () {
console.log("-----------------------------");
this.data.forEach(function (row, index) { console.log("| " + row.toString().replace(/,/g, " ") + " |"); });
console.log("-----------------------------");
}
Board.prototype.solve = function () {
var cell = this.findEmptyCell();
if (!cell) { return true; }
for (var digit = 1; digit <= 9; digit++) {
console.log("Trying " + digit + " at [" + cell[row] + ", " + cell[column] + "]");
if (this.isValid(cell, digit)) {
this.data[cell[row]][cell[column]] = digit;
if (this.solve()) { return true; }
this.data[cell[row]][cell[column]] = x;
}
else {
this.print();
}
}
return false;
}
Board.prototype.isValid = function (cell, digit) {
for (var c = 0; c < this.columns; c++) { if (this.data[cell[row]][c] == digit && cell[column] != c) { return false; } }
for (var r = 0; r < this.rows; r++) { if (this.data[r][cell[column]] == digit && cell[row] != r) { return false; } }
var boxRow = Math.floor(cell[row] / 3) * 3;
var boxColumn = Math.floor(cell[column] / 3) * 3;
for (boxRow; boxRow < boxRow * 3; boxRow++) {
for (boxColumn; boxColumn < boxColumn * 3; boxColumn++) {
if (this.data[boxRow][boxColumn] == digit && cell[row] != boxRow && cell[column] != boxColumn) { return false; }
}
}
return true;
}
Board.prototype.findEmptyCell = function () {
for (var r = 0; r < this.rows; r++) {
for (var c = 0; c < this.columns; c++) {
if (this.data[r][c] == x) { return [r, c]; }
}
}
return false;
}
but here is the end of the output:
...
Trying 5 at [2, 6]
board.js:39 Trying 1 at [2, 8]
board.js:23 -----------------------------
board.js:25 | 5 3 1 2 7 4 6 9 8 |
board.js:25 | 6 2 3 1 9 5 8 4 7 |
board.js:25 | 1 9 8 3 4 7 5 6 # |
board.js:25 | 8 # # # 6 # # # 3 |
board.js:25 | 4 # # 8 # 3 # # 1 |
board.js:25 | 7 # # # 2 # # # 6 |
board.js:25 | # 6 # # # # 2 8 # |
board.js:25 | # # # 4 1 9 # # 5 |
board.js:25 | # # # # 8 # # 7 9 |
board.js:27 -----------------------------
board.js:39 Trying 2 at [2, 8]
board.js:39 Trying 1 at [3, 1]
the program freezes after that line. does anyone know why?
p.s. i understand it's not recommended to ask two questions in one post, but as a side question, does anyone know why trying to draw to the p5 canvas after creating a guess does not update the canvas? i have the 'drawBoard()' functions which i have made in a separate file after the this.data[cell[row]][cell[column]] = digit;
line, but nothing is shown to the screen, only the console. could someone tell me why, and how to adjust my code so that it can be drawn to the canvas?
please let me know if i should add any more code to help my example! thank you in advance :)
edit: here is the proper solution for the board
5 3 4 ¦ 6 7 8 ¦ 9 1 2
6 7 2 ¦ 1 9 5 ¦ 3 4 8
1 9 8 ¦ 3 4 2 ¦ 5 6 7
------¦-------¦------
8 5 9 ¦ 7 6 1 ¦ 4 2 3
4 2 6 ¦ 8 5 3 ¦ 7 9 1
7 1 3 ¦ 9 2 4 ¦ 8 5 6
------¦-------¦------
9 6 1 ¦ 5 3 7 ¦ 2 8 4
2 8 7 ¦ 4 1 9 ¦ 6 3 5
3 4 5 ¦ 2 8 6 ¦ 1 7 9