mirror of
https://github.com/jeremysrand/a2sudoku.git
synced 2024-06-12 20:06:50 +00:00
Big performance improvement by optimizing the algorithm for finding invalid squares.
This commit is contained in:
parent
5b0b4966c8
commit
d43aa69a7c
|
@ -256,9 +256,12 @@ bool isSquareInvalid(tPos col, tPos row)
|
||||||
subSquareYEnd = subSquareYStart + SUBSQUARE_SIZE;
|
subSquareYEnd = subSquareYStart + SUBSQUARE_SIZE;
|
||||||
for (y = subSquareYStart; y < subSquareYEnd; y++) {
|
for (y = subSquareYStart; y < subSquareYEnd; y++) {
|
||||||
for (x = subSquareXStart; x < subSquareXEnd; x++) {
|
for (x = subSquareXStart; x < subSquareXEnd; x++) {
|
||||||
if ((x != col) &&
|
if (x == col)
|
||||||
(y != row) &&
|
continue;
|
||||||
(value == SQUARE_XY(x, y).value))
|
if (y == col)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (value == SQUARE_XY(x, y).value)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -269,16 +272,74 @@ bool isSquareInvalid(tPos col, tPos row)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void refreshInvalid(void)
|
void refreshInvalid(tPos col, tPos row, tSquareVal oldValue)
|
||||||
{
|
{
|
||||||
tPos x, y;
|
tPos x, y;
|
||||||
tGameSquare *square;
|
tGameSquare *square = &(SQUARE_XY(col, row));
|
||||||
bool newInvalid;
|
bool newInvalid;
|
||||||
|
tPos subSquareXStart, subSquareXEnd;
|
||||||
|
tPos subSquareYStart, subSquareYEnd;
|
||||||
|
|
||||||
|
newInvalid = isSquareInvalid(col, row);
|
||||||
|
|
||||||
|
if (newInvalid != square->invalid) {
|
||||||
|
square->invalid = newInvalid;
|
||||||
|
refreshPos(col, row);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the value was empty, and this square is not invalid,
|
||||||
|
// then nothing more to check. We couldn't be adding a
|
||||||
|
// new invalid square nor fixing an existing invalid
|
||||||
|
// square.
|
||||||
|
if ((oldValue == EMPTY_SQUARE) &&
|
||||||
|
(!newInvalid))
|
||||||
|
return;
|
||||||
|
|
||||||
for (y = 0; y < BOARD_SIZE; y++) {
|
for (y = 0; y < BOARD_SIZE; y++) {
|
||||||
for (x = 0; x < BOARD_SIZE; x++) {
|
if (y == row)
|
||||||
square = &(SQUARE_XY(x, y));
|
continue;
|
||||||
|
|
||||||
|
square = &(SQUARE_XY(col, y));
|
||||||
|
if (square->knownAtStart)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
newInvalid = isSquareInvalid(col, y);
|
||||||
|
|
||||||
|
if (newInvalid != square->invalid) {
|
||||||
|
square->invalid = newInvalid;
|
||||||
|
refreshPos(col, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (x = 0; x < BOARD_SIZE; x++) {
|
||||||
|
if (x == col)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
square = &(SQUARE_XY(x, row));
|
||||||
|
if (square->knownAtStart)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
newInvalid = isSquareInvalid(x, row);
|
||||||
|
|
||||||
|
if (newInvalid != square->invalid) {
|
||||||
|
square->invalid = newInvalid;
|
||||||
|
refreshPos(x, row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
subSquareXStart = ((col / SUBSQUARE_SIZE) * SUBSQUARE_SIZE);
|
||||||
|
subSquareXEnd = subSquareXStart + SUBSQUARE_SIZE;
|
||||||
|
|
||||||
|
subSquareYStart = ((row / SUBSQUARE_SIZE) * SUBSQUARE_SIZE);
|
||||||
|
subSquareYEnd = subSquareYStart + SUBSQUARE_SIZE;
|
||||||
|
for (y = subSquareYStart; y < subSquareYEnd; y++) {
|
||||||
|
for (x = subSquareXStart; x < subSquareXEnd; x++) {
|
||||||
|
if (x == col)
|
||||||
|
continue;
|
||||||
|
if (y == col)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
square = &(SQUARE_XY(x, y));
|
||||||
if (square->knownAtStart)
|
if (square->knownAtStart)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -299,6 +360,7 @@ bool setValueAtPos(tPos x, tPos y, tSquareVal val)
|
||||||
bool update = false;
|
bool update = false;
|
||||||
bool checkValues = false;
|
bool checkValues = false;
|
||||||
bool correct;
|
bool correct;
|
||||||
|
tSquareVal oldValue = EMPTY_SQUARE;
|
||||||
|
|
||||||
if (square->knownAtStart) {
|
if (square->knownAtStart) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -310,6 +372,7 @@ bool setValueAtPos(tPos x, tPos y, tSquareVal val)
|
||||||
theGame.undo.y = y;
|
theGame.undo.y = y;
|
||||||
|
|
||||||
if (square->value != val) {
|
if (square->value != val) {
|
||||||
|
oldValue = square->value;
|
||||||
square->value = val;
|
square->value = val;
|
||||||
update = true;
|
update = true;
|
||||||
checkValues = true;
|
checkValues = true;
|
||||||
|
@ -332,7 +395,7 @@ bool setValueAtPos(tPos x, tPos y, tSquareVal val)
|
||||||
refreshPos(x,y);
|
refreshPos(x,y);
|
||||||
|
|
||||||
if (checkValues)
|
if (checkValues)
|
||||||
refreshInvalid();
|
refreshInvalid(x, y, oldValue);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -366,6 +429,7 @@ bool undoLastMove(void)
|
||||||
tPos x = theGame.undo.x;
|
tPos x = theGame.undo.x;
|
||||||
tPos y = theGame.undo.y;
|
tPos y = theGame.undo.y;
|
||||||
bool correct;
|
bool correct;
|
||||||
|
tSquareVal oldValue = EMPTY_SQUARE;
|
||||||
|
|
||||||
if (!theGame.undo.isValid)
|
if (!theGame.undo.isValid)
|
||||||
return false;
|
return false;
|
||||||
|
@ -379,6 +443,7 @@ bool undoLastMove(void)
|
||||||
theGame.undo.isValid = false;
|
theGame.undo.isValid = false;
|
||||||
|
|
||||||
if (square->value != theGame.undo.oldSquare.value) {
|
if (square->value != theGame.undo.oldSquare.value) {
|
||||||
|
oldValue = square->value;
|
||||||
square->value = theGame.undo.oldSquare.value;
|
square->value = theGame.undo.oldSquare.value;
|
||||||
update = true;
|
update = true;
|
||||||
checkValues = true;
|
checkValues = true;
|
||||||
|
@ -401,7 +466,7 @@ bool undoLastMove(void)
|
||||||
refreshPos(x,y);
|
refreshPos(x,y);
|
||||||
|
|
||||||
if (checkValues)
|
if (checkValues)
|
||||||
refreshInvalid();
|
refreshInvalid(x, y, oldValue);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user