Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Sudoku Lösen und Code Verständnisproblem (https://www.delphipraxis.net/151460-sudoku-loesen-und-code-verstaendnisproblem.html)

MaToBe 18. Mai 2010 22:19


Sudoku Lösen und Code Verständnisproblem
 
Hallo, da bin ich schon wieder :D

Nun geht es darum, ein Sudoku zu lösen. Genauer gesagt habe ch ein Sudoku mit einigen Lücken und möchte eine bestimmte Zahl in eine dieser Lücken platzieren, wo die Spielregeln dies eben zulassen.

Ich habe hier meines Wissens alle Sudoku-OpenSource Codes ect. durchgesehen. Am ansprechensden fand ich diesen hier, sehr gut gegliedert und strukturiert. Denoch ist das ein wenig zu hoch für mich.

Leider scheitert es schon am Anfang, dem "eingeben" des Sudokus. Ich habe mein Sudoku in einem StringGrid gespeichert und möchte es nun in das Array der Unit umwandeln.

Der Code der fremden Unit:
Delphi-Quellcode:
...
type
  use= set of 1..81;
  TSudoku=Class(TObject)
  private
    sudoku:   Array of Array[1..81]         of Integer;
    impossible:Array of Array[1..9,1..9,1..9] of Boolean;
    owner:    Array of Array[1..9,1..9,1..9] of Integer;
    quadrant: Array of Array[1..3,1..3,1..9] of Boolean;
    count,num:integer;
...
procedure TSudoku.SetVal(num,index,val:integer);
begin
  sudoku[num,index]:=val;
end;;
...
Mein Code zum Eintragen:
Delphi-Quellcode:
procedure TfrmMain.btnSudokuAnClick(Sender: TObject);
var m, n, i: integer;
begin
    Sudoku.Create;
    i := 1;

    for m := 0 to 8 do
    begin
      for n := 0 to 8 do
        begin
           Sudoku.SetVal(0,i,strtoint(sgSudoku.Cells[m,n]));
           inc(i);
        end;
    end;
end;
In der Beschreibung steht noch:
Zitat:

#
1. Unit USudoku einbinden über uses
2. Variable vom Typ TSudoku erstellen.
3. .create methode aufrufen
4. Werte ins Objekt laden. Dies geschieht per .Setvalue(0,1..81,val) //Wert 0 für leeres Feld!
...
Die Funktionen zum Setzen/Abrufen der Werte brauchen als ersten Paramter eine 0, damit auf die erste lösung zugegriffen wird. Ich bin gerade debei eine Funktion hinzuzufügen, die noch weitere Möglichkeiten berechnen kann, und diese in einem anderen Array abspeichert.
...
Punkt 1-3 waren einfach 8-) aber bei Punkt 4 mach ich irgendwas falsch :?

MFG MaToBe

PS: Falls jemand einen Codeausschnitt hat, der genau das Leistet was ich oben beschieben habe, wär ich nicht abgeneigt, mir diesen mal anzusehn :thumb:

omata 18. Mai 2010 23:03

Re: Sudoku Lösen und Code Verständnisproblem
 
Vielleicht hilft dir das hier weiter.

Tryer 18. Mai 2010 23:11

Re: Sudoku Lösen und Code Verständnisproblem
 
Delphi-Quellcode:
Sudoku := TSudoku.Create;
Ansonsten dürfte die Fehlerbeschreibung etwas genauer sein ;)

Grüsse, Dirk

MaToBe 18. Mai 2010 23:33

Re: Sudoku Lösen und Code Verständnisproblem
 
Zitat:

Zitat von omata
Vielleicht hilft dir das hier weiter.

Besitzt dein Programm solch eine Funktion? Ich habe dein Projekt bereits aufm PC aber ich kann es nicht compilieren... "QuickRpt, QRCtrls können nicht aufgelöst werden".


Zitat:

Zitat von Tryer
Delphi-Quellcode:
Sudoku := TSudoku.Create;
Ansonsten dürfte die Fehlerbeschreibung etwas genauer sein ;)

okay das war wirklich ein blöde Fehler... naja is schon spät :D

jetzt scheint es zu funktionieren, auch wenn ich natürlich keine visuelle Bestätigung habe.

Delphi-Quellcode:
...
type
  use= set of 1..81;
  TSudoku=Class(TObject)
  private
    sudoku:   Array of Array[1..81]         of Integer;
    impossible:Array of Array[1..9,1..9,1..9] of Boolean;
    owner:    Array of Array[1..9,1..9,1..9] of Integer;
    quadrant: Array of Array[1..3,1..3,1..9] of Boolean;
    count,num:integer;
    fehler:boolean;
    ErrVal,ErrNum:integer;
    inuse: set of 1..81;
...
procedure TSudoku.SetPos(num,index:integer);       //Möglichkeiten setzen
var
x,y,c1,c2,Val,LineX,LineY,QuadX,QuadY:integer;
begin
  LineX:=GetLineX(index);
  LineY:=GetLineY(index);
  QuadX:=GetQuadX(index);
  QuadY:=GetQuadY(index);
  Val:=Sudoku[num,index];
  //Zeilen Möglichkeiten setzen;
  for c1:=1 to 9 do begin
    if owner[num,LineX,c1,val]=0 then owner[num,LineX,c1,val]:=index;
    impossible[num,LineX,c1,val]:=true;
    if owner[num,c1,LineY,val]=0 then owner[num,c1,LineY,val]:=index;
    impossible[num,c1,LineY,val]:=true;
    if owner[num,Linex,Liney,c1]=0 then begin
      owner[num,Linex,Liney,c1]:=index;
      impossible[num,Linex,Liney,c1]:=true;
    end;
  end;
  for c1:= 1 to 3 do begin
    x:=(Quadx-1)*3+c1;
    for c2:=1 to 3 do begin
      y:=(Quady-1)*3+c2;
      if owner[num,x,y,val]=0 then owner[num,x,y,val]:=index;
      impossible[num,x,y,val]:=true;
    end;
  end;
  Quadrant[num,QuadX,QuadY,val]:=true;
end;
Mit diesem Code werden fü jedes Feld, so wie ich das Verstanden habe, die möglichen Zahlen gesetzt. Allerdings werde ich daraus nicht ganz schlau. Vielleicht kann mir das einer grob erklären... Ansatz usw.

Tryer 19. Mai 2010 19:54

Re: Sudoku Lösen und Code Verständnisproblem
 
Zitat:

Zitat von MaToBe
Mit diesem Code werden fü jedes Feld, so wie ich das Verstanden habe, die möglichen Zahlen gesetzt.

Es wid gesetzt wo die Zahl nicht mehr hin kann.
Trägst Du in ein Feld eine Zahl ein und rufst SetPos(Feld) auf, dann werden hier alle Feldern der betreffenden Zeile, Spalte und des betreffenden Quadrats markiert als "hier darf die Zahl nicht mehr hin".
Jetzt könnte es ja sein das man bei diesem "Verbieten" an ein Feld kommt wo die Zahl sowieso schon nicht mehr hin darf, bedingt durch ein ganz anderes Feld. Wenn ich dann im Lösungsalgorithmus des Feld wieder zurücknehmen möchte weil es falsch war, dann darf ich die Zahl nur an den Stellen "freigeben" an denen sie auch durch dieses Feld verboten wurde.
Diese Unterscheidung passiert in "Owner", da wird eingetragen welches Feld dafür verantwortlich ist das diese spezielle Zahl an der Stelle keinen Platz findet.

Grüsse, Dirk

PS: ob diese Implementierung jetzt besonders gut strukturiert ist weis ich nicht, mir fehlt die Objektorientierung in der Datenstruktur (ein Feld wäre für mich ein individuelles Objekt das in Zeile/Spalte/Quadrat referenziert wird) und es gibt für meinen Geschmack zu viele goto´s.. und selbermachen ist viel lehrreicher ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:52 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz