Sudoku: refactor unit SudokuType: more verbose names of types, methods and parameters. No functional changes.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7238 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
lazarus-bart
2020-01-05 11:41:05 +00:00
parent 2b77fd9f3e
commit dcbe588b51

View File

@ -30,26 +30,28 @@ uses
Classes, SysUtils, StdCtrls; Classes, SysUtils, StdCtrls;
type type
Digits = set of 1..9; TDigits = 1..9;
TDigitSet = set of TDigits;
TSquare = record TSquare = record
Value: Integer; // The value of this square. Value: Integer; // The value of this square.
Locked: Boolean; // Wether or not the value is known. Locked: Boolean; // Wether or not the value is known.
DigitsPossible: Digits; DigitsPossible: TDigitSet;
end; end;
TValues = Array[1..9,1..9] of Integer; TValues = Array[1..9,1..9] of Integer;
TRawGrid = Array[1..9, 1..9] of TSquare;
{ TSudoku } { TSudoku }
TSudoku = class(TObject) TSudoku = class(TObject)
function GiveSolution(var Values: TValues; out Steps: Integer): Boolean; function GiveSolution(var Values: TValues; out Steps: Integer): Boolean;
private private
Grid : Array[1..9, 1..9] of TSquare; Grid: TRawGrid;
procedure CalculateValues(out IsSolved: Boolean); procedure CalculateValues(out IsSolved: Boolean);
procedure CheckRow(c, r: Integer); procedure CheckRow(Col, Row: Integer);
procedure CheckCol(c, r: Integer); procedure CheckCol(Col, Row: Integer);
procedure CheckBlock(c, r: Integer); procedure CheckBlock(Col, Row: Integer);
procedure CheckDigits(d: Integer); procedure CheckDigits(ADigit: Integer);
procedure Fill(Values: TValues); procedure FillGridFromValues(Values: TValues);
function Solve(out Steps: Integer): Boolean; function Solve(out Steps: Integer): Boolean;
//function Solved: Boolean; //function Solved: Boolean;
end; end;
@ -61,10 +63,10 @@ const
cmax : Array[1..9] of Integer = (3, 3, 3, 6, 6, 6, 9, 9, 9); cmax : Array[1..9] of Integer = (3, 3, 3, 6, 6, 6, 9, 9, 9);
{ {
Counts the number of digits in ASet. Counts the number of TDigitSet in ASet.
aValue only has meaning if Result = 1 (which means this cell is solved) aValue only has meaning if Result = 1 (which means this cell is solved)
} }
function CountSetMembers(const ASet: Digits; out aValue: Integer): Integer; function CountSetMembers(const ASet: TDigitSet; out aValue: Integer): Integer;
var var
D: Integer; D: Integer;
begin begin
@ -80,7 +82,7 @@ end;
{ TSudoku } { TSudoku }
procedure TSudoku.Fill(Values: TValues); procedure TSudoku.FillGridFromValues(Values: TValues);
var var
c, r: Integer; c, r: Integer;
begin begin
@ -124,7 +126,7 @@ function TSudoku.GiveSolution(var Values: TValues; out Steps: Integer): Boolean;
var var
c, r: Integer; c, r: Integer;
begin begin
Fill(Values); FillGridFromValues(Values);
Result := Solve(Steps); Result := Solve(Steps);
for c := 1 to 9 do begin for c := 1 to 9 do begin
for r := 1 to 9 do begin for r := 1 to 9 do begin
@ -159,46 +161,46 @@ begin
IsSolved := Count = 9 * 9; IsSolved := Count = 9 * 9;
end; end;
procedure TSudoku.CheckCol(c, r: Integer); procedure TSudoku.CheckCol(Col, Row: Integer);
var var
i, d: Integer; i, d: Integer;
begin begin
for i := 1 to 9 do begin for i := 1 to 9 do begin
if i = r then continue; if i = Row then continue;
for d := 1 to 9 do begin for d := 1 to 9 do begin
if Grid[c, i].Value = d then exclude(Grid[c, r].DigitsPossible, d); if Grid[Col, i].Value = d then exclude(Grid[Col, Row].DigitsPossible, d);
end; end;
end; end;
end; end;
procedure TSudoku.CheckRow(c, r: Integer); procedure TSudoku.CheckRow(Col, Row: Integer);
var var
i, d: Integer; i, d: Integer;
begin begin
for i := 1 to 9 do begin for i := 1 to 9 do begin
if i = c then continue; if i = Col then continue;
for d := 1 to 9 do begin for d := 1 to 9 do begin
if Grid[i, r].Value = d then exclude(Grid[c, r].DigitsPossible, d); if Grid[i, Row].Value = d then exclude(Grid[Col, Row].DigitsPossible, d);
end; end;
end; end;
end; end;
procedure TSudoku.CheckBlock(c, r: Integer); procedure TSudoku.CheckBlock(Col, Row: Integer);
var var
i, j, d: Integer; i, j, d: Integer;
begin begin
for i := cmin[c] to cmax[c] do begin for i := cmin[Col] to cmax[Col] do begin
for j := cmin[r] to cmax[r] do begin for j := cmin[Row] to cmax[Row] do begin
if not ((i = c) and (j = r)) then begin if not ((i = Col) and (j = Row)) then begin
for d := 1 to 9 do begin for d := 1 to 9 do begin
if Grid[i, j].Value = d then exclude(Grid[c, r].DigitsPossible, d); if Grid[i, j].Value = d then exclude(Grid[Col, Row].DigitsPossible, d);
end; end;
end; end;
end; end;
end; end;
end; end;
procedure TSudoku.CheckDigits(d: Integer); procedure TSudoku.CheckDigits(ADigit: Integer);
var var
OtherPossible: Boolean; OtherPossible: Boolean;
c, r: Integer; c, r: Integer;
@ -209,22 +211,22 @@ begin
for r := 1 to 9 do begin for r := 1 to 9 do begin
if Grid[c, r].Locked if Grid[c, r].Locked
or (CountSetMembers(Grid[c, r].DigitsPossible, Value) = 1) then continue; or (CountSetMembers(Grid[c, r].DigitsPossible, Value) = 1) then continue;
if d in Grid[c, r].DigitsPossible then begin if ADigit in Grid[c, r].DigitsPossible then begin
OtherPossible := False; OtherPossible := False;
for i := 1 to 9 do begin for i := 1 to 9 do begin
if i <> c then OtherPossible := (d in Grid[i, r].DigitsPossible); if i <> c then OtherPossible := (ADigit in Grid[i, r].DigitsPossible);
if OtherPossible then Break; if OtherPossible then Break;
end; end;
if not OtherPossible then begin if not OtherPossible then begin
Grid[c, r].DigitsPossible := [d]; Grid[c, r].DigitsPossible := [ADigit];
end else begin end else begin
OtherPossible := False; OtherPossible := False;
for i := 1 to 9 do begin for i := 1 to 9 do begin
if i <> r then OtherPossible := (d in Grid[c, i].DigitsPossible); if i <> r then OtherPossible := (ADigit in Grid[c, i].DigitsPossible);
if OtherPossible then Break; if OtherPossible then Break;
end; end;
if not OtherPossible then begin if not OtherPossible then begin
Grid[c, r].DigitsPossible := [d]; Grid[c, r].DigitsPossible := [ADigit];
end; end;
end; end;
end; end;