So I am writing a sudoku solver in C++ and have run into a little snag. Below is my solve board code. It works for the first 3 rows of the puzzle, but unrecurses when hitting the end of the 4th row. Looking at the code on gdb it hits the end of the 4th row, backtracks to 6th column, tries and then unrecurses out to the end.
A couple of other notes about the code is the matrix which holds the sudoku board begins at 1,1 not 0,0. So when solveBoard is initially called the parameters are (1, 1, 0). I have also attached the setCell and checkConflicts functions for more insight on there. I have three vectors rowConf,colConf and squConf to store the values that have already been placed in the respective row, column, or square. I have been at this for hours and cannot get it to go past the 3rd row. Any assistance is greatly appreicated. Thanks!
EDIT: Added clearCell()
bool board::solveBoard(int i, int j, int count)
{
if (j > 9)
{
j = 1;
i++;
printBoard();
if (isSolved())
{
printBoard();
cout <<"The Board has been solved!" <<endl
<<" The number of recursive calls was: " <<count <<endl;
return true;
}
}
if (isBlank(i, j))
{
for (int n = 1; n < 10; n++)
{
if (setCell(i, j, (char)n + '0'))
{
if (solveBoard(i, j + 1, count + 1))
{
return true;
}
}
}
}
else
{
return (solveBoard(i, j + 1, count + 1));
}
clearCell(i, j);
return false;
}
bool board::setCell(int i, int j, char val)
{
int intVal;
intVal = atoi(&val);
if (i >= 1 && i <= BoardSize && j >= 1 && j <= BoardSize &&
intVal >= 1 && intVal <= BoardSize)
{
if (!(checkConflicts(intVal, i, j, squareNumber(i, j))))
{
return false;
}
value[i][j] = intVal;
// Set flags of the conflicts
rowConf[i][intVal] = true;
colConf[j][intVal] = true;
squConf[squareNumber(i, j)][intVal] = true;
return true;
}
else
{
throw rangeError("bad value in setCell");
}
}
bool board::checkConflicts(int val, int i, int j, int k)
{
if (i < 1 && i > BoardSize && j < 1 && j > BoardSize &&
k < 1 && k > BoardSize && val < 1 && val > BoardSize)
{
throw rangeError("bad value in checkConflicts()");
}
if (rowConf[i][val] || colConf[j][val] || squConf[k][val])
{
return false;
}
else
{
return true;
}
}
Initial Board:
-----------------------------
| 3 | 8 | -----------------------------
| | 7 | 5 -----------------------------
| 1 | | -----------------------------
-----------------------------
| | | 3 6 -----------------------------
| 2 | 4 | -----------------------------
| 7 | | -----------------------------
-----------------------------
| | 6 | 1 3 -----------------------------
| 4 5 | 2 | -----------------------------
| | | 8 -----------------------------
-----------------------------
Final Output:
-----------------------------
| 3 2 4 | 1 8 5 | 6 7 9 -----------------------------
| 6 8 9 | 7 2 3 | 4 1 5 -----------------------------
| 1 5 7 | 4 9 6 | 2 8 3 -----------------------------
-----------------------------
| | | 3 6 -----------------------------
| 2 | 4 | -----------------------------
| 7 | | -----------------------------
-----------------------------
| | 6 | 1 3 -----------------------------
| 4 5 | 2 | -----------------------------
| | | 8 -----------------------------
-----------------------------
void board::clearCell(int i, int j)
{
int intVal;
if (i >= 1 && i <= BoardSize && j >= 1 && j <= BoardSize)
{
if (value[i][j] != -1)
{
intVal = value[i][j];
rowConf[i][intVal] = false;
colConf[j][intVal] = false;
squConf[squareNumber(i, j)][intVal] = false;
value[i][j] = -1;
}
}
else
{
throw rangeError("bad value in setCell");
}
}