sudoku: remove commented out code.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26169 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
0a4eda4d46
commit
93258e4130
1 changed files with 0 additions and 286 deletions
|
@ -286,292 +286,6 @@ static unsigned int cellypos[9]={
|
|||
#define BLOCK 3
|
||||
#define SIZE (BLOCK*BLOCK)
|
||||
|
||||
#if 0
|
||||
/****** Solver routine by Tom Shackell <shackell@cs.york.ac.uk>
|
||||
|
||||
Downloaded from:
|
||||
|
||||
http://www-users.cs.york.ac.uk/~shackell/sudoku/Sudoku.html
|
||||
|
||||
Released under GPLv2
|
||||
|
||||
*/
|
||||
|
||||
typedef unsigned int Bitset;
|
||||
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
typedef struct _Sudoku {
|
||||
Bitset table[SIZE][SIZE];
|
||||
}Sudoku;
|
||||
|
||||
typedef struct _Stats {
|
||||
int numTries;
|
||||
int backTracks;
|
||||
int numEmpty;
|
||||
bool solutionFound;
|
||||
}Stats;
|
||||
|
||||
typedef struct _Options {
|
||||
bool allSolutions;
|
||||
bool uniquenessCheck;
|
||||
}Options;
|
||||
|
||||
void sudoku_init(Sudoku* sud);
|
||||
void sudoku_set(Sudoku* sud, int x, int y, int num, bool original);
|
||||
int sudoku_get(Sudoku* sud, int x, int y, bool* original);
|
||||
|
||||
#define BIT(n) ((Bitset)BIT_N(n))
|
||||
#define BIT_TEST(v,n) ((((Bitset)v) & BIT(n)) != 0)
|
||||
#define BIT_CLEAR(v,n) (v) &= ~BIT(n)
|
||||
#define MARK_BIT BIT(0)
|
||||
#define ORIGINAL_BIT BIT(SIZE+1)
|
||||
|
||||
#define ALL_BITS (BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(9))
|
||||
|
||||
/* initialize a sudoku problem, should be called before using set or get */
|
||||
void sudoku_init(Sudoku* sud)
|
||||
{
|
||||
int y, x;
|
||||
for (y = 0; y < SIZE; y++){
|
||||
for (x = 0; x < SIZE; x++){
|
||||
sud->table[x][y] = ALL_BITS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set the number at a particular x and y column */
|
||||
void sudoku_set(Sudoku* sud, int x, int y, int num, bool original)
|
||||
{
|
||||
int i, j;
|
||||
int bx, by;
|
||||
Bitset orig;
|
||||
|
||||
/* clear the row and columns */
|
||||
for (i = 0; i < SIZE; i++){
|
||||
BIT_CLEAR(sud->table[i][y], num);
|
||||
BIT_CLEAR(sud->table[x][i], num);
|
||||
}
|
||||
/* clear the block */
|
||||
bx = x - (x % BLOCK);
|
||||
by = y - (y % BLOCK);
|
||||
for (i = 0; i < BLOCK; i++){
|
||||
for (j = 0; j < BLOCK; j++){
|
||||
BIT_CLEAR(sud->table[bx+j][by+i], num);
|
||||
}
|
||||
}
|
||||
/* mark the table */
|
||||
orig = original ? ORIGINAL_BIT : 0;
|
||||
sud->table[x][y] = BIT(num) | MARK_BIT | orig;
|
||||
}
|
||||
|
||||
/* get the number at a particular x and y column, if this
|
||||
is not unique return 0 */
|
||||
int sudoku_get(Sudoku* sud, int x, int y, bool* original)
|
||||
{
|
||||
Bitset val = sud->table[x][y];
|
||||
int result = 0;
|
||||
int i;
|
||||
|
||||
if (original) {
|
||||
*original = val & ORIGINAL_BIT;
|
||||
}
|
||||
for (i = 1; i <= SIZE; i++){
|
||||
if (BIT_TEST(val, i)){
|
||||
if (result != 0){
|
||||
return 0;
|
||||
}
|
||||
result = i;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* returns true if this is a valid problem, this is necessary because the input
|
||||
problem might be degenerate which breaks the solver algorithm. */
|
||||
static bool is_valid(const Sudoku* sud)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < SIZE; y++){
|
||||
for (x = 0; x < SIZE; x++){
|
||||
if ((sud->table[x][y] & ALL_BITS) == 0){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* scan the table for the most constrained item, giving all it's options, sets
|
||||
the best x and y coordinates, the number of options and the options for
|
||||
that coordinate and returns true if the puzzle is finished */
|
||||
static bool scan(const Sudoku* sud, int* rX, int* rY, int *num, int* options)
|
||||
{
|
||||
int x, y, i, j;
|
||||
int bestCount = SIZE+1;
|
||||
Bitset val;
|
||||
bool allMarked = true;
|
||||
|
||||
for (y = 0; y < SIZE; y++){
|
||||
for (x = 0; x < SIZE; x++){
|
||||
Bitset val = sud->table[x][y];
|
||||
int i;
|
||||
int count = 0;
|
||||
|
||||
if (val & MARK_BIT) {
|
||||
/* already set */
|
||||
continue;
|
||||
}
|
||||
allMarked = false;
|
||||
for (i = 1; i <= SIZE; i++){
|
||||
if (BIT_TEST(val, i)){
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count < bestCount){
|
||||
bestCount = count;
|
||||
*rX = x;
|
||||
*rY = y;
|
||||
if (count == 0){
|
||||
/* can't possibly be beaten */
|
||||
*num = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* now copy into options */
|
||||
*num = bestCount;
|
||||
val = sud->table[*rX][*rY];
|
||||
for (i = 1, j = 0; i <= SIZE; i++){
|
||||
if (BIT_TEST(val, i)){
|
||||
options[j++] = i;
|
||||
}
|
||||
}
|
||||
return allMarked;
|
||||
}
|
||||
|
||||
static bool solve(Sudoku* sud, Stats* stats, const Options* options);
|
||||
|
||||
/* try a particular option and return true if that gives a solution or false
|
||||
if it doesn't, restores board on backtracking */
|
||||
static bool spawn_option(Sudoku* sud, Stats* stats, const Options* options,
|
||||
int x, int y, int num)
|
||||
{
|
||||
Sudoku copy;
|
||||
|
||||
rb->memcpy(©,sud,sizeof(Sudoku));
|
||||
sudoku_set(©, x, y, num, false);
|
||||
stats->numTries += 1;
|
||||
if (solve(©, stats, options)){
|
||||
if (!options->allSolutions && stats->solutionFound){
|
||||
rb->memcpy(sud,©,sizeof(Sudoku));
|
||||
}
|
||||
return true;
|
||||
}else{
|
||||
stats->backTracks++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* solve a sudoku problem, returns true if there is a solution and false
|
||||
otherwise. stats is used to track statisticss */
|
||||
static bool solve(Sudoku* sud, Stats* stats, const Options* options)
|
||||
{
|
||||
while (true){
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int i, num;
|
||||
int places[SIZE];
|
||||
|
||||
if (scan(sud, &x, &y, &num, places)){
|
||||
/* a solution was found! */
|
||||
if (options->uniquenessCheck && stats->solutionFound){
|
||||
/*printf("\n\t... But the solution is not unique!\n"); */
|
||||
return true;
|
||||
}
|
||||
stats->solutionFound = true;
|
||||
if (options->allSolutions || options->uniquenessCheck){
|
||||
/*printf("\n\tSolution after %d iterations\n", stats->numTries); */
|
||||
/*sudoku_print(sud); */
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (num == 0){
|
||||
/* can't be satisfied */
|
||||
return false;
|
||||
}
|
||||
/* try all the places (except the last one) */
|
||||
for (i = 0; i < num-1; i++){
|
||||
if (spawn_option(sud, stats, options, x, y, places[i])){
|
||||
/* solution found! */
|
||||
if (!options->allSolutions && stats->solutionFound){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* take the last place ourself */
|
||||
stats->numTries += 1;
|
||||
sudoku_set(sud, x, y, places[num-1], false);
|
||||
}
|
||||
}
|
||||
|
||||
/******** END OF IMPORTED CODE */
|
||||
|
||||
|
||||
/* A wrapper function between the Sudoku plugin and the above solver code */
|
||||
void sudoku_solve(struct sudoku_state_t* state)
|
||||
{
|
||||
bool ret;
|
||||
Stats stats;
|
||||
Options options;
|
||||
Sudoku sud;
|
||||
bool original;
|
||||
int r,c;
|
||||
|
||||
/* Initialise the parameters */
|
||||
sudoku_init(&sud);
|
||||
rb->memset(&stats,0,sizeof(stats));
|
||||
options.allSolutions=false;
|
||||
options.uniquenessCheck=false;
|
||||
|
||||
/* Convert Rockbox format into format for solver */
|
||||
for (r=0;r<9;r++) {
|
||||
for (c=0;c<9;c++) {
|
||||
if (state->startboard[r][c]!='0') {
|
||||
sudoku_set(&sud, c, r, state->startboard[r][c]-'0', true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* need to check for degenerate input problems ... */
|
||||
if (is_valid(&sud)){
|
||||
ret = solve(&sud, &stats, &options);
|
||||
} else {
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
/* Populate the board with the solution. */
|
||||
for (r=0;r<9;r++) {
|
||||
for (c=0;c<9;c++) {
|
||||
state->currentboard[r][c]='0'+
|
||||
sudoku_get(&sud, c, r, &original);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rb->splash(HZ*2, "Solve failed");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
void sudoku_solve(struct sudoku_state_t* state)
|
||||
{
|
||||
bool ret = sudoku_solve_board(state);
|
||||
|
|
Loading…
Reference in a new issue