* 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:
parent
60e8637484
commit
451cbc4a94
@ -144,7 +144,13 @@ SudokuSolver::SudokuSolver()
|
|||||||
SudokuSolver::~SudokuSolver()
|
SudokuSolver::~SudokuSolver()
|
||||||
{
|
{
|
||||||
// we don't own the field but the solutions
|
// we don't own the field but the solutions
|
||||||
|
_MakeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SudokuSolver::_MakeEmpty()
|
||||||
|
{
|
||||||
for (uint32 i = 0; i < fSolutions.size(); i++) {
|
for (uint32 i = 0; i < fSolutions.size(); i++) {
|
||||||
delete fSolutions[i];
|
delete fSolutions[i];
|
||||||
}
|
}
|
||||||
@ -161,6 +167,20 @@ SudokuSolver::SetTo(SudokuField* field)
|
|||||||
void
|
void
|
||||||
SudokuSolver::ComputeSolutions()
|
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;
|
Stack<SolutionStep*> stack;
|
||||||
SolutionStep* step = new SolutionStep(fField);
|
SolutionStep* step = new SolutionStep(fField);
|
||||||
step->ToFirstUnset();
|
step->ToFirstUnset();
|
||||||
|
@ -26,6 +26,8 @@ public:
|
|||||||
SudokuField* SolutionAt(uint32 index);
|
SudokuField* SolutionAt(uint32 index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void _MakeEmpty();
|
||||||
|
|
||||||
typedef std::vector<SudokuField*> SudokuList;
|
typedef std::vector<SudokuField*> SudokuList;
|
||||||
|
|
||||||
SudokuField* fField;
|
SudokuField* fField;
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
|
#include <Beep.h>
|
||||||
#include <File.h>
|
#include <File.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
|
|
||||||
@ -617,12 +618,18 @@ SudokuView::MessageReceived(BMessage* message)
|
|||||||
if (solver.CountSolutions() > 0) {
|
if (solver.CountSolutions() > 0) {
|
||||||
fField->SetTo(solver.SolutionAt(0));
|
fField->SetTo(solver.SolutionAt(0));
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
} else
|
||||||
|
beep();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case kMsgSolveSingle:
|
case kMsgSolveSingle:
|
||||||
{
|
{
|
||||||
|
if (fField->IsSolved()) {
|
||||||
|
beep();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
SudokuSolver solver;
|
SudokuSolver solver;
|
||||||
solver.SetTo(fField);
|
solver.SetTo(fField);
|
||||||
bigtime_t start = system_time();
|
bigtime_t start = system_time();
|
||||||
@ -640,7 +647,8 @@ SudokuView::MessageReceived(BMessage* message)
|
|||||||
fField->SetValueAt(x, y,
|
fField->SetValueAt(x, y,
|
||||||
solver.SolutionAt(0)->ValueAt(x, y));
|
solver.SolutionAt(0)->ValueAt(x, y));
|
||||||
_InvalidateField(x, y);
|
_InvalidateField(x, y);
|
||||||
}
|
} else
|
||||||
|
beep();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user