Sudoku: consolidated set value code paths.
* Renamed _ToggleValue() to _SetValue(), and only let it do that. * It's now called from _InsertKey(), and _SolveSingle() as well which results in a correct visual update (ie. completed values, and the value hints are updated correctly). * _SolveSingle() would also not test for a completed game.
This commit is contained in:
@@ -618,7 +618,7 @@ SudokuView::MouseDown(BPoint where)
|
|||||||
| B_TERTIARY_MOUSE_BUTTON)) != 0) {
|
| B_TERTIARY_MOUSE_BUTTON)) != 0) {
|
||||||
// Double click or other buttons set or remove a value
|
// Double click or other buttons set or remove a value
|
||||||
if (!fField->IsInitialValue(x, y))
|
if (!fField->IsInitialValue(x, y))
|
||||||
_ToggleValue(x, y, value, field);
|
_SetValue(x, y, fField->ValueAt(x, y) == 0 ? value + 1 : 0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1068,9 +1068,7 @@ SudokuView::_InsertKey(char rawKey, int32 modifiers)
|
|||||||
fField->SetHintMaskAt(fKeyboardX, fKeyboardY, hintMask);
|
fField->SetHintMaskAt(fKeyboardX, fKeyboardY, hintMask);
|
||||||
} else {
|
} else {
|
||||||
_PushUndo();
|
_PushUndo();
|
||||||
fField->SetValueAt(fKeyboardX, fKeyboardY, value);
|
_SetValue(fKeyboardX, fKeyboardY, value);
|
||||||
if (value)
|
|
||||||
BMessenger(this).SendMessage(kMsgCheckSolved);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1112,37 +1110,37 @@ SudokuView::_GetFieldFor(BPoint where, uint32& x, uint32& y)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SudokuView::_ToggleValue(uint32 x, uint32 y, uint32 value, uint32 field)
|
SudokuView::_SetValue(uint32 x, uint32 y, uint32 value)
|
||||||
{
|
{
|
||||||
bool wasCompleted;
|
bool wasCompleted;
|
||||||
if (fField->ValueAt(x, y) > 0) {
|
if (value == 0) {
|
||||||
// Remove value
|
// Remove value
|
||||||
value = fField->ValueAt(x, y) - 1;
|
value = fField->ValueAt(x, y);
|
||||||
wasCompleted = fField->IsValueCompleted(value + 1);
|
wasCompleted = fField->IsValueCompleted(value);
|
||||||
|
|
||||||
fField->SetValueAt(x, y, 0);
|
fField->SetValueAt(x, y, 0);
|
||||||
fShowHintX = x;
|
fShowHintX = x;
|
||||||
fShowHintY = y;
|
fShowHintY = y;
|
||||||
} else {
|
} else {
|
||||||
// Set value
|
// Set value
|
||||||
wasCompleted = fField->IsValueCompleted(value + 1);
|
wasCompleted = fField->IsValueCompleted(value);
|
||||||
|
|
||||||
fField->SetValueAt(x, y, value + 1);
|
fField->SetValueAt(x, y, value);
|
||||||
BMessenger(this).SendMessage(kMsgCheckSolved);
|
BMessenger(this).SendMessage(kMsgCheckSolved);
|
||||||
|
|
||||||
_RemoveHintValues(x, y, value);
|
_RemoveHintValues(x, y, value);
|
||||||
|
|
||||||
// allow dragging to remove the hint from other fields
|
// allow dragging to remove the hint from other fields
|
||||||
fLastHintValueSet = false;
|
fLastHintValueSet = false;
|
||||||
fLastHintValue = value;
|
fLastHintValue = value - 1;
|
||||||
fLastField = field;
|
fLastField = x + y * fField->Size();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value + 1 != fValueHintValue && fValueHintValue != ~0UL)
|
if (value != fValueHintValue && fValueHintValue != ~0UL)
|
||||||
_SetValueHintValue(value + 1);
|
_SetValueHintValue(value);
|
||||||
|
|
||||||
if (wasCompleted != fField->IsValueCompleted(value + 1))
|
if (wasCompleted != fField->IsValueCompleted(value))
|
||||||
_InvalidateValue(value + 1, false, x, y);
|
_InvalidateValue(value, false, x, y);
|
||||||
else
|
else
|
||||||
_InvalidateField(x, y);
|
_InvalidateField(x, y);
|
||||||
}
|
}
|
||||||
@@ -1181,7 +1179,7 @@ SudokuView::_RemoveHintValues(uint32 atX, uint32 atY, uint32 value)
|
|||||||
uint32 blockSize = fField->BlockSize();
|
uint32 blockSize = fField->BlockSize();
|
||||||
uint32 blockX = (atX / blockSize) * blockSize;
|
uint32 blockX = (atX / blockSize) * blockSize;
|
||||||
uint32 blockY = (atY / blockSize) * blockSize;
|
uint32 blockY = (atY / blockSize) * blockSize;
|
||||||
uint32 valueMask = 1UL << value;
|
uint32 valueMask = 1UL << (value - 1);
|
||||||
|
|
||||||
for (uint32 y = blockY; y < blockY + blockSize; y++) {
|
for (uint32 y = blockY; y < blockY + blockSize; y++) {
|
||||||
for (uint32 x = blockX; x < blockX + blockSize; x++) {
|
for (uint32 x = blockX; x < blockX + blockSize; x++) {
|
||||||
@@ -1259,9 +1257,8 @@ SudokuView::_SolveSingle()
|
|||||||
y = rand() % fField->Size();
|
y = rand() % fField->Size();
|
||||||
} while (fField->ValueAt(x, y));
|
} while (fField->ValueAt(x, y));
|
||||||
|
|
||||||
fField->SetValueAt(x, y,
|
uint32 value = solver.SolutionAt(0)->ValueAt(x, y);
|
||||||
solver.SolutionAt(0)->ValueAt(x, y));
|
_SetValue(x, y, value);
|
||||||
_InvalidateField(x, y);
|
|
||||||
} else
|
} else
|
||||||
beep();
|
beep();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,8 +106,7 @@ private:
|
|||||||
uint32 y, uint32& hintX, uint32& hintY);
|
uint32 y, uint32& hintX, uint32& hintY);
|
||||||
bool _GetFieldFor(BPoint where, uint32& x,
|
bool _GetFieldFor(BPoint where, uint32& x,
|
||||||
uint32& y);
|
uint32& y);
|
||||||
void _ToggleValue(uint32 x, uint32 y, uint32 value,
|
void _SetValue(uint32 x, uint32 y, uint32 value);
|
||||||
uint32 field);
|
|
||||||
void _ToggleHintValue(uint32 x, uint32 y,
|
void _ToggleHintValue(uint32 x, uint32 y,
|
||||||
uint32 hintX, uint32 hintY,
|
uint32 hintX, uint32 hintY,
|
||||||
uint32 value, uint32 field);
|
uint32 value, uint32 field);
|
||||||
|
|||||||
Reference in New Issue
Block a user