mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 02:27:39 -04:00
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 BLOCK 3
|
||||||
#define SIZE (BLOCK*BLOCK)
|
#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)
|
void sudoku_solve(struct sudoku_state_t* state)
|
||||||
{
|
{
|
||||||
bool ret = sudoku_solve_board(state);
|
bool ret = sudoku_solve_board(state);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue