Update the discussion of themeing in the manual, and put a note in the wps tags appen...
[kugel-rb.git] / apps / plugins / sudoku / generator.c
blobba74fa5b08ff659af02f3553a35355887975d858
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 #define assert(x)
40 /* Common state encoding in a 32-bit integer:
41 * bits 0-6 index
42 * 7-15 state [bit high signals digits not possible]
43 * 16-19 digit
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()]
47 * 23 unused
48 * 24-26 hint
49 * 27-31 unused
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))
90 /* Board state */
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
105 * lost.
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 */
129 static
130 void
131 reset( void )
133 rb->memset( board, 0x00, sizeof( board ) );
134 rb->memset( history, 0x00, sizeof( history ) );
135 idx_history = 0;
136 pass = 0;
139 /* Management of the move history - compression */
140 static
141 void
142 compress( int limit )
144 int i, j;
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 ];
150 idx_history = j;
153 /* Management of the move history - adding a move */
154 static
155 void
156 add_move( int idx, int digit, int choice )
158 int i;
160 if( sizeof( history ) / sizeof( int ) == idx_history )
161 compress( 81 );
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;
171 break;
175 /* Iteration over rows/columns/blocks handled by specialised code.
176 * Each function returns a block index - call must manage element/idx.
178 static
180 idx_row( int el, int idx ) /* Index within a row */
182 return INDEX( el, idx );
185 static
187 idx_column( int el, int idx ) /* Index within a column */
189 return INDEX( idx, el );
192 static
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)
201 static
202 void
203 update( int idx )
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 ) );
209 int i;
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.
226 static
228 reapply( void )
230 int digit, idx, j;
231 int allok = 0;
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 ) )
239 allok = -1;
240 board[ idx ] = SET_DIGIT( digit );
241 if( history[ j ] & FIXED )
242 board[ idx ] |= FIXED;
243 update( idx );
245 return allok;
248 /* Clear moves, leaving fixed squares
250 static
251 void
252 clear_moves( void )
254 for( idx_history = 0 ; history[ idx_history ] & FIXED ; ++idx_history )
256 reapply( );
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) */
263 static
265 numset( int mask )
267 int i, n = 0;
268 for( i = STATE_SHIFT + 1 ; i <= STATE_SHIFT + 9 ; ++i )
269 if( mask & BIT_N(i) )
270 ++n;
271 else
272 ++counts[ i - STATE_SHIFT - 1 ];
273 return n;
276 static
277 void
278 count_set_digits( int el, int (*idx_fn)( int, int ) )
280 int i;
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)
289 static
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 ) )
299 return -1;
301 board[ idx ] = SET_DIGIT( digit );
302 update( idx );
303 add_move( idx, digit, 0 );
305 return 0;
308 /* Find all squares with a single digit allowed -- do not mutate board */
309 static
310 void
311 singles( int el, int (*idx_fn)( int, int ), int hintcode )
313 int i, j, idx;
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 )
327 | SET_DIGIT( i + 1 )
328 | hintcode;
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 )
338 | SET_DIGIT( j )
339 | hintcode;
344 /* Given the board state, find all possible 'moves' (i.e. squares with just
345 * a single digit).
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
350 * different hints).
352 static
354 findmoves( void )
356 int i;
358 rb->yield();
360 idx_possible = 0;
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 );
367 return idx_possible;
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.
390 static
391 void
392 pairs( int el, int (*idx_fn)( int, int ) )
394 int i, j, k, mask, idx;
396 rb->yield();
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 */
419 static
420 void
421 exmask( int mask, int block, int el, int (*idx_fn)( int, int ) )
423 int i, idx;
425 rb->yield();
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() */
436 static
437 void
438 exblock( int block, int el, int (*idx_fn)( int, int ) )
440 int i, idx, mask;
442 rb->yield();
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
447 * block.
449 mask = 0;
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 );
459 static
460 void
461 block( int el )
463 int i, idx = 0, row, col;
465 rb->yield();
467 /* Find first unknown square */
468 for( i = 0 ; i < 9 && !IS_EMPTY( idx = idx_block( el, i ) ) ; ++i )
470 if( i < 9 )
472 assert( IS_EMPTY( idx ) );
473 row = ROW( idx );
474 col = COLUMN( idx );
475 for( ++i ; i < 9 ; ++i )
477 idx = idx_block( el, i );
478 if( IS_EMPTY( idx ) )
480 if( ROW( idx ) != row )
481 row = -1;
482 if( COLUMN( idx ) != col )
483 col = -1;
486 if( 0 <= row )
487 exblock( el, row, idx_row );
488 if( 0 <= col )
489 exblock( el, col, idx_column );
493 static
494 void
495 common( int el )
497 int i, idx, row, col, digit, mask;
499 rb->yield();
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 ) )
511 if( row < 0 )
512 row = ROW( idx );
513 else
514 if( row != ROW( idx ) )
515 row = 9; /* Digit appears in multiple rows */
516 if( col < 0 )
517 col = COLUMN( idx );
518 else
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 ];
533 static
534 void
535 position2( int el )
537 int digit, digit2, i, mask, mask2, posn, count, idx;
539 rb->yield();
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 ) ] ) )
549 ++count;
550 posn |= DIGIT_STATE( i );
552 if( 2 == count )
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 ] )
561 mask = STATE_MASK
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;
574 break;
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.
584 static
586 allmoves( void )
588 int i, n;
590 rb->yield();
592 n = findmoves( );
593 if( 0 < n )
594 return n;
596 for( i = 0 ; i < 9 ; ++i )
598 count_set_digits( i, idx_row );
599 pairs( 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 );
607 n = findmoves( );
608 if( 0 < n )
609 return n;
611 for( i = 0 ; i < 9 ; ++i )
613 block( i );
614 common( i );
615 position2( i );
617 return findmoves( );
620 /* Helper: sort based on index */
621 static
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
630 * cryptic moves.
633 findhints( void )
635 int i, n, mutated = 0;
637 rb->yield();
639 n = findmoves( );
640 if( n < 2 )
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 );
648 pairs( 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 );
656 mutated = 1;
657 n = findmoves( );
659 if( n < 2 )
661 for( i = 0 ; i < 9 ; ++i )
663 block( i );
664 common( i );
666 mutated = 1;
667 n = findmoves( );
670 /* Sort the possible moves, and allow just one hint per square */
671 if( 0 < n )
673 int i, j;
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 ];
686 else
687 i = j;
689 n = i + 1;
692 /* Undo any mutations of the board state */
693 if( mutated )
694 reapply( );
696 return n;
699 /* Deterministic solver; return 0 on success, else -1 on error.
701 static
703 deterministic( void )
705 int i, n;
707 rb->yield();
709 n = allmoves( );
710 while( 0 < n )
712 ++pass;
713 for( i = 0 ; i < n ; ++i )
714 if( -1 == fill( GET_INDEX( possible[ i ] ),
715 GET_DIGIT( possible[ i ] ) ) )
716 return -1;
717 n = allmoves( );
719 return 0;
722 /* Return index of square for choice.
724 * If no choice is possible (i.e. board solved or inconsistent),
725 * return -1.
727 * The current implementation finds a square with the minimum
728 * number of unknown digits (i.e. maximum # masked digits).
730 static
732 cmp( const void * e1, const void * e2 )
734 return GET_DIGIT( *(const int *)e2 ) - GET_DIGIT( *(const int *)e1 );
737 static
739 choice( void )
741 int i, n;
743 rb->yield();
745 for( n = i = 0 ; i < 81 ; ++i )
746 if( IS_EMPTY( 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 ] ) )
752 return -2;
753 ++n;
756 if( 0 == 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.
767 static
769 choose( int idx, int digit )
771 rb->yield();
773 for( ; digit <= 9 ; ++digit )
774 if( !DISALLOWED( idx, digit ) )
776 board[ idx ] = SET_DIGIT( digit );
777 update( idx );
778 add_move( idx, digit, CHOICE );
779 return digit;
782 return -1;
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.
791 static
793 backtrack( void )
795 int digit, idx;
797 rb->yield();
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;
805 reapply( );
806 if( -1 != choose( idx, digit ) )
807 return idx;
810 return -1;
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.
819 static
821 solve( void )
823 int idx;
825 rb->yield();
827 while( 1 )
829 if( 0 == deterministic( ) )
831 /* Solved, make a new choice, or rewind a previous choice */
832 idx = choice( );
833 if( -1 == idx )
834 return 0;
835 else
836 if( ( idx < 0 || -1 == choose( idx, 1 ) ) && -1 == backtrack( ) )
837 return -1;
839 else /* rewind to a previous choice */
840 if( -1 == backtrack( ) )
841 return -1;
843 return -1;
846 static
848 init_template( int template )
850 int i, row, col;
851 int mask;
853 reset( );
854 len_tmplt = 0;
856 /* Consume grid - allow leading spaces and comments at end */
857 for( row = 0 ; row < 9 ; ++row )
859 mask=0x100;
860 for( col = 0 ; col < 9 ; ++col )
862 if (templates[template][row] & mask)
863 tmplt[ len_tmplt++ ] = INDEX( row, col );
864 mask /= 2;
868 /* Construct move history for a template */
869 idx_history = 0;
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;
878 return 0;
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
890 * to be counted.
892 * Return 0 on error, else a string classification.
895 static
896 char *
897 classify( void )
899 int i, score;
901 rb->yield();
903 pass = 0;
904 clear_moves( );
905 if( -1 == solve( ) )
906 return 0;
908 score = 81;
909 for( i = 0 ; i < 81 ; ++i )
910 if( IS_FIXED( i ) )
911 --score;
913 assert( 81 == idx_history );
915 for( i = 0 ; i < 81 ; ++i )
916 if( history[ i ] & CHOICE )
917 score -= 5;
919 if( 15 * pass < score )
920 return "very easy";
921 else
922 if( 11 * pass < score )
923 return "easy";
924 else
925 if( 7 * pass < score )
926 return "medium";
927 else
928 if( 4 * pass < score )
929 return "hard";
930 else
931 return "fiendish";
934 /* exchange disjoint, identical length blocks of data */
935 static
936 void
937 exchange( int * a, int * b, int len )
939 int i, tmp;
940 for( i = 0 ; i < len ; ++i )
942 tmp = a[ i ];
943 a[ i ] = b[ i ];
944 b[ i ] = tmp;
948 /* rotate left */
949 static
950 void
951 rotate1_left( int * a, int len )
953 int i, tmp;
954 tmp = a[ 0 ];
955 for( i = 1 ; i < len ; ++i )
956 a[ i - 1 ] = a[ i ];
957 a[ len - 1 ] = tmp;
960 /* rotate right */
961 static
962 void
963 rotate1_right( int * a, int len )
965 int i, tmp;
966 tmp = a[ len - 1 ];
967 for( i = len - 1 ; 0 < i ; --i )
968 a[ i ] = a[ i - 1 ];
969 a[ 0 ] = tmp;
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
980 static
981 void
982 rotate( int * a, int len, int idx )
984 int xdi = len - idx;
985 int delta = idx - xdi;
987 while( 0 != delta && 0 != idx )
989 if( delta < 0 )
991 if( 1 == idx )
993 rotate1_left( a, len );
994 idx = 0;
996 else
998 exchange( a, a + xdi, idx );
999 len = xdi;
1002 else /* 0 < delta */
1004 if( 1 == xdi )
1006 rotate1_right( a, len );
1007 idx = 0;
1009 else
1011 exchange( a, a + idx, xdi );
1012 a += xdi;
1013 len = idx;
1014 idx -= xdi;
1017 xdi = len - idx;
1018 delta = idx - xdi;
1020 if( 0 < idx )
1021 exchange( a, a + idx, idx );
1024 /* Shuffle an array of integers */
1025 static
1026 void
1027 shuffle( int * a, int len )
1029 int i, j, tmp;
1031 i = len;
1032 while( 1 <= i )
1034 j = rb->rand( ) % i;
1035 tmp = a[ --i ];
1036 a[ i ] = a[ j ];
1037 a[ j ] = tmp;
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 */
1049 static
1050 void
1051 select_template( void )
1053 int i = rb->rand( ) % NUM_TEMPLATES;
1054 init_template( i );
1057 static bool check_buttons(void)
1059 int button = rb->button_get(false);
1060 return (button && (!(button & BUTTON_REL)) && (!(button & BUTTON_REPEAT)));
1063 static
1064 bool
1065 generate( void )
1067 static int digits[ 9 ];
1069 int i;
1071 start:
1072 /* Allow the user to abort generation by pressing any button */
1073 if (check_buttons())
1074 return false;
1076 for( i = 0 ; i < 9 ; ++i )
1077 digits[ i ] = i + 1;
1079 rotate( digits, 9, 1 + rb->rand( ) % 8 );
1080 shuffle( digits, 9 );
1081 select_template( );
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())
1093 return false;
1095 rb->yield();
1097 if( 0 != solve( ) || idx_history < 81 )
1098 goto start;
1100 /* Allow the user to abort generation by pressing any button */
1101 if (check_buttons())
1102 return false;
1104 rb->yield();
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 )
1111 if( IS_FIXED( i ) )
1112 history[ idx_history++ ] = SET_INDEX( i )
1113 | SET_DIGIT( DIGIT( i ) )
1114 | FIXED;
1115 clear_moves( );
1117 if( 0 != solve( ) || idx_history < 81 )
1118 goto start;
1119 if( -1 != backtrack( ) && 0 == solve( ) )
1120 goto start;
1122 clear_moves( );
1124 return true;
1127 bool sudoku_generate_board(struct sudoku_state_t* state, char** difficulty)
1129 int r,c,i;
1131 rb->srand(*rb->current_tick);
1133 rb->button_clear_queue();
1135 if (!generate()) {
1136 /* User has aborted with a button press */
1137 return false;
1140 i=0;
1141 for (r=0;r<9;r++) {
1142 for (c=0;c<9;c++) {
1143 if( IS_EMPTY( i ) )
1144 state->startboard[r][c]='0';
1145 else
1146 state->startboard[r][c]='0'+GET_DIGIT( board[ i ] );
1148 state->currentboard[r][c]=state->startboard[r][c];
1149 i++;
1153 *difficulty = classify( );
1154 return true;
1157 bool sudoku_solve_board(struct sudoku_state_t* state)
1159 bool ret;
1160 int r,c,i;
1162 reset( );
1163 i=0;
1164 for (r=0;r<9;r++) {
1165 for (c=0;c<9;c++) {
1166 if( state->startboard[r][c]!='0' )
1168 fill( i, state->startboard[r][c] - '0' );
1170 i++;
1174 ret = ( 0 == solve( ) && 81 == idx_history );
1176 if (ret) {
1177 i=0;
1178 for (r=0;r<9;r++) {
1179 for (c=0;c<9;c++) {
1180 state->currentboard[r][c]='0'+GET_DIGIT( board[ i ] );
1181 i++;
1185 return ret;