#include <stdio.h>
#include "sudoku.h"

FUNC main()
{
int ct;

show_game("I expect your game to be in \"game.sud\", about to read it...\n");
init_game();
readin_game("game.sud");  
show_game("Here is your game. Hit RETURN to start solving it.\n");
getchar();

while ((ct = ct_turned_on()) != 81)
    {
    find_val_to_turn_on();
    show_game("Can't find more stuff to turn on, how about turning off?\n");
    getchar();

    find_rowcol_to_turn_off();
    find_more_rowcols_to_turn_off(COL);
    find_more_rowcols_to_turn_off(ROW);
    showall_game("Can't find more stuff to turn off, how about turning on?\n");
    getchar();
    
    if (ct == ct_turned_on())	// nothing happened!!
        find_all_pairs();
    }
show_game("ALL DONE\n");
}

FUNC find_val_to_turn_on()
{
int r,x,y,val;

for (x = 0; x < 9; x++)
    for (y = 0; y < 9; y++)
        for (val = 1; val <= 9; val++)
	    {
	    if (check_val_to_turn_on(x,y,val) == NO)
                continue;
	    turn_val_on(x,y,val);
            printf("Cell (%d,%d) is now set to %d.\n", x, y, val);
            break;
            }
}

/* if a box has NOs for X in 2 of the rows/cols, then X must be in the third */

FUNC find_rowcol_to_turn_off()
{
int box, val, b0, b1, b2, rowcol, num;

for (box = 0; box < 9; box++)
   for (val = 1; val <= 9; val++)
      {
      if (val_is_set_in_box(box, val))		
          continue;

      // printf ("Value %d is not set in box %d\n", val, box);
      for (rowcol = ROW; rowcol <= COL; rowcol++)
        {
        b0 = box_rowcol_has_maybes(box,0,val,rowcol, &num);	
        b1 = box_rowcol_has_maybes(box,1,val,rowcol, &num);	
        b2 = box_rowcol_has_maybes(box,2,val,rowcol, &num);	
        if (b0+b1+b2 != 1)
            continue;		// rowcol w/maybes is not unique

        bot_get_other_boxes_in_rowcol(box, rowcol, &b1, &b2);
        printf("In box %d, %s %d is unique for value %d. Other boxes are %d,%d.\n", 
	        box, rowcol == ROW ? "row" : "col", num, val, b1, b2);
        box_set_rowcol_off(b1, num, val, rowcol);
        box_set_rowcol_off(b2, num, val, rowcol);
        }
    }
}

/* if two boxes in row/col have NO for X is same row/col then third one must have it there
? ? +   + + +  + + +
? ? +   + + +  + + +
+ + +   + + +  + + +
 
X X ?   + + +  + + +
X X ?   + + +  + + +
X X +   + + +  + + +

? ? +   + + +  + + +
? ? +   + + +  + + +
+ + +   + + +  + + +
*/

FUNC find_more_rowcols_to_turn_off(rowcol)
{
int ii, bb, incr, idx, box_incr, box1, box2, box3, val, b1, b2, b3, num1, num2, temp;

// COLS: do box 0-3-6,1-4-7,2-5-8 (cols 0-1-2) 
// ROWS: do box 0-1-2,3-4-5,6-7-8 (rows 0-1-2)

incr = (rowcol == COL) ? 1 : 3;
box_incr = (rowcol == COL) ? 3 : 1;

for (ii = 0; ii < 3; ii++)
    {
    box1 = 0 + ii * incr;
    box2 = box1+box_incr; 
    box3 = box2+box_incr; 

    for (val = 1; val <= 9; val++)
        {
        if (val_is_set_in_box(box1, val) || val_is_set_in_box(box2, val) ||
 	  			            val_is_set_in_box(box3, val))		
            continue;

        // printf ("Value %d is not set in boxes %d,%d,%d\n", val, box1,box2,box3);
        for (idx = 0; idx < 3; idx++)	// going through rows/columns
            {
            b1 = box_rowcol_has_maybes(box1, idx, val,rowcol, &temp);	
            b2 = box_rowcol_has_maybes(box2, idx, val,rowcol, &temp);	
            b3 = box_rowcol_has_maybes(box3, idx, val,rowcol, &temp);	
            if (b1+b2+b3 != 1)
                continue;		// rowcol w/MAYBEs is not unique
  
            if (b1) bb = box1;
            else if (b2) bb = box2;
            else bb = box3;

            if (idx == 0)
               { num1 = 1; num2 = 2; }
            else if (idx == 1)
               { num1 = 0; num2 = 2; }
            else if (idx == 2)
               { num1 = 0; num2 = 1; }

            printf("Box %d is unique out of (%d,%d,%d): %s %d is unique MAYBE for value %d.\n", 
  	        bb, box1, box2, box3, rowcol == ROW ? "row" : "col", idx, val);
            printf("We need to set to NOs box %d, %s %d and %d\n", 
		bb, rowcol == ROW ? "row" : "col", num1, num2);
            box_set_rowcol_off(bb, num1, val, rowcol);
            box_set_rowcol_off(bb, num2, val, rowcol);
            }
        }
    }
}

FUNC readin_game(char *fname)
{
int x,y,val;
char cval;
FILE *fptr;

fptr = fopen(fname, "r");
for (x = 0; x < 9; x++)
    for (y = 0; y < 9; y++)
        {
        fscanf(fptr, "%c ", &cval);
        if (cval < '1' || cval > '9')
	    continue;
        val = cval - '0'; 
        turn_val_on(x,y,val); 
        }
fclose(fptr);
}

FUNC show_game(char *msg)
{
int x,y,val;
char cval;

for (x = 0; x < 9; x++)
    {
    for (y = 0; y < 9; y++)
        {
        val = bot_get_cell_val(x,y);		// 0 if no value
        cval = (val == 0) ?  '+' : val + '0';
        printf("%c ", cval); 
        }
    printf("\n"); 
    } 
printf("%s", msg);
}
        
FUNC showall_game(char *msg)
{
int x, y;
char code[10];

for (x = 0; x < 9; x++)
    {
    for (y = 0; y < 9; y++)
        {
        bot_get_cell_code(x,y,code);
        printf("%s ", code); 
        }
    printf("\n"); 
    } 
printf("%s", msg);
}
        
FUNC init_game()
{
int x,y,val;

   for (x = 0; x < 9; x++)
       for (y = 0; y < 9; y++)
           for (val = 1; val <= 9; val++)
               bot_set_val_code(x,y,val,VAL_MAYBE);
}
