Hallo,
ich las gerade eben nochmals meinen letzten Beitrag, und ich muss zugeben dieser war nun wirklich nicht verständlich formuliert. Es tut mir sehr leid, dadurch vielleicht mehr Verwirrung gestiftet, als zu einer Lösung beigetragen zu haben.
Mit:
Zitat:
In Deiner while-Schleife prüfst Du, ob ein gültiges Spielfeld noch immer gültig ist(?)
und dem nachfolgenden bezog ich mich auf das, meiner Meinung nach falsche Prüfen der Bedingung IsValid(SG) in der Schleifenbedingung. Und das geht aus meinem Beitrag nun wirklich nicht hervor; sorry dafür.
Ich habe mich jetzt zwar nicht näher mit Sudokus – und deren Theorie – auseinander gesetzt, aber mit Deinem Thema in einem komplett gefüllten Sudoku Felder auszublenden und dabei die eindeutige Lösbarkeit zu erhalten. Ich hoffe, dass folgender Quellcode verständlich und nachvollziehbar ist. Wenn Fragen bestehen gerne.
Delphi-Quellcode:
type
TSudokuBounds = 0..8;
TSudokuDigit = 0..9;
TSudokuBoard = array [TSudokuBounds, TSudokuBounds] of TSudokuDigit;
TSudokuField = record
Col : Byte;
Row : Byte;
end;
Delphi-Quellcode:
TForm4 = class(TForm)
private
FDigitCounter : Byte;
FSudokuBoard : TSudokuBoard;
procedure ClearRandomFields;
function GetRandomFieldNotEmpty : TSudokuField;
function IsDefiniteSolvable : Boolean;
end;
Delphi-Quellcode:
procedure TForm4.ClearRandomFields;
var
v :
array [TSudokuBounds, TSudokuBounds]
of Boolean;
f : TSudokuField;
t : 1..9;
begin
FillChar (v, SizeOf (v), Integer (True));
while FDigitCounter > 21
do
begin
f := GetRandomFieldNotEmpty;
if v [f.Col, f.Row] = False
then
Continue;
t := FSudokuBoard [f.Col, f.Row];
FSudokuBoard [f.Col, f.Row] := 0;
if IsDefiniteSolvable
then
Dec (FDigitCounter)
else
begin
FSudokuBoard [f.Col, f.Row] := t;
v [f.Col, f.Row] := False
end
end
end;
function TForm4.GetRandomFieldNotEmpty : TSudokuField;
begin
repeat
with Result
do
begin
Col := Random (9);
Row := Random (9);
if FSudokuBoard [Col, Row] <> 0
then
Break
end
until True
end;
function TForm4.IsDefiniteSolvable : Boolean;
var
i, n : Byte;
c, r : TSudokuBounds;
f : Boolean;
begin
n := 0;
for i := 1
to 9
do
begin
f := False;
c := 0;
repeat
r := 0;
repeat
if FSudokuBoard [c, r] = i
then
begin
f := True;
Inc (n)
end;
Inc (r)
until f
or (r = High (TSudokuBounds) + 1);
Inc (c)
until f
or (c = High (TSudokuBounds) + 1)
end;
Result := n > 8
end;
Gruß