MH-SudokuSolver ver 4 Implementation Issues
1) Evaluation of true / false
When I applied the C code as is in C#, Visual Studio would show errors:
Operator && cannot be applied to operands of type 'int' and 'int'
Operator || cannot be applied to operands of type 'int' and 'int'
Operator '!' canot be applied to operand of type 'int'
In C, zero is false; so you could use positive values of scalars or expressions to test for true in conditional (if) and iterative statements (do, while, for).
So code like
if (!(x%4 && y%4))
becomes
if ((x%4 == 0) && (y%4 == 0))
Some more examples:
if (!box[i][ j] && !poss[i][ j])
becomes
if ((box[i, j] == 0) && (poss[i, j] == 0))
Similarly,
do
{
success = 0;
................
} while (success);
becomes
do
{
success = 0;
..................
} while (success > 0);
2) The dreaded exit
In the C program, there is the following code:
int try_obvious (void)
{
int i, j, k, success;
if (Nsolved == 81)
{
sols++;
..............
..............
exit (0);
}
..........
}
if FIRST_SOLUTION_OK is true, exit is called which stops the program. Function try_obvious is called from function solve_it. solve_it calls it recursively, and when the above code is hit, irrespective of the depth of recursion, the program just stops.
What are the constraints in C# ? Firstly, there is no exit. At least I did not find it. Secondly, MH-Sudoku Solver is a visual program, so the exit has to be to the gui. Thirdly, the C functions were translated to methods in the C# class.
First, I tried the return statement; the execution returned to the calling method (solve_it), but then the recursive logic continues. I had to return to the method above solve_it i.e. method process_input that calls solve_it, whose return goes to the application GUI.
gui --> process_input --> solve_it --> calls try_obvious and then itself recursively
I tried setting a few variables and checking for them, but since the method was in recursion, it did not work.
Next, I considered goto, however, goto transfers control only within the lexical scope (same method), but not to a label in another method.
As I was working, at one point it flashed to me that I should be using exceptions which allows us to transfer execution control to the catch block. The C# code I came up with is:
if (Nsolved == 81)
{
sols++;
// exit is called in the original C program
throw new SudokuSolvedException();
}
In process_input method, I catch the exception
try
{
solve_it(0);
}
catch (SudokuSolvedException sse)
{
.......................
return;
}
This is not an exception (an error occured), but a success condition and the exception handling mechanism is used to get out of the recursion and exit to the gui. Thus, exception handling is used as a glorified goto.