Einzelnen Beitrag anzeigen

Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#16

AW: Sudoku Array of Array vergleichen

  Alt 19. Nov 2011, 19:52
Hab’s mal ausprobiert, allerdings etwas anders. Die Quadranten nenne ich hier Blöcke. Als Grundlage der Suche benutze ich eine Pemutliste. Geht recht flott so, < 2 sec..

Delphi-Quellcode:
function BlockToRowCol(Block, Index: integer): TPoint;
var
  VX, VY: integer;
begin
  // Block 0..8, Index 0..8
  // Result.X = Row 0..8, Result.Y = Col 0..8
  VX:= 0;
  VY:= 0;
  case Block of
    0: begin VX:= 0; VY:= 0; end;
    1: begin VX:= 3; VY:= 0; end;
    2: begin VX:= 6; VY:= 0; end;
    3: begin VX:= 0; VY:= 3; end;
    4: begin VX:= 3; VY:= 3; end;
    5: begin VX:= 6; VY:= 3; end;
    6: begin VX:= 0; VY:= 6; end;
    7: begin VX:= 3; VY:= 6; end;
    8: begin VX:= 6; VY:= 6; end;
  end;
  with Result do
  begin
    X:= 0;
    Y:= 0;
    case Index of
      0: begin X:= VY; Y:= VX; end;
      1: begin X:= VY; Y:= VX+1; end;
      2: begin X:= VY; Y:= VX+2; end;
      3: begin X:= VY+1; Y:= VX; end;
      4: begin X:= VY+1; Y:= VX+1; end;
      5: begin X:= VY+1; Y:= VX+2; end;
      6: begin X:= VY+2; Y:= VX; end;
      7: begin X:= VY+2; Y:= VX+1; end;
      8: begin X:= VY+2; Y:= VX+2; end;
    end;
  end;
end;

procedure TForm1.SetSudokuBlock(I: integer; Numbers: TIntegerList);
var
  Result: TIntegerList;
  J, N, Index: integer;
  T: TPoint;
  A, B, C: boolean;
begin
  Result:= TIntegerList.Create;
  try
    Result.FillUp(9);
    N:= 0;
    repeat
      A:= true;
      B:= true;
      C:= true;
      for J:= 0 to 8 do
      begin
        Index:= FPermutList.Item[N*9+J];
        Result.Item[J]:= Numbers.Item[Index];
        T:= BlockToRowCol(I, J);
        A:= A and FRow[T.X].CanHaveValue(Result.Item[J]);
        B:= B and FCol[T.Y].CanHaveValue(Result.Item[J]);
        C:= C and FBlock[I].CanHaveValue(Result.Item[J]);
      end;
      Inc(N);
    until (A and B and C);
    for J:= 0 to 8 do
    begin
      T:= BlockToRowCol(I, J);
      FRow[T.X].Item[T.Y]:= Result.Item[J];
      FCol[T.Y].Item[T.X]:= Result.Item[J];
      FBlock[I].Item[J]:= Result.Item[J];
    end;
  finally
    Result.Free;
  end;
end;

procedure TForm1.BuildSudoku;
var
  Numbers: TIntegerList;
  I, J: integer;
begin
  Numbers:= TIntegerList.Create;
  try
    Numbers.FillUp(9, 1, 1);
    Numbers.Mix;
    SudokuNull;
    for I:= 0 to 8 do // Blöcke
      SetSudokuBlock(I, Numbers);
  finally
    Numbers.Free;
  end;
end;
  Mit Zitat antworten Zitat