* SudokuSolver::ComputeSolutions() can now be called more than once without

doubling the solution list.
* ComputeSolutions() will now check if solving the Sudoku is affordable for
  this algorithm (at least 1/6th of the fields must be known). This fixes
  one part of bug #1435.
* SudokuView now checks if the Sudoku is already solved before trying to
  fill in a value from the solution (and then it did not find a free spot,
  surprisingly). This fixes the other part of bug #1435.
* SudokuView now beeps if there was no solution.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22110 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2007-08-29 13:24:31 +00:00
parent 60e8637484
commit 451cbc4a94
3 changed files with 33 additions and 3 deletions

View File

@ -144,7 +144,13 @@ SudokuSolver::SudokuSolver()
SudokuSolver::~SudokuSolver()
{
// we don't own the field but the solutions
_MakeEmpty();
}
void
SudokuSolver::_MakeEmpty()
{
for (uint32 i = 0; i < fSolutions.size(); i++) {
delete fSolutions[i];
}
@ -161,6 +167,20 @@ SudokuSolver::SetTo(SudokuField* field)
void
SudokuSolver::ComputeSolutions()
{
_MakeEmpty();
// We need to check if generating a solution is affordable with a
// brute force algorithm like this one
uint32 set = 0;
for (uint32 y = 0; y < fField->Size(); y++) {
for (uint32 x = 0; x < fField->Size(); x++) {
if (fField->ValueAt(x, y))
set++;
}
}
if (set < fField->Size() * fField->Size() / 6)
return;
Stack<SolutionStep*> stack;
SolutionStep* step = new SolutionStep(fField);
step->ToFirstUnset();

View File

@ -26,6 +26,8 @@ public:
SudokuField* SolutionAt(uint32 index);
private:
void _MakeEmpty();
typedef std::vector<SudokuField*> SudokuList;
SudokuField* fField;

View File

@ -15,6 +15,7 @@
#include <stdlib.h>
#include <Application.h>
#include <Beep.h>
#include <File.h>
#include <Path.h>
@ -617,12 +618,18 @@ SudokuView::MessageReceived(BMessage* message)
if (solver.CountSolutions() > 0) {
fField->SetTo(solver.SolutionAt(0));
Invalidate();
}
} else
beep();
break;
}
case kMsgSolveSingle:
{
if (fField->IsSolved()) {
beep();
break;
}
SudokuSolver solver;
solver.SetTo(fField);
bigtime_t start = system_time();
@ -640,7 +647,8 @@ SudokuView::MessageReceived(BMessage* message)
fField->SetValueAt(x, y,
solver.SolutionAt(0)->ValueAt(x, y));
_InvalidateField(x, y);
}
} else
beep();
break;
}