Sudoku: added "set all hints" help item.

* Sets all the hints for all the fields.
This commit is contained in:
Axel Dörfler 2014-12-29 10:03:28 +01:00
parent fe7fe2666d
commit 7ccbecc056
3 changed files with 87 additions and 46 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007-2012, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2007-2014, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
@ -1101,53 +1101,17 @@ SudokuView::MessageReceived(BMessage* message)
Redo();
break;
case kMsgSolveSudoku:
{
SudokuSolver solver;
solver.SetTo(fField);
bigtime_t start = system_time();
solver.ComputeSolutions();
printf("found %" B_PRIu32 " solutions in %g msecs\n",
solver.CountSolutions(), (system_time() - start) / 1000.0);
if (solver.CountSolutions() > 0) {
_PushUndo();
fField->SetTo(solver.SolutionAt(0));
Invalidate();
} else
beep();
case kMsgSetAllHints:
_SetAllHints();
break;
case kMsgSolveSudoku:
_Solve();
break;
}
case kMsgSolveSingle:
{
if (fField->IsSolved()) {
beep();
break;
}
SudokuSolver solver;
solver.SetTo(fField);
bigtime_t start = system_time();
solver.ComputeSolutions();
printf("found %" B_PRIu32 " solutions in %g msecs\n",
solver.CountSolutions(), (system_time() - start) / 1000.0);
if (solver.CountSolutions() > 0) {
_PushUndo();
// find free spot
uint32 x, y;
do {
x = rand() % fField->Size();
y = rand() % fField->Size();
} while (fField->ValueAt(x, y));
fField->SetValueAt(x, y,
solver.SolutionAt(0)->ValueAt(x, y));
_InvalidateField(x, y);
} else
beep();
_SolveSingle();
break;
}
default:
BView::MessageReceived(message);
@ -1320,3 +1284,70 @@ SudokuView::Draw(BRect /*updateRect*/)
}
void
SudokuView::_SetAllHints()
{
uint32 size = fField->Size();
for (uint32 y = 0; y < size; y++) {
for (uint32 x = 0; x < size; x++) {
uint32 validMask = fField->ValidMaskAt(x, y);
fField->SetHintMaskAt(x, y, validMask);
}
}
Invalidate();
}
void
SudokuView::_Solve()
{
SudokuSolver solver;
if (_GetSolutions(solver)) {
_PushUndo();
fField->SetTo(solver.SolutionAt(0));
Invalidate();
} else
beep();
}
void
SudokuView::_SolveSingle()
{
if (fField->IsSolved()) {
beep();
return;
}
SudokuSolver solver;
if (_GetSolutions(solver)) {
_PushUndo();
// find free spot
uint32 x, y;
do {
x = rand() % fField->Size();
y = rand() % fField->Size();
} while (fField->ValueAt(x, y));
fField->SetValueAt(x, y,
solver.SolutionAt(0)->ValueAt(x, y));
_InvalidateField(x, y);
} else
beep();
}
bool
SudokuView::_GetSolutions(SudokuSolver& solver)
{
solver.SetTo(fField);
bigtime_t start = system_time();
solver.ComputeSolutions();
printf("found %" B_PRIu32 " solutions in %g msecs\n",
solver.CountSolutions(), (system_time() - start) / 1000.0);
return solver.CountSolutions() > 0;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007-2012, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2007-2014, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
#ifndef SUDOKU_VIEW_H
@ -12,6 +12,7 @@
class BDataIO;
class SudokuField;
class SudokuSolver;
struct entry_ref;
@ -113,6 +114,10 @@ private:
void _UndoRedo(BObjectList<BMessage>& undos,
BObjectList<BMessage>& redos);
void _PushUndo();
void _SetAllHints();
void _Solve();
void _SolveSingle();
bool _GetSolutions(SudokuSolver& solver);
private:
rgb_color fBackgroundColor;
@ -146,6 +151,7 @@ private:
static const uint32 kMsgSudokuSolved = 'susl';
static const uint32 kMsgSolveSudoku = 'slvs';
static const uint32 kMsgSolveSingle = 'slsg';
static const uint32 kMsgSetAllHints = 'salh';
// you can observe these:
static const int32 kUndoRedoChanged = 'unre';

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007-2011, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2007-2014, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
@ -276,6 +276,10 @@ SudokuWindow::SudokuWindow()
fRestoreStateItem->SetEnabled(fStoredState != NULL);
menu->AddSeparatorItem();
menu->AddItem(new BMenuItem(B_TRANSLATE("Set all hints"),
new BMessage(kMsgSetAllHints)));
menu->AddSeparatorItem();
menu->AddItem(new BMenuItem(B_TRANSLATE("Solve"),
new BMessage(kMsgSolveSudoku)));
menu->AddItem(new BMenuItem(B_TRANSLATE("Solve single field"),