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:
Axel Dörfler
2015-01-15 20:30:46 +01:00
parent 758cfd808a
commit aeb121ec03
2 changed files with 18 additions and 22 deletions
+17 -20
View File
@@ -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();
} }
+1 -2
View File
@@ -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);