very minor code police. also fix a possible but unlikely missed cpu_boost(false)
[Rockbox.git] / apps / plugins / sudoku / generator.c
blob56dce48cc2826ca0530b68cd1f829c55f2519c31
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.
33 #include "plugin.h"
35 #include "sudoku.h"
36 #include "templates.h"
38 extern const struct plugin_api* rb;
40 #define assert(x)
42 /* Common state encoding in a 32-bit integer:
43 * bits 0-6 index
44 * 7-15 state [bit high signals digits not possible]
45 * 16-19 digit
46 * 20 fixed [set if digit initially fixed]
47 * 21 choice [set if solver chose this digit]
48 * 22 ignore [set if ignored by reapply()]
49 * 23 unused
50 * 24-26 hint
51 * 27-31 unused
53 #define INDEX_MASK 0x0000007f
54 #define GET_INDEX(val) (INDEX_MASK&(val))
55 #define SET_INDEX(val) (val)
57 #define STATE_MASK 0x0000ff80
58 #define STATE_SHIFT (7-1) /* digits 1..9 */
59 #define DIGIT_STATE(digit) (1<<(STATE_SHIFT+(digit)))
61 #define DIGIT_MASK 0x000f0000
62 #define DIGIT_SHIFT 16
63 #define GET_DIGIT(val) (((val)&DIGIT_MASK)>>(DIGIT_SHIFT))
64 #define SET_DIGIT(val) ((val)<<(DIGIT_SHIFT))
66 #define FIXED 0x00100000
67 #define CHOICE 0x00200000
68 #define IGNORED 0x00400000
70 /* Hint codes (c.f. singles(), pairs(), findmoves()) */
71 #define HINT_ROW 0x01000000
72 #define HINT_COLUMN 0x02000000
73 #define HINT_BLOCK 0x04000000
75 /* For a general board it may be necessary to do backtracking (i.e. to
76 * rewind the board to an earlier state), and make choices during the
77 * solution process. This can be implemented naturally using recursion,
78 * but it is more efficient to maintain a single board.
80 static int board[ 81 ];
82 /* Addressing board elements: linear array 0..80 */
83 #define ROW(idx) ((idx)/9)
84 #define COLUMN(idx) ((idx)%9)
85 #define BLOCK(idx) (3*(ROW(idx)/3)+(COLUMN(idx)/3))
86 #define INDEX(row,col) (9*(row)+(col))
88 /* Blocks indexed 0..9 */
89 #define IDX_BLOCK(row,col) (3*((row)/3)+((col)/3))
90 #define TOP_LEFT(block) (INDEX(block/3,block%3))
92 /* Board state */
93 #define STATE(idx) ((board[idx])&STATE_MASK)
94 #define DIGIT(idx) (GET_DIGIT(board[idx]))
95 #define HINT(idx) ((board[idx])&HINT_MASK)
96 #define IS_EMPTY(idx) (0 == DIGIT(idx))
97 #define DISALLOWED(idx,digit) ((board[idx])&DIGIT_STATE(digit))
98 #define IS_FIXED(idx) (board[idx]&FIXED)
100 /* Record move history, and maintain a counter for the current
101 * move number. Concessions are made for the user interface, and
102 * allow digit 0 to indicate clearing a square. The move history
103 * is used to support 'undo's for the user interface, and hence
104 * is larger than required - there is sufficient space to solve
105 * the puzzle, undo every move, and then redo the puzzle - and
106 * if the user requires more space, then the full history will be
107 * lost.
109 static int idx_history;
110 static int history[ 3 * 81 ];
112 /* Possible moves for a given board (c.f. fillmoves()).
113 * Also used by choice() when the deterministic solver has failed,
114 * and for calculating user hints. The number of hints is stored
115 * in num_hints, or -1 if no hints calculated. The number of hints
116 * requested by the user since their last move is stored in req_hints;
117 * if the user keeps requesting hints, start giving more information.
118 * Finally, record the last hint issued to the user; attempt to give
119 * different hints each time.
121 static int idx_possible;
122 static int possible[ 81 ];
124 static int pass; /* count # passes of deterministic solver */
126 /* Support for template file */
127 static int tmplt[ 81 ]; /* Template indices */
128 static int len_tmplt; /* Number of template indices */
130 /* Reset global state */
131 static
132 void
133 reset( void )
135 rb->memset( board, 0x00, sizeof( board ) );
136 rb->memset( history, 0x00, sizeof( history ) );
137 idx_history = 0;
138 pass = 0;
141 /* Management of the move history - compression */
142 static
143 void
144 compress( int limit )
146 int i, j;
147 for( i = j = 0 ; i < idx_history && j < limit ; ++i )
148 if( !( history[ i ] & IGNORED ) )
149 history[ j++ ] = history[ i ];
150 for( ; i < idx_history ; ++i )
151 history[ j++ ] = history[ i ];
152 idx_history = j;
155 /* Management of the move history - adding a move */
156 static
157 void
158 add_move( int idx, int digit, int choice )
160 int i;
162 if( sizeof( history ) / sizeof( int ) == idx_history )
163 compress( 81 );
165 /* Never ignore the last move */
166 history[ idx_history++ ] = SET_INDEX( idx ) | SET_DIGIT( digit ) | choice;
168 /* Ignore all previous references to idx */
169 for( i = idx_history - 2 ; 0 <= i ; --i )
170 if( GET_INDEX( history[ i ] ) == idx )
172 history[ i ] |= IGNORED;
173 break;
177 /* Iteration over rows/columns/blocks handled by specialised code.
178 * Each function returns a block index - call must manage element/idx.
180 static
182 idx_row( int el, int idx ) /* Index within a row */
184 return INDEX( el, idx );
187 static
189 idx_column( int el, int idx ) /* Index within a column */
191 return INDEX( idx, el );
194 static
196 idx_block( int el, int idx ) /* Index within a block */
198 return INDEX( 3 * ( el / 3 ) + idx / 3, 3 * ( el % 3 ) + idx % 3 );
201 /* Update board state after setting a digit (clearing not handled)
203 static
204 void
205 update( int idx )
207 const int row = ROW( idx );
208 const int col = COLUMN( idx );
209 const int block = IDX_BLOCK( row, col );
210 const int mask = DIGIT_STATE( DIGIT( idx ) );
211 int i;
213 board[ idx ] |= STATE_MASK; /* filled - no choice possible */
215 /* Digit cannot appear in row, column or block */
216 for( i = 0 ; i < 9 ; ++i )
218 board[ idx_row( row, i ) ] |= mask;
219 board[ idx_column( col, i ) ] |= mask;
220 board[ idx_block( block, i ) ] |= mask;
224 /* Refresh board state, given move history. Note that this can yield
225 * an incorrect state if the user has made errors - return -1 if an
226 * incorrect state is generated; else return 0 for a correct state.
228 static
230 reapply( void )
232 int digit, idx, j;
233 int allok = 0;
234 rb->memset( board, 0x00, sizeof( board ) );
235 for( j = 0 ; j < idx_history ; ++j )
236 if( !( history[ j ] & IGNORED ) && 0 != GET_DIGIT( history[ j ] ) )
238 idx = GET_INDEX( history[ j ] );
239 digit = GET_DIGIT( history[ j ] );
240 if( !IS_EMPTY( idx ) || DISALLOWED( idx, digit ) )
241 allok = -1;
242 board[ idx ] = SET_DIGIT( digit );
243 if( history[ j ] & FIXED )
244 board[ idx ] |= FIXED;
245 update( idx );
247 return allok;
250 /* Clear moves, leaving fixed squares
252 static
253 void
254 clear_moves( void )
256 for( idx_history = 0 ; history[ idx_history ] & FIXED ; ++idx_history )
258 reapply( );
261 static int digits[ 9 ]; /* # digits expressed in element square */
262 static int counts[ 9 ]; /* Count of digits (c.f. count_set_digits()) */
264 /* Count # set bits (within STATE_MASK) */
265 static
267 numset( int mask )
269 int i, n = 0;
270 for( i = STATE_SHIFT + 1 ; i <= STATE_SHIFT + 9 ; ++i )
271 if( mask & (1<<i) )
272 ++n;
273 else
274 ++counts[ i - STATE_SHIFT - 1 ];
275 return n;
278 static
279 void
280 count_set_digits( int el, int (*idx_fn)( int, int ) )
282 int i;
283 rb->memset( counts, 0x00, sizeof( counts ) );
284 for( i = 0 ; i < 9 ; ++i )
285 digits[ i ] = numset( board[ (*idx_fn)( el, i ) ] );
288 /* Fill square with given digit, and update state.
289 * Returns 0 on success, else -1 on error (i.e. invalid fill)
291 static
293 fill( int idx, int digit )
295 assert( 0 != digit );
297 if( !IS_EMPTY( idx ) )
298 return ( DIGIT( idx ) == digit ) ? 0 : -1;
300 if( DISALLOWED( idx, digit ) )
301 return -1;
303 board[ idx ] = SET_DIGIT( digit );
304 update( idx );
305 add_move( idx, digit, 0 );
307 return 0;
310 /* Find all squares with a single digit allowed -- do not mutate board */
311 static
312 void
313 singles( int el, int (*idx_fn)( int, int ), int hintcode )
315 int i, j, idx;
317 count_set_digits( el, idx_fn );
319 for( i = 0 ; i < 9 ; ++i )
321 if( 1 == counts[ i ] )
323 /* Digit 'i+1' appears just once in the element */
324 for( j = 0 ; j < 9 ; ++j )
326 idx = (*idx_fn)( el, j );
327 if( !DISALLOWED( idx, i + 1 ) && idx_possible < 81 )
328 possible[ idx_possible++ ] = SET_INDEX( idx )
329 | SET_DIGIT( i + 1 )
330 | hintcode;
333 if( 8 == digits[ i ] )
335 /* 8 digits are masked at this position - just one remaining */
336 idx = (*idx_fn)( el, i );
337 for( j = 1 ; j <= 9 ; ++j )
338 if( 0 == ( STATE( idx ) & DIGIT_STATE( j ) ) && idx_possible < 81 )
339 possible[ idx_possible++ ] = SET_INDEX( idx )
340 | SET_DIGIT( j )
341 | hintcode;
346 /* Given the board state, find all possible 'moves' (i.e. squares with just
347 * a single digit).
349 * Returns the number of (deterministic) moves (and fills the moves array),
350 * or 0 if no moves are possible. This function does not mutate the board
351 * state, and hence, can return the same move multiple times (with
352 * different hints).
354 static
356 findmoves( void )
358 int i;
360 rb->yield();
362 idx_possible = 0;
363 for( i = 0 ; i < 9 ; ++i )
365 singles( i, idx_row, HINT_ROW );
366 singles( i, idx_column, HINT_COLUMN );
367 singles( i, idx_block, HINT_BLOCK );
369 return idx_possible;
372 /* Strategies for refining the board state
373 * - 'pairs' if there are two unfilled squares in a given row/column/
374 * block with the same state, and just two possibilities,
375 * then all other unfilled squares in the row/column/block
376 * CANNOT be either of these digits.
377 * - 'block' if the unknown squares in a block all appear in the same
378 * row or column, then all unknown squares outside the block
379 * and in the same row/column cannot be any of the unknown
380 * squares in the block.
381 * - 'common' if all possible locations for a digit in a block appear
382 * in a row or column, then that digit cannot appear outside
383 * the block in the same row or column.
384 * - 'position2' if the positions of 2 unknown digits in a block match
385 * identically in precisely 2 positions, then those 2 positions
386 * can only contain the 2 unknown digits.
388 * Recall that each state bit uses a 1 to prevent a digit from
389 * filling that square.
392 static
393 void
394 pairs( int el, int (*idx_fn)( int, int ) )
396 int i, j, k, mask, idx;
398 rb->yield();
400 for( i = 0 ; i < 8 ; ++i )
401 if( 7 == digits[ i ] ) /* 2 digits unknown */
402 for( j = i + 1 ; j < 9 ; ++j )
404 idx = (*idx_fn)( el, i );
405 if( STATE( idx ) == STATE( (*idx_fn)( el, j ) ) )
407 /* Found a row/column pair - mask other entries */
408 mask = STATE_MASK ^ (STATE_MASK & board[ idx ] );
409 for( k = 0 ; k < i ; ++k )
410 board[ (*idx_fn)( el, k ) ] |= mask;
411 for( k = i + 1 ; k < j ; ++k )
412 board[ (*idx_fn)( el, k ) ] |= mask;
413 for( k = j + 1 ; k < 9 ; ++k )
414 board[ (*idx_fn)( el, k ) ] |= mask;
415 digits[ j ] = -1; /* now processed */
420 /* Worker: mask elements outside block */
421 static
422 void
423 exmask( int mask, int block, int el, int (*idx_fn)( int, int ) )
425 int i, idx;
427 rb->yield();
429 for( i = 0 ; i < 9 ; ++i )
431 idx = (*idx_fn)( el, i );
432 if( block != BLOCK( idx ) && IS_EMPTY( idx ) )
433 board[ idx ] |= mask;
437 /* Worker for block() */
438 static
439 void
440 exblock( int block, int el, int (*idx_fn)( int, int ) )
442 int i, idx, mask;
444 rb->yield();
446 /* By assumption, all unknown squares in the block appear in the
447 * same row/column, so to construct a mask for these squares, it
448 * is sufficient to invert the mask for the known squares in the
449 * block.
451 mask = 0;
452 for( i = 0 ; i < 9 ; ++i )
454 idx = idx_block( block, i );
455 if( !IS_EMPTY( idx ) )
456 mask |= DIGIT_STATE( DIGIT( idx ) );
458 exmask( mask ^ STATE_MASK, block, el, idx_fn );
461 static
462 void
463 block( int el )
465 int i, idx = 0, row, col;
467 rb->yield();
469 /* Find first unknown square */
470 for( i = 0 ; i < 9 && !IS_EMPTY( idx = idx_block( el, i ) ) ; ++i )
472 if( i < 9 )
474 assert( IS_EMPTY( idx ) );
475 row = ROW( idx );
476 col = COLUMN( idx );
477 for( ++i ; i < 9 ; ++i )
479 idx = idx_block( el, i );
480 if( IS_EMPTY( idx ) )
482 if( ROW( idx ) != row )
483 row = -1;
484 if( COLUMN( idx ) != col )
485 col = -1;
488 if( 0 <= row )
489 exblock( el, row, idx_row );
490 if( 0 <= col )
491 exblock( el, col, idx_column );
495 static
496 void
497 common( int el )
499 int i, idx, row, col, digit, mask;
501 rb->yield();
503 for( digit = 1 ; digit <= 9 ; ++digit )
505 mask = DIGIT_STATE( digit );
506 row = col = -1; /* Value '9' indicates invalid */
507 for( i = 0 ; i < 9 ; ++i )
509 /* Digit possible? */
510 idx = idx_block( el, i );
511 if( IS_EMPTY( idx ) && 0 == ( board[ idx ] & mask ) )
513 if( row < 0 )
514 row = ROW( idx );
515 else
516 if( row != ROW( idx ) )
517 row = 9; /* Digit appears in multiple rows */
518 if( col < 0 )
519 col = COLUMN( idx );
520 else
521 if( col != COLUMN( idx ) )
522 col = 9; /* Digit appears in multiple columns */
525 if( -1 != row && row < 9 )
526 exmask( mask, el, row, idx_row );
527 if( -1 != col && col < 9 )
528 exmask( mask, el, col, idx_column );
532 /* Encoding of positions of a digit (c.f. position2()) - abuse DIGIT_STATE */
533 static int posn_digit[ 10 ];
535 static
536 void
537 position2( int el )
539 int digit, digit2, i, mask, mask2, posn, count, idx;
541 rb->yield();
543 /* Calculate positions of each digit within block */
544 for( digit = 1 ; digit <= 9 ; ++digit )
546 mask = DIGIT_STATE( digit );
547 posn_digit[ digit ] = count = posn = 0;
548 for( i = 0 ; i < 9 ; ++i )
549 if( 0 == ( mask & board[ idx_block( el, i ) ] ) )
551 ++count;
552 posn |= DIGIT_STATE( i );
554 if( 2 == count )
555 posn_digit[ digit ] = posn;
557 /* Find pairs of matching positions, and mask */
558 for( digit = 1 ; digit < 9 ; ++digit )
559 if( 0 != posn_digit[ digit ] )
560 for( digit2 = digit + 1 ; digit2 <= 9 ; ++digit2 )
561 if( posn_digit[ digit ] == posn_digit[ digit2 ] )
563 mask = STATE_MASK
564 ^ ( DIGIT_STATE( digit ) | DIGIT_STATE( digit2 ) );
565 mask2 = DIGIT_STATE( digit );
566 for( i = 0 ; i < 9 ; ++i )
568 idx = idx_block( el, i );
569 if( 0 == ( mask2 & board[ idx ] ) )
571 assert( 0 == (DIGIT_STATE(digit2) & board[idx]) );
572 board[ idx ] |= mask;
575 posn_digit[ digit ] = posn_digit[ digit2 ] = 0;
576 break;
580 /* Find some moves for the board; starts with a simple approach (finding
581 * singles), and if no moves found, starts using more involved strategies
582 * until a move is found. The more advanced strategies can mask states
583 * in the board, making this an efficient mechanism, but difficult for
584 * a human to understand.
586 static
588 allmoves( void )
590 int i, n;
592 rb->yield();
594 n = findmoves( );
595 if( 0 < n )
596 return n;
598 for( i = 0 ; i < 9 ; ++i )
600 count_set_digits( i, idx_row );
601 pairs( i, idx_row );
603 count_set_digits( i, idx_column );
604 pairs( i, idx_column );
606 count_set_digits( i, idx_block );
607 pairs( i, idx_block );
609 n = findmoves( );
610 if( 0 < n )
611 return n;
613 for( i = 0 ; i < 9 ; ++i )
615 block( i );
616 common( i );
617 position2( i );
619 return findmoves( );
622 /* Helper: sort based on index */
623 static
625 cmpindex( const void * a, const void * b )
627 return GET_INDEX( *((const int *)b) ) - GET_INDEX( *((const int *)a) );
630 /* Return number of hints. The hints mechanism should attempt to find
631 * 'easy' moves first, and if none are possible, then try for more
632 * cryptic moves.
635 findhints( void )
637 int i, n, mutated = 0;
639 rb->yield();
641 n = findmoves( );
642 if( n < 2 )
644 /* Each call to pairs() can mutate the board state, making the
645 * hints very, very cryptic... so later undo the mutations.
647 for( i = 0 ; i < 9 ; ++i )
649 count_set_digits( i, idx_row );
650 pairs( i, idx_row );
652 count_set_digits( i, idx_column );
653 pairs( i, idx_column );
655 count_set_digits( i, idx_block );
656 pairs( i, idx_block );
658 mutated = 1;
659 n = findmoves( );
661 if( n < 2 )
663 for( i = 0 ; i < 9 ; ++i )
665 block( i );
666 common( i );
668 mutated = 1;
669 n = findmoves( );
672 /* Sort the possible moves, and allow just one hint per square */
673 if( 0 < n )
675 int i, j;
677 rb->qsort( possible, n, sizeof( int ), cmpindex );
678 for( i = 0, j = 1 ; j < n ; ++j )
680 if( GET_INDEX( possible[ i ] ) == GET_INDEX( possible[ j ] ) )
682 /* Let the user make mistakes - do not assume the
683 * board is in a consistent state.
685 if( GET_DIGIT( possible[i] ) == GET_DIGIT( possible[j] ) )
686 possible[ i ] |= possible[ j ];
688 else
689 i = j;
691 n = i + 1;
694 /* Undo any mutations of the board state */
695 if( mutated )
696 reapply( );
698 return n;
701 /* Deterministic solver; return 0 on success, else -1 on error.
703 static
705 deterministic( void )
707 int i, n;
709 rb->yield();
711 n = allmoves( );
712 while( 0 < n )
714 ++pass;
715 for( i = 0 ; i < n ; ++i )
716 if( -1 == fill( GET_INDEX( possible[ i ] ),
717 GET_DIGIT( possible[ i ] ) ) )
718 return -1;
719 n = allmoves( );
721 return 0;
724 /* Return index of square for choice.
726 * If no choice is possible (i.e. board solved or inconsistent),
727 * return -1.
729 * The current implementation finds a square with the minimum
730 * number of unknown digits (i.e. maximum # masked digits).
732 static
734 cmp( const void * e1, const void * e2 )
736 return GET_DIGIT( *(const int *)e2 ) - GET_DIGIT( *(const int *)e1 );
739 static
741 choice( void )
743 int i, n;
745 rb->yield();
747 for( n = i = 0 ; i < 81 ; ++i )
748 if( IS_EMPTY( i ) )
750 possible[ n ] = SET_INDEX( i ) | SET_DIGIT( numset( board[ i ] ) );
752 /* Inconsistency if square unknown, but nothing possible */
753 if( 9 == GET_DIGIT( possible[ n ] ) )
754 return -2;
755 ++n;
758 if( 0 == n )
759 return -1; /* All squares known */
761 rb->qsort( possible, n, sizeof( possible[ 0 ] ), cmp );
762 return GET_INDEX( possible[ 0 ] );
765 /* Choose a digit for the given square.
766 * The starting digit is passed as a parameter.
767 * Returns -1 if no choice possible.
769 static
771 choose( int idx, int digit )
773 rb->yield();
775 for( ; digit <= 9 ; ++digit )
776 if( !DISALLOWED( idx, digit ) )
778 board[ idx ] = SET_DIGIT( digit );
779 update( idx );
780 add_move( idx, digit, CHOICE );
781 return digit;
784 return -1;
787 /* Backtrack to a previous choice point, and attempt to reseed
788 * the search. Return -1 if no further choice possible, or
789 * the index of the changed square.
791 * Assumes that the move history and board are valid.
793 static
795 backtrack( void )
797 int digit, idx;
799 rb->yield();
801 for( ; 0 <= --idx_history ; )
802 if( history[ idx_history ] & CHOICE )
804 /* Remember the last choice, and advance */
805 idx = GET_INDEX( history[ idx_history ] );
806 digit = GET_DIGIT( history[ idx_history ] ) + 1;
807 reapply( );
808 if( -1 != choose( idx, digit ) )
809 return idx;
812 return -1;
815 /* Attempt to solve 'board'; return 0 on success else -1 on error.
817 * The solution process attempts to fill-in deterministically as
818 * much of the board as possible. Once that is no longer possible,
819 * need to choose a square to fill in.
821 static
823 solve( void )
825 int idx;
827 rb->yield();
829 while( 1 )
831 if( 0 == deterministic( ) )
833 /* Solved, make a new choice, or rewind a previous choice */
834 idx = choice( );
835 if( -1 == idx )
836 return 0;
837 else
838 if( ( idx < 0 || -1 == choose( idx, 1 ) ) && -1 == backtrack( ) )
839 return -1;
841 else /* rewind to a previous choice */
842 if( -1 == backtrack( ) )
843 return -1;
845 return -1;
848 static
850 init_template( int template )
852 int i, row, col;
853 int mask;
855 reset( );
856 len_tmplt = 0;
858 /* Consume grid - allow leading spaces and comments at end */
859 for( row = 0 ; row < 9 ; ++row )
861 mask=0x100;
862 for( col = 0 ; col < 9 ; ++col )
864 if (templates[template][row] & mask)
865 tmplt[ len_tmplt++ ] = INDEX( row, col );
866 mask /= 2;
870 /* Construct move history for a template */
871 idx_history = 0;
872 for( i = 0 ; i < 81 ; ++i )
873 if( 0 != DIGIT( i ) )
874 history[ idx_history++ ] = i | (DIGIT( i )<<8);
876 /* Finally, markup all of these moves as 'fixed' */
877 for( i = 0 ; i < idx_history ; ++i )
878 history[ i ] |= FIXED;
880 return 0;
883 /* Classify a SuDoKu, given its solution.
885 * The classification is based on the average number of possible moves
886 * for each pass of the deterministic solver - it is a rather simplistic
887 * measure, but gives reasonable results. Note also that the classification
888 * is based on the first solution found (but does handle the pathological
889 * case of multiple solutions). Note that the average moves per pass
890 * depends just on the number of squares initially set... this simplifies
891 * the statistics collection immensely, requiring just the number of passes
892 * to be counted.
894 * Return 0 on error, else a string classification.
897 static
898 char *
899 classify( void )
901 int i, score;
903 rb->yield();
905 pass = 0;
906 clear_moves( );
907 if( -1 == solve( ) )
908 return 0;
910 score = 81;
911 for( i = 0 ; i < 81 ; ++i )
912 if( IS_FIXED( i ) )
913 --score;
915 assert( 81 == idx_history );
917 for( i = 0 ; i < 81 ; ++i )
918 if( history[ i ] & CHOICE )
919 score -= 5;
921 if( 15 * pass < score )
922 return "very easy";
923 else
924 if( 11 * pass < score )
925 return "easy";
926 else
927 if( 7 * pass < score )
928 return "medium";
929 else
930 if( 4 * pass < score )
931 return "hard";
932 else
933 return "fiendish";
936 /* exchange disjoint, identical length blocks of data */
937 static
938 void
939 exchange( int * a, int * b, int len )
941 int i, tmp;
942 for( i = 0 ; i < len ; ++i )
944 tmp = a[ i ];
945 a[ i ] = b[ i ];
946 b[ i ] = tmp;
950 /* rotate left */
951 static
952 void
953 rotate1_left( int * a, int len )
955 int i, tmp;
956 tmp = a[ 0 ];
957 for( i = 1 ; i < len ; ++i )
958 a[ i - 1 ] = a[ i ];
959 a[ len - 1 ] = tmp;
962 /* rotate right */
963 static
964 void
965 rotate1_right( int * a, int len )
967 int i, tmp;
968 tmp = a[ len - 1 ];
969 for( i = len - 1 ; 0 < i ; --i )
970 a[ i ] = a[ i - 1 ];
971 a[ 0 ] = tmp;
974 /* Generalised left rotation - there is a naturally recursive
975 * solution that is best implementation using iteration.
976 * Note that it is not necessary to do repeated unit rotations.
978 * This function is analogous to 'cutting' a 'pack of cards'.
980 * On entry: 0 < idx < len
982 static
983 void
984 rotate( int * a, int len, int idx )
986 int xdi = len - idx;
987 int delta = idx - xdi;
989 while( 0 != delta && 0 != idx )
991 if( delta < 0 )
993 if( 1 == idx )
995 rotate1_left( a, len );
996 idx = 0;
998 else
1000 exchange( a, a + xdi, idx );
1001 len = xdi;
1004 else /* 0 < delta */
1006 if( 1 == xdi )
1008 rotate1_right( a, len );
1009 idx = 0;
1011 else
1013 exchange( a, a + idx, xdi );
1014 a += xdi;
1015 len = idx;
1016 idx -= xdi;
1019 xdi = len - idx;
1020 delta = idx - xdi;
1022 if( 0 < idx )
1023 exchange( a, a + idx, idx );
1026 /* Shuffle an array of integers */
1027 static
1028 void
1029 shuffle( int * a, int len )
1031 int i, j, tmp;
1033 i = len;
1034 while( 1 <= i )
1036 j = rb->rand( ) % i;
1037 tmp = a[ --i ];
1038 a[ i ] = a[ j ];
1039 a[ j ] = tmp;
1043 /* Generate a SuDoKu puzzle
1045 * The generation process selects a random template, and then attempts
1046 * to fill in the exposed squares to generate a board. The order of the
1047 * digits and of filling in the exposed squares are random.
1050 /* Select random template; sets tmplt, len_tmplt */
1051 static
1052 void
1053 select_template( void )
1055 int i = rb->rand( ) % NUM_TEMPLATES;
1056 init_template( i );
1059 static bool check_buttons(void)
1061 int button = rb->button_get(false);
1062 return (button && (!(button & BUTTON_REL)) && (!(button & BUTTON_REPEAT)));
1065 static
1066 bool
1067 generate( void )
1069 static int digits[ 9 ];
1071 int i;
1073 start:
1074 /* Allow the user to abort generation by pressing any button */
1075 if (check_buttons())
1076 return false;
1078 for( i = 0 ; i < 9 ; ++i )
1079 digits[ i ] = i + 1;
1081 rotate( digits, 9, 1 + rb->rand( ) % 8 );
1082 shuffle( digits, 9 );
1083 select_template( );
1085 rotate( tmplt, len_tmplt, 1 + rb->rand( ) % ( len_tmplt - 1 ) );
1086 shuffle( tmplt, len_tmplt );
1088 reset( ); /* construct a new board */
1090 for( i = 0 ; i < len_tmplt ; ++i )
1091 fill( tmplt[ i ], digits[ i % 9 ] );
1093 /* Allow the user to abort generation by pressing any button */
1094 if (check_buttons())
1095 return false;
1097 rb->yield();
1099 if( 0 != solve( ) || idx_history < 81 )
1100 goto start;
1102 /* Allow the user to abort generation by pressing any button */
1103 if (check_buttons())
1104 return false;
1106 rb->yield();
1108 for( i = 0 ; i < len_tmplt ; ++i )
1109 board[ tmplt[ i ] ] |= FIXED;
1111 /* Construct fixed squares */
1112 for( idx_history = i = 0 ; i < 81 ; ++i )
1113 if( IS_FIXED( i ) )
1114 history[ idx_history++ ] = SET_INDEX( i )
1115 | SET_DIGIT( DIGIT( i ) )
1116 | FIXED;
1117 clear_moves( );
1119 if( 0 != solve( ) || idx_history < 81 )
1120 goto start;
1121 if( -1 != backtrack( ) && 0 == solve( ) )
1122 goto start;
1124 clear_moves( );
1126 return true;
1129 bool sudoku_generate_board(struct sudoku_state_t* state, char** difficulty)
1131 int r,c,i;
1133 rb->srand(*rb->current_tick);
1135 rb->button_clear_queue();
1137 if (!generate()) {
1138 /* User has aborted with a button press */
1139 return false;
1142 i=0;
1143 for (r=0;r<9;r++) {
1144 for (c=0;c<9;c++) {
1145 if( IS_EMPTY( i ) )
1146 state->startboard[r][c]='0';
1147 else
1148 state->startboard[r][c]='0'+GET_DIGIT( board[ i ] );
1150 state->currentboard[r][c]=state->startboard[r][c];
1151 i++;
1155 *difficulty = classify( );
1156 return true;