1 /* sudoku.c - sudoku game
3 * Writing a fun Su-Do-Ku game has turned out to be a difficult exercise.
4 * The biggest difficulty is keeping the game fun - and this means allowing
5 * the user to make mistakes. The game is not much fun if it prevents the
6 * user from making moves, or if it informs them of an incorrect move.
7 * With movement constraints, the 'game' is little more than an automated
8 * solver (and no fun at all).
10 * Another challenge is generating good puzzles that are entertaining to
11 * solve. It is certainly true that there is an art to creating good
12 * Su-Do-Ku puzzles, and that good hand generated puzzles are more
13 * entertaining than many computer generated puzzles - I just hope that
14 * the algorithm implemented here provides fun puzzles. It is an area
15 * that needs work. The puzzle classification is very simple, and could
16 * also do with work. Finally, understanding the automatically generated
17 * hints is sometimes more work than solving the puzzle - a better, and
18 * more human friendly, mechanism is needed.
20 * Comments, suggestions, and contributions are always welcome - send email
21 * to: mike 'at' laurasia.com.au. Note that this code assumes a single
22 * threaded process, makes extensive use of global variables, and has
23 * not been written to be reused in other applications. The code makes no
24 * use of dynamic memory allocation, and hence, requires no heap. It should
25 * also run with minimal stack space.
27 * This code and accompanying files have been placed into the public domain
28 * by Michael Kennett, July 2005. It is provided without any warranty
29 * whatsoever, and in no event shall Michael Kennett be liable for
30 * any damages of any kind, however caused, arising from this software.
36 #include "templates.h"
40 /* Common state encoding in a 32-bit integer:
42 * 7-15 state [bit high signals digits not possible]
44 * 20 fixed [set if digit initially fixed]
45 * 21 choice [set if solver chose this digit]
46 * 22 ignore [set if ignored by reapply()]
51 #define INDEX_MASK 0x0000007f
52 #define GET_INDEX(val) (INDEX_MASK&(val))
53 #define SET_INDEX(val) (val)
55 #define STATE_MASK 0x0000ff80
56 #define STATE_SHIFT (7-1) /* digits 1..9 */
57 #define DIGIT_STATE(digit) BIT_N(STATE_SHIFT+(digit))
59 #define DIGIT_MASK 0x000f0000
60 #define DIGIT_SHIFT 16
61 #define GET_DIGIT(val) (((val)&DIGIT_MASK)>>(DIGIT_SHIFT))
62 #define SET_DIGIT(val) ((val)<<(DIGIT_SHIFT))
64 #define FIXED 0x00100000
65 #define CHOICE 0x00200000
66 #define IGNORED 0x00400000
68 /* Hint codes (c.f. singles(), pairs(), findmoves()) */
69 #define HINT_ROW 0x01000000
70 #define HINT_COLUMN 0x02000000
71 #define HINT_BLOCK 0x04000000
73 /* For a general board it may be necessary to do backtracking (i.e. to
74 * rewind the board to an earlier state), and make choices during the
75 * solution process. This can be implemented naturally using recursion,
76 * but it is more efficient to maintain a single board.
78 static int board
[ 81 ];
80 /* Addressing board elements: linear array 0..80 */
81 #define ROW(idx) ((idx)/9)
82 #define COLUMN(idx) ((idx)%9)
83 #define BLOCK(idx) (3*(ROW(idx)/3)+(COLUMN(idx)/3))
84 #define INDEX(row,col) (9*(row)+(col))
86 /* Blocks indexed 0..9 */
87 #define IDX_BLOCK(row,col) (3*((row)/3)+((col)/3))
88 #define TOP_LEFT(block) (INDEX(block/3,block%3))
91 #define STATE(idx) ((board[idx])&STATE_MASK)
92 #define DIGIT(idx) (GET_DIGIT(board[idx]))
93 #define HINT(idx) ((board[idx])&HINT_MASK)
94 #define IS_EMPTY(idx) (0 == DIGIT(idx))
95 #define DISALLOWED(idx,digit) ((board[idx])&DIGIT_STATE(digit))
96 #define IS_FIXED(idx) (board[idx]&FIXED)
98 /* Record move history, and maintain a counter for the current
99 * move number. Concessions are made for the user interface, and
100 * allow digit 0 to indicate clearing a square. The move history
101 * is used to support 'undo's for the user interface, and hence
102 * is larger than required - there is sufficient space to solve
103 * the puzzle, undo every move, and then redo the puzzle - and
104 * if the user requires more space, then the full history will be
107 static int idx_history
;
108 static int history
[ 3 * 81 ];
110 /* Possible moves for a given board (c.f. fillmoves()).
111 * Also used by choice() when the deterministic solver has failed,
112 * and for calculating user hints. The number of hints is stored
113 * in num_hints, or -1 if no hints calculated. The number of hints
114 * requested by the user since their last move is stored in req_hints;
115 * if the user keeps requesting hints, start giving more information.
116 * Finally, record the last hint issued to the user; attempt to give
117 * different hints each time.
119 static int idx_possible
;
120 static int possible
[ 81 ];
122 static int pass
; /* count # passes of deterministic solver */
124 /* Support for template file */
125 static int tmplt
[ 81 ]; /* Template indices */
126 static int len_tmplt
; /* Number of template indices */
128 /* Reset global state */
133 rb
->memset( board
, 0x00, sizeof( board
) );
134 rb
->memset( history
, 0x00, sizeof( history
) );
139 /* Management of the move history - compression */
142 compress( int limit
)
145 for( i
= j
= 0 ; i
< idx_history
&& j
< limit
; ++i
)
146 if( !( history
[ i
] & IGNORED
) )
147 history
[ j
++ ] = history
[ i
];
148 for( ; i
< idx_history
; ++i
)
149 history
[ j
++ ] = history
[ i
];
153 /* Management of the move history - adding a move */
156 add_move( int idx
, int digit
, int choice
)
160 if( sizeof( history
) / sizeof( int ) == idx_history
)
163 /* Never ignore the last move */
164 history
[ idx_history
++ ] = SET_INDEX( idx
) | SET_DIGIT( digit
) | choice
;
166 /* Ignore all previous references to idx */
167 for( i
= idx_history
- 2 ; 0 <= i
; --i
)
168 if( GET_INDEX( history
[ i
] ) == idx
)
170 history
[ i
] |= IGNORED
;
175 /* Iteration over rows/columns/blocks handled by specialised code.
176 * Each function returns a block index - call must manage element/idx.
180 idx_row( int el
, int idx
) /* Index within a row */
182 return INDEX( el
, idx
);
187 idx_column( int el
, int idx
) /* Index within a column */
189 return INDEX( idx
, el
);
194 idx_block( int el
, int idx
) /* Index within a block */
196 return INDEX( 3 * ( el
/ 3 ) + idx
/ 3, 3 * ( el
% 3 ) + idx
% 3 );
199 /* Update board state after setting a digit (clearing not handled)
205 const int row
= ROW( idx
);
206 const int col
= COLUMN( idx
);
207 const int block
= IDX_BLOCK( row
, col
);
208 const int mask
= DIGIT_STATE( DIGIT( idx
) );
211 board
[ idx
] |= STATE_MASK
; /* filled - no choice possible */
213 /* Digit cannot appear in row, column or block */
214 for( i
= 0 ; i
< 9 ; ++i
)
216 board
[ idx_row( row
, i
) ] |= mask
;
217 board
[ idx_column( col
, i
) ] |= mask
;
218 board
[ idx_block( block
, i
) ] |= mask
;
222 /* Refresh board state, given move history. Note that this can yield
223 * an incorrect state if the user has made errors - return -1 if an
224 * incorrect state is generated; else return 0 for a correct state.
232 rb
->memset( board
, 0x00, sizeof( board
) );
233 for( j
= 0 ; j
< idx_history
; ++j
)
234 if( !( history
[ j
] & IGNORED
) && 0 != GET_DIGIT( history
[ j
] ) )
236 idx
= GET_INDEX( history
[ j
] );
237 digit
= GET_DIGIT( history
[ j
] );
238 if( !IS_EMPTY( idx
) || DISALLOWED( idx
, digit
) )
240 board
[ idx
] = SET_DIGIT( digit
);
241 if( history
[ j
] & FIXED
)
242 board
[ idx
] |= FIXED
;
248 /* Clear moves, leaving fixed squares
254 for( idx_history
= 0 ; history
[ idx_history
] & FIXED
; ++idx_history
)
259 static int digits
[ 9 ]; /* # digits expressed in element square */
260 static int counts
[ 9 ]; /* Count of digits (c.f. count_set_digits()) */
262 /* Count # set bits (within STATE_MASK) */
268 for( i
= STATE_SHIFT
+ 1 ; i
<= STATE_SHIFT
+ 9 ; ++i
)
269 if( mask
& BIT_N(i
) )
272 ++counts
[ i
- STATE_SHIFT
- 1 ];
278 count_set_digits( int el
, int (*idx_fn
)( int, int ) )
281 rb
->memset( counts
, 0x00, sizeof( counts
) );
282 for( i
= 0 ; i
< 9 ; ++i
)
283 digits
[ i
] = numset( board
[ (*idx_fn
)( el
, i
) ] );
286 /* Fill square with given digit, and update state.
287 * Returns 0 on success, else -1 on error (i.e. invalid fill)
291 fill( int idx
, int digit
)
293 assert( 0 != digit
);
295 if( !IS_EMPTY( idx
) )
296 return ( DIGIT( idx
) == digit
) ? 0 : -1;
298 if( DISALLOWED( idx
, digit
) )
301 board
[ idx
] = SET_DIGIT( digit
);
303 add_move( idx
, digit
, 0 );
308 /* Find all squares with a single digit allowed -- do not mutate board */
311 singles( int el
, int (*idx_fn
)( int, int ), int hintcode
)
315 count_set_digits( el
, idx_fn
);
317 for( i
= 0 ; i
< 9 ; ++i
)
319 if( 1 == counts
[ i
] )
321 /* Digit 'i+1' appears just once in the element */
322 for( j
= 0 ; j
< 9 ; ++j
)
324 idx
= (*idx_fn
)( el
, j
);
325 if( !DISALLOWED( idx
, i
+ 1 ) && idx_possible
< 81 )
326 possible
[ idx_possible
++ ] = SET_INDEX( idx
)
331 if( 8 == digits
[ i
] )
333 /* 8 digits are masked at this position - just one remaining */
334 idx
= (*idx_fn
)( el
, i
);
335 for( j
= 1 ; j
<= 9 ; ++j
)
336 if( 0 == ( STATE( idx
) & DIGIT_STATE( j
) ) && idx_possible
< 81 )
337 possible
[ idx_possible
++ ] = SET_INDEX( idx
)
344 /* Given the board state, find all possible 'moves' (i.e. squares with just
347 * Returns the number of (deterministic) moves (and fills the moves array),
348 * or 0 if no moves are possible. This function does not mutate the board
349 * state, and hence, can return the same move multiple times (with
361 for( i
= 0 ; i
< 9 ; ++i
)
363 singles( i
, idx_row
, HINT_ROW
);
364 singles( i
, idx_column
, HINT_COLUMN
);
365 singles( i
, idx_block
, HINT_BLOCK
);
370 /* Strategies for refining the board state
371 * - 'pairs' if there are two unfilled squares in a given row/column/
372 * block with the same state, and just two possibilities,
373 * then all other unfilled squares in the row/column/block
374 * CANNOT be either of these digits.
375 * - 'block' if the unknown squares in a block all appear in the same
376 * row or column, then all unknown squares outside the block
377 * and in the same row/column cannot be any of the unknown
378 * squares in the block.
379 * - 'common' if all possible locations for a digit in a block appear
380 * in a row or column, then that digit cannot appear outside
381 * the block in the same row or column.
382 * - 'position2' if the positions of 2 unknown digits in a block match
383 * identically in precisely 2 positions, then those 2 positions
384 * can only contain the 2 unknown digits.
386 * Recall that each state bit uses a 1 to prevent a digit from
387 * filling that square.
392 pairs( int el
, int (*idx_fn
)( int, int ) )
394 int i
, j
, k
, mask
, idx
;
398 for( i
= 0 ; i
< 8 ; ++i
)
399 if( 7 == digits
[ i
] ) /* 2 digits unknown */
400 for( j
= i
+ 1 ; j
< 9 ; ++j
)
402 idx
= (*idx_fn
)( el
, i
);
403 if( STATE( idx
) == STATE( (*idx_fn
)( el
, j
) ) )
405 /* Found a row/column pair - mask other entries */
406 mask
= STATE_MASK
^ (STATE_MASK
& board
[ idx
] );
407 for( k
= 0 ; k
< i
; ++k
)
408 board
[ (*idx_fn
)( el
, k
) ] |= mask
;
409 for( k
= i
+ 1 ; k
< j
; ++k
)
410 board
[ (*idx_fn
)( el
, k
) ] |= mask
;
411 for( k
= j
+ 1 ; k
< 9 ; ++k
)
412 board
[ (*idx_fn
)( el
, k
) ] |= mask
;
413 digits
[ j
] = -1; /* now processed */
418 /* Worker: mask elements outside block */
421 exmask( int mask
, int block
, int el
, int (*idx_fn
)( int, int ) )
427 for( i
= 0 ; i
< 9 ; ++i
)
429 idx
= (*idx_fn
)( el
, i
);
430 if( block
!= BLOCK( idx
) && IS_EMPTY( idx
) )
431 board
[ idx
] |= mask
;
435 /* Worker for block() */
438 exblock( int block
, int el
, int (*idx_fn
)( int, int ) )
444 /* By assumption, all unknown squares in the block appear in the
445 * same row/column, so to construct a mask for these squares, it
446 * is sufficient to invert the mask for the known squares in the
450 for( i
= 0 ; i
< 9 ; ++i
)
452 idx
= idx_block( block
, i
);
453 if( !IS_EMPTY( idx
) )
454 mask
|= DIGIT_STATE( DIGIT( idx
) );
456 exmask( mask
^ STATE_MASK
, block
, el
, idx_fn
);
463 int i
, idx
= 0, row
, col
;
467 /* Find first unknown square */
468 for( i
= 0 ; i
< 9 && !IS_EMPTY( idx
= idx_block( el
, i
) ) ; ++i
)
472 assert( IS_EMPTY( idx
) );
475 for( ++i
; i
< 9 ; ++i
)
477 idx
= idx_block( el
, i
);
478 if( IS_EMPTY( idx
) )
480 if( ROW( idx
) != row
)
482 if( COLUMN( idx
) != col
)
487 exblock( el
, row
, idx_row
);
489 exblock( el
, col
, idx_column
);
497 int i
, idx
, row
, col
, digit
, mask
;
501 for( digit
= 1 ; digit
<= 9 ; ++digit
)
503 mask
= DIGIT_STATE( digit
);
504 row
= col
= -1; /* Value '9' indicates invalid */
505 for( i
= 0 ; i
< 9 ; ++i
)
507 /* Digit possible? */
508 idx
= idx_block( el
, i
);
509 if( IS_EMPTY( idx
) && 0 == ( board
[ idx
] & mask
) )
514 if( row
!= ROW( idx
) )
515 row
= 9; /* Digit appears in multiple rows */
519 if( col
!= COLUMN( idx
) )
520 col
= 9; /* Digit appears in multiple columns */
523 if( -1 != row
&& row
< 9 )
524 exmask( mask
, el
, row
, idx_row
);
525 if( -1 != col
&& col
< 9 )
526 exmask( mask
, el
, col
, idx_column
);
530 /* Encoding of positions of a digit (c.f. position2()) - abuse DIGIT_STATE */
531 static int posn_digit
[ 10 ];
537 int digit
, digit2
, i
, mask
, mask2
, posn
, count
, idx
;
541 /* Calculate positions of each digit within block */
542 for( digit
= 1 ; digit
<= 9 ; ++digit
)
544 mask
= DIGIT_STATE( digit
);
545 posn_digit
[ digit
] = count
= posn
= 0;
546 for( i
= 0 ; i
< 9 ; ++i
)
547 if( 0 == ( mask
& board
[ idx_block( el
, i
) ] ) )
550 posn
|= DIGIT_STATE( i
);
553 posn_digit
[ digit
] = posn
;
555 /* Find pairs of matching positions, and mask */
556 for( digit
= 1 ; digit
< 9 ; ++digit
)
557 if( 0 != posn_digit
[ digit
] )
558 for( digit2
= digit
+ 1 ; digit2
<= 9 ; ++digit2
)
559 if( posn_digit
[ digit
] == posn_digit
[ digit2
] )
562 ^ ( DIGIT_STATE( digit
) | DIGIT_STATE( digit2
) );
563 mask2
= DIGIT_STATE( digit
);
564 for( i
= 0 ; i
< 9 ; ++i
)
566 idx
= idx_block( el
, i
);
567 if( 0 == ( mask2
& board
[ idx
] ) )
569 assert( 0 == (DIGIT_STATE(digit2
) & board
[idx
]) );
570 board
[ idx
] |= mask
;
573 posn_digit
[ digit
] = posn_digit
[ digit2
] = 0;
578 /* Find some moves for the board; starts with a simple approach (finding
579 * singles), and if no moves found, starts using more involved strategies
580 * until a move is found. The more advanced strategies can mask states
581 * in the board, making this an efficient mechanism, but difficult for
582 * a human to understand.
596 for( i
= 0 ; i
< 9 ; ++i
)
598 count_set_digits( i
, idx_row
);
601 count_set_digits( i
, idx_column
);
602 pairs( i
, idx_column
);
604 count_set_digits( i
, idx_block
);
605 pairs( i
, idx_block
);
611 for( i
= 0 ; i
< 9 ; ++i
)
620 /* Helper: sort based on index */
623 cmpindex( const void * a
, const void * b
)
625 return GET_INDEX( *((const int *)b
) ) - GET_INDEX( *((const int *)a
) );
628 /* Return number of hints. The hints mechanism should attempt to find
629 * 'easy' moves first, and if none are possible, then try for more
635 int i
, n
, mutated
= 0;
642 /* Each call to pairs() can mutate the board state, making the
643 * hints very, very cryptic... so later undo the mutations.
645 for( i
= 0 ; i
< 9 ; ++i
)
647 count_set_digits( i
, idx_row
);
650 count_set_digits( i
, idx_column
);
651 pairs( i
, idx_column
);
653 count_set_digits( i
, idx_block
);
654 pairs( i
, idx_block
);
661 for( i
= 0 ; i
< 9 ; ++i
)
670 /* Sort the possible moves, and allow just one hint per square */
675 rb
->qsort( possible
, n
, sizeof( int ), cmpindex
);
676 for( i
= 0, j
= 1 ; j
< n
; ++j
)
678 if( GET_INDEX( possible
[ i
] ) == GET_INDEX( possible
[ j
] ) )
680 /* Let the user make mistakes - do not assume the
681 * board is in a consistent state.
683 if( GET_DIGIT( possible
[i
] ) == GET_DIGIT( possible
[j
] ) )
684 possible
[ i
] |= possible
[ j
];
692 /* Undo any mutations of the board state */
699 /* Deterministic solver; return 0 on success, else -1 on error.
703 deterministic( void )
713 for( i
= 0 ; i
< n
; ++i
)
714 if( -1 == fill( GET_INDEX( possible
[ i
] ),
715 GET_DIGIT( possible
[ i
] ) ) )
722 /* Return index of square for choice.
724 * If no choice is possible (i.e. board solved or inconsistent),
727 * The current implementation finds a square with the minimum
728 * number of unknown digits (i.e. maximum # masked digits).
732 cmp( const void * e1
, const void * e2
)
734 return GET_DIGIT( *(const int *)e2
) - GET_DIGIT( *(const int *)e1
);
745 for( n
= i
= 0 ; i
< 81 ; ++i
)
748 possible
[ n
] = SET_INDEX( i
) | SET_DIGIT( numset( board
[ i
] ) );
750 /* Inconsistency if square unknown, but nothing possible */
751 if( 9 == GET_DIGIT( possible
[ n
] ) )
757 return -1; /* All squares known */
759 rb
->qsort( possible
, n
, sizeof( possible
[ 0 ] ), cmp
);
760 return GET_INDEX( possible
[ 0 ] );
763 /* Choose a digit for the given square.
764 * The starting digit is passed as a parameter.
765 * Returns -1 if no choice possible.
769 choose( int idx
, int digit
)
773 for( ; digit
<= 9 ; ++digit
)
774 if( !DISALLOWED( idx
, digit
) )
776 board
[ idx
] = SET_DIGIT( digit
);
778 add_move( idx
, digit
, CHOICE
);
785 /* Backtrack to a previous choice point, and attempt to reseed
786 * the search. Return -1 if no further choice possible, or
787 * the index of the changed square.
789 * Assumes that the move history and board are valid.
799 for( ; 0 <= --idx_history
; )
800 if( history
[ idx_history
] & CHOICE
)
802 /* Remember the last choice, and advance */
803 idx
= GET_INDEX( history
[ idx_history
] );
804 digit
= GET_DIGIT( history
[ idx_history
] ) + 1;
806 if( -1 != choose( idx
, digit
) )
813 /* Attempt to solve 'board'; return 0 on success else -1 on error.
815 * The solution process attempts to fill-in deterministically as
816 * much of the board as possible. Once that is no longer possible,
817 * need to choose a square to fill in.
829 if( 0 == deterministic( ) )
831 /* Solved, make a new choice, or rewind a previous choice */
836 if( ( idx
< 0 || -1 == choose( idx
, 1 ) ) && -1 == backtrack( ) )
839 else /* rewind to a previous choice */
840 if( -1 == backtrack( ) )
848 init_template( int template )
856 /* Consume grid - allow leading spaces and comments at end */
857 for( row
= 0 ; row
< 9 ; ++row
)
860 for( col
= 0 ; col
< 9 ; ++col
)
862 if (templates
[template][row
] & mask
)
863 tmplt
[ len_tmplt
++ ] = INDEX( row
, col
);
868 /* Construct move history for a template */
870 for( i
= 0 ; i
< 81 ; ++i
)
871 if( 0 != DIGIT( i
) )
872 history
[ idx_history
++ ] = i
| (DIGIT( i
)<<8);
874 /* Finally, markup all of these moves as 'fixed' */
875 for( i
= 0 ; i
< idx_history
; ++i
)
876 history
[ i
] |= FIXED
;
881 /* Classify a SuDoKu, given its solution.
883 * The classification is based on the average number of possible moves
884 * for each pass of the deterministic solver - it is a rather simplistic
885 * measure, but gives reasonable results. Note also that the classification
886 * is based on the first solution found (but does handle the pathological
887 * case of multiple solutions). Note that the average moves per pass
888 * depends just on the number of squares initially set... this simplifies
889 * the statistics collection immensely, requiring just the number of passes
892 * Return 0 on error, else a string classification.
909 for( i
= 0 ; i
< 81 ; ++i
)
913 assert( 81 == idx_history
);
915 for( i
= 0 ; i
< 81 ; ++i
)
916 if( history
[ i
] & CHOICE
)
919 if( 15 * pass
< score
)
922 if( 11 * pass
< score
)
925 if( 7 * pass
< score
)
928 if( 4 * pass
< score
)
934 /* exchange disjoint, identical length blocks of data */
937 exchange( int * a
, int * b
, int len
)
940 for( i
= 0 ; i
< len
; ++i
)
951 rotate1_left( int * a
, int len
)
955 for( i
= 1 ; i
< len
; ++i
)
963 rotate1_right( int * a
, int len
)
967 for( i
= len
- 1 ; 0 < i
; --i
)
972 /* Generalised left rotation - there is a naturally recursive
973 * solution that is best implementation using iteration.
974 * Note that it is not necessary to do repeated unit rotations.
976 * This function is analogous to 'cutting' a 'pack of cards'.
978 * On entry: 0 < idx < len
982 rotate( int * a
, int len
, int idx
)
985 int delta
= idx
- xdi
;
987 while( 0 != delta
&& 0 != idx
)
993 rotate1_left( a
, len
);
998 exchange( a
, a
+ xdi
, idx
);
1002 else /* 0 < delta */
1006 rotate1_right( a
, len
);
1011 exchange( a
, a
+ idx
, xdi
);
1021 exchange( a
, a
+ idx
, idx
);
1024 /* Shuffle an array of integers */
1027 shuffle( int * a
, int len
)
1034 j
= rb
->rand( ) % i
;
1041 /* Generate a SuDoKu puzzle
1043 * The generation process selects a random template, and then attempts
1044 * to fill in the exposed squares to generate a board. The order of the
1045 * digits and of filling in the exposed squares are random.
1048 /* Select random template; sets tmplt, len_tmplt */
1051 select_template( void )
1053 int i
= rb
->rand( ) % NUM_TEMPLATES
;
1057 static bool check_buttons(void)
1059 int button
= rb
->button_get(false);
1060 return (button
&& (!(button
& BUTTON_REL
)) && (!(button
& BUTTON_REPEAT
)));
1067 static int digits
[ 9 ];
1072 /* Allow the user to abort generation by pressing any button */
1073 if (check_buttons())
1076 for( i
= 0 ; i
< 9 ; ++i
)
1077 digits
[ i
] = i
+ 1;
1079 rotate( digits
, 9, 1 + rb
->rand( ) % 8 );
1080 shuffle( digits
, 9 );
1083 rotate( tmplt
, len_tmplt
, 1 + rb
->rand( ) % ( len_tmplt
- 1 ) );
1084 shuffle( tmplt
, len_tmplt
);
1086 reset( ); /* construct a new board */
1088 for( i
= 0 ; i
< len_tmplt
; ++i
)
1089 fill( tmplt
[ i
], digits
[ i
% 9 ] );
1091 /* Allow the user to abort generation by pressing any button */
1092 if (check_buttons())
1097 if( 0 != solve( ) || idx_history
< 81 )
1100 /* Allow the user to abort generation by pressing any button */
1101 if (check_buttons())
1106 for( i
= 0 ; i
< len_tmplt
; ++i
)
1107 board
[ tmplt
[ i
] ] |= FIXED
;
1109 /* Construct fixed squares */
1110 for( idx_history
= i
= 0 ; i
< 81 ; ++i
)
1112 history
[ idx_history
++ ] = SET_INDEX( i
)
1113 | SET_DIGIT( DIGIT( i
) )
1117 if( 0 != solve( ) || idx_history
< 81 )
1119 if( -1 != backtrack( ) && 0 == solve( ) )
1127 bool sudoku_generate_board(struct sudoku_state_t
* state
, char** difficulty
)
1131 rb
->srand(*rb
->current_tick
);
1133 rb
->button_clear_queue();
1136 /* User has aborted with a button press */
1144 state
->startboard
[r
][c
]='0';
1146 state
->startboard
[r
][c
]='0'+GET_DIGIT( board
[ i
] );
1148 state
->currentboard
[r
][c
]=state
->startboard
[r
][c
];
1153 *difficulty
= classify( );
1157 bool sudoku_solve_board(struct sudoku_state_t
* state
)
1166 if( state
->startboard
[r
][c
]!='0' )
1168 fill( i
, state
->startboard
[r
][c
] - '0' );
1174 ret
= ( 0 == solve( ) && 81 == idx_history
);
1180 state
->currentboard
[r
][c
]='0'+GET_DIGIT( board
[ i
] );