/* Find some moves for the board; starts with a simple approach (finding * singles), and if no moves found, starts using more involved strategies * until a move is found. The more advanced strategies can mask states * in the board, making this an efficient mechanism, but difficult for * a human to understand. */ static int allmoves( void ) { int i, n; rb->yield(); n = findmoves( ); if( 0 < n ) return n; for( i = 0 ; i < 9 ; ++i ) { count_set_digits( i, idx_row ); pairs( i, idx_row ); count_set_digits( i, idx_column ); pairs( i, idx_column ); count_set_digits( i, idx_block ); pairs( i, idx_block ); } n = findmoves( ); if( 0 < n ) return n; for( i = 0 ; i < 9 ; ++i ) { block( i ); common( i ); position2( i ); } return findmoves( ); }
int main() { FILE *fr; int i,j, sq = 0; int zmena = 0, res; printf("\nSUDOKU v1.1"); printf("\n(c) Copyright 2006, vbmacher"); if ((fr = fopen("sudoku.txt", "r")) == NULL) { printf("\nFile sudoku.txt cannot be found."); return 0; } sq = 2; for (i = 0; i < 9; i++) { if (i && !(i % 3)) sq++; else sq -= 2; for (j = 0; j < 9; j++) { fscanf(fr, "%d ", &sudoku[i][j].mark); memset(sudoku[i][j].moves, 0, sizeof(int) * 9); if (j && !(j % 3)) sq++; sudoku[i][j].square = sq; } } fclose(fr); print_sudoku(); printf("\n-------------------------------------------"); findmoves(); zac: removebadmoves(); removecrossmoves(); if (markonly()) goto zac; for (i = 0; i < 9; i++) { if (markonlycol(i)) goto zac; if (markfreecol(i)) goto zac; } for (j = 0; j < 9; j++) { if (markonlyrow(j)) goto zac; if (markfreerow(j)) goto zac; } for (i = 0; i < 9; i++) { if (markonlysq(i)) goto zac; if (markfreesq(i)) goto zac; } print_sudoku(); print_moves(); getchar(); getchar(); return 0; }
/* Return number of hints. The hints mechanism should attempt to find * 'easy' moves first, and if none are possible, then try for more * cryptic moves. */ int findhints( void ) { int i, n, mutated = 0; rb->yield(); n = findmoves( ); if( n < 2 ) { /* Each call to pairs() can mutate the board state, making the * hints very, very cryptic... so later undo the mutations. */ for( i = 0 ; i < 9 ; ++i ) { count_set_digits( i, idx_row ); pairs( i, idx_row ); count_set_digits( i, idx_column ); pairs( i, idx_column ); count_set_digits( i, idx_block ); pairs( i, idx_block ); } mutated = 1; n = findmoves( ); } if( n < 2 ) { for( i = 0 ; i < 9 ; ++i ) { block( i ); common( i ); } mutated = 1; n = findmoves( ); } /* Sort the possible moves, and allow just one hint per square */ if( 0 < n ) { int i, j; rb->qsort( possible, n, sizeof( int ), cmpindex ); for( i = 0, j = 1 ; j < n ; ++j ) { if( GET_INDEX( possible[ i ] ) == GET_INDEX( possible[ j ] ) ) { /* Let the user make mistakes - do not assume the * board is in a consistent state. */ if( GET_DIGIT( possible[i] ) == GET_DIGIT( possible[j] ) ) possible[ i ] |= possible[ j ]; } else i = j; } n = i + 1; } /* Undo any mutations of the board state */ if( mutated ) reapply( ); return n; }