Einzelnen Beitrag anzeigen

Volker Z.

Registriert seit: 3. Dez 2012
Ort: Augsburg, Bayern, Süddeutschland
419 Beiträge
 
Delphi XE4 Ultimate
 
#18

AW: Sudoku Generator (Anfänge)

  Alt 28. Jan 2013, 00:14
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ß
Volker Zeller
  Mit Zitat antworten Zitat