Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Sudoku Richtigkeit Kontrollieren
Grimsch - Do 26.11.09 13:22
Titel: Sudoku Richtigkeit Kontrollieren
hallo und guten tag :)
ich programmiere momentan ein Sudoku Programm. Nun bin ich dabei Per Buttonklick das Sudoku auf seine Richtigkeit zu prüfen. Meine Idee war es jedes einzelne feld eines Stringgrid mit den anderen zu vergleichen welche waagerecht und senkrecht dazu liegen und am Ende eine Message auszugeben, welche sagt ob ein Fehler vorhanden ist oder nicht. Allerdings weiß ich nicht wie ich das in einem kompakten Umfang machen kann. Das wohl einfachste wäre folgendes:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| procedure TForm1.Button2Click(Sender: TObject); begin if stringgrid1.cells[0,0]<>stringgrid1.cells[1,0] then showmessage('Richtig') else showmessage('Falsch') end; |
allerdings müsste ich um dies mit jedem Feld zu machen diesen quelltext hunderte oder eher tausende male wiederholen. Könnt ihr mir ein gutes Beispiel geben um mein Problem zu lösen? und bitte so simpel wie möglich für mich erklären bin nicht sonderlich gut um umgang mit delphi :)
Mike19 - Do 26.11.09 13:24
ja, gibt es in der Suche!
Nersgatt - Do 26.11.09 13:39
Nur so als Ansatz. Es dürfen ja die Zahlen 1-9 nur einmal je Reihe/Spalte/Feld vorkommen.
Du musst also für jede Reihe, für jede Spalte und für jedes Feld das prüfen (es sei denn, du findest einen Fehler, dann kannst Du natürlich schon abbrechen).
Mach doch ein Array, in dem Du dir merkst, ob eine Zahl schon da war. Psyeudocode:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| Zahlen[1..9] : Boolean;
Für Jede Reihe Setze alle Arrayfelder von Zahlen auf false für jedes Feld in Reihe Wenn Zahlen[Feld] = False dann Setze Zahlen[Feld] = True sonst Fehlermeldung "Zahl im Feld " + Feld + " in Reihe " + Reihe + " doppelt vorhanden!" Prozedur abbrechen nächstes Feld nächste Reihe |
Das selbe für jede Spalte und jedes Feld. Fertig.
Grimsch - Di 01.12.09 13:16
ok danke aber ich habe momentan ja schon das Array:
Delphi-Quelltext
1:
| sudoku: array[0..8] of array[0..8] of array[0..14] of string; |
dieses habe ich dem stringgrid schon soweit zugewiesen. Nur wie mache ich das dann mit dem boolean array? das sieht nun so aus:
Delphi-Quelltext
1:
| zahlen: array[1..9] of array[1..9] of boolean; |
nur kann ich mir nun nicht genau vorstellen wie der weitergehende quelltext aussehen soll. Ich muss das doch irgendwie zuordnen zum Stringgrid oder nicht? Außerdem versteh ich nicht wie das mit den true und false funktionieren soll um zu prüfen dass die bestimmte zahl in der einen reihe und spalte nur einmal vorhanden ist. :S
Tilo - Di 01.12.09 13:39
Du must für jede Gruppierung von Zahlen (hier 9 Quadrate, 9 Zeilen und 9 Spalten) jeweils ein Boolarray[0..8] anlegen.
Jetzt durchläufst Du das gesamte SpielFeld einmal. Zu jedem Element prüfst Du in welchen Gruppierungen es sich befindet. Dies sind immer 1 Quadrat, eine Zeile und eine Spalte. Für die 3 betreffenden Gruppierungen prüfst ob die Zahl des akutellen Feldes schonmal in der Gruppierung vorkam (Gruppierung[Zahl]=true), Ist dies der Fall => Fehler, sonst auf Wahr setzen und beim nächsten Feld weiter machen.
Sind alle Felder ohne Fehler durchgelaufen müsste zur Vollständigkeit geprüft werden ob für jede Gruppierung jede Zahl vorkam. Dies dient zur Kontrolle ob der Test korrekt durchgelaufen ist und nicht durch irgendeinen unwahrscheinlichen Zufall (oder eher Programmierfehler) ein Feld, Zeile, Spalte oder Quadrat vergessen wurde.
Wobei mir die exesive Verwendung von Arrays mitlerweile grusellig vorkommt. statt eines Arrays of boolean wäre es hier auch möglich eine Liste von Integern zu nehmen und diese beim ersten Vorkommen einer Zahl aus der Liste zu entfernen.
Die Abschlussprüfung ist dann einfacher: Ist Liste leer? ja > alles prima, nein =>Sch***benkleister
Bergmann89 - Di 01.12.09 13:42
Hey,
wozu das letzte Array von dem Soduku? Und warum String?
bei mir würde ein Sodoku so aussehen:
Delphi-Quelltext
1:
| sodoku: array[0..8, 0..8] of Integer |
Ich hab auch ma eins gebaut, die Funktion die das prüft hab ich aber Daheim (bin grad in der Schule). Die kann ich dir dann ja ma geben...
MfG Bergmann.
Tilo - Di 01.12.09 13:44
Hallo,
eben ist mir noch eine Test Möglichkeit eingefallen: Summen.
Die Summen in jedem Qudarat, jeder Zeile und jeder Spalte müssen identisch sein.
Im klassischen Falle 45.
Grimsch - Di 01.12.09 14:01
die idee mit den summen gefällt mir muss ich nurnoch gucken wie man das umsetzen kann^^
@bergmann: string hab ich gemacht damit ich nicht umwandeln brauche das und das macht ja wohl auch nichts weiter aus oder?
und die letzte zeile sollte für ganze sudokus also fertige sudokus sein, welche dann durch zufall ausgewählt werden. Wollte ersteinmal einfach anfangen bevor ich mir selbst ein sudoku durch zufall generieren lasse. :) und das mit dem quelltext wäre super :D aber am besten auch mit erklärung bei den meisten zeilen, da ich das ja selbst auch irgendwie verstehen muss^^
Bergmann89 - Di 01.12.09 15:18
Hey,
ich hab mein Sudoku nich mehr gefunden, aber ich hab das ganze ma schnell neu geschrieben (zumindest die Tests):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53:
| var sudoku: array[0..8, 0..8] of Integer;
function CheckField(X, Y: Integer): Boolean; var i, QuadPosX, QuadPosY: Integer; begin result := false ; if(X < 0)or(X > 8) then exit; if(Y < 0)or(Y > 8) then exit; for i := 0 to 8 do begin if (i <> X)and (sudoku[i,Y] = sudoku[X,Y]) then exit; if (i <> Y)and (sudoku[X,i] = sudoku[X,Y]) then exit; QuadPosX := (i mod 3) + (X div 3)*3; QuadPosY := (i div 3) + (Y div 3)*3; if(QuadPosX <> X)and (QuadPosY <> Y)and (sudoku[QuadPosX, QuadPosY] = sudoku[X, Y]) then exit; end; result := true; end;
function CheckAll: Boolean; var i: Integer; begin result := False; for i := 0 to 80 do if not CheckField( i mod 9, i div 9) then exit; result := True; end; |
!!!ABER UNGETESTET!!!
Ich hab mit nem
Sudoku: array[0..8, 0..8] of Integer gearbeitet, wie du siehst. Also musst du jetzt so oder so umwandeln. Ich würd dir aber empfehlen es als Integer zu machen, weil du noch heufiger admit rechnen musst un dann jedesma Umwandeln is mist...
Das mit den Fertigen Sodokus wird ich dann in ne Liste machen, die du aus ner Datei laden kannst:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| type TSudoku = array[0..8, 0..8] of Integer; PSodoku = ^TSudoku; var SudokuList: TList;
procedure AddSudokuToList(FileName: String); var p: PSodoku; begin new(p); LoadSudoku(p^, FileName); SudokuList.Add(p); end; |
un mit der Liste kannste dann ganz gut arbeiten un die Sodokus da raus laden, oder auch ganz easy neue hinzufügen oder welche löschen, die Möglichkeiten sind einfach mehr als beim Array...
MfG Bergmann.
p.s.: wenn ich dir noch was zum Quelltext erklären soll frag, aber die Komments sind eigentlich ziemlich ausführlich ^^
Grimsch - Di 08.12.09 13:47
ich verstehe da irgendwie so einiges nicht :S
wie sieht das mit dem X und Y aus? ich versteh nicht was das eigentlich genau in dieser programmierung ist. speziell in dem teil : (sudoku[i,Y] = sudoku[X,Y]) weil das ja irgendwie alles variablen sind oder nicht? und wenn das der fall ist muss man doch irgendwie x und y etwas zuweisen nur was? Außerdem weiß ich nicht was das mit dem div und mod genau bringt. ich weiß zwar dass das etwas ist womit gerechnet wird aber wie das nun hier gebraucht wird weiß ich auch nicht :S
ich könnte nun zwar durch deine beschreibungen sagen wo was passiert aber wie und warum weiß ich nicht. :S
irgendwie is mir das zu hoch >.<
gibt es nicht irgendwie eine Möglichkeit alle reihen und alle spalten sowie die quadrate anzusteuern und zu überprüfen ob die einen Wert von 45 besitzen?
meine idee war halt dass ich s,z,q: boolean; setze und da irgendwie zu jedem etwas schreibe also zB. wenn spalte 0-9 jeweils 45 ist dann s=true. und dann zum schluss wenn s,z und q = true dann Richtig gelöst. ich weiß nur nicht wie ich das umsetze :S
---
Moderiert von
Narses: Beiträge zusammengefasst---
beachtet am besten nur den zweiten teil^^
{spalte 1 bis 9 jeweils 45
zeile 1 bis 9 jeweils 45
quadrat 1 bis 9 jeweils 45
dann: s,z und q = true
if s,z,q = true then
showmessage('Sudoku korrekt gelöst')}
das würde ich am liebsten programmieren ich weiß nur überhaupt nicht wie. :S
Bergmann89 - Mi 09.12.09 00:17
Hey,
das X und das Y sind Parameter, die mit an die Funktion übergeben werden. (wie du ne Funktion schreibst un was das is weißt du, oder?). Also bekommt X und Y ihre Werte beim aufruf der Funktion:
CheckField(1,2);
mit dem
div und dem
mod berechne ich den Index des gewünschten Feldes. Man kann auch 2 Schleifen nehmen, die jeweils von 0 bis 2 gehen. Oder halt eine Schleife von 0 bis 8 und die Indices selbst umrechnen.
Die CheckField-Funktion prüft ein bestimmtes Feld ob die zahl richtig gesetzt ist, das Feld[X,Y]. Zuerst wird die horizontale Spalte abgesucht, wenn die Zahl 2x drin steht wird die Funktion abgebrochen un das Ergebniss is FALSCH. Dann das selbe mit der vertikalen Spalte und dem MiniQuad. wenn alle felder durchgelaufen sind, un die Funktion nicht abgebrochen wurde heißt das, dass die Zahl richtig ist.
Die CheckAll-Funktion geht jetzt mit einer Schleife alle Felder durch ( 0 bis 80 ). Man hätte natürlich auch wieder 2 ( jeweils von 0 bis 8 ) nehmen können. Dann wird jedes einzellne Feld durch die CheckField-Funktion geprüft. Wenn einmal FALSCH zurückgegeben wird (das sodoku hat mind. eine falsche Zahl), dann ist das Sodoku nicht richtig gelöst und die Funktion wird mit FALSCH beendet. Wenn alle Felder ohne Abbruch duchlaufen wurden sind is das Sodoku richtig.
Man kann das ganze natürlich auch mit nem Haufen Boolean-Variablen berechnen, aber ich finde das ist Speicher- und Rechenzeitverschwendung.
Hier ma noch ne Möglichkeit wie man das mit den Summen machen kann (diesmal ohne
mod un
div, sofern es geht ;) ):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55:
| function CheckCols: Boolean; var x, y, sum: Integer; begin result := false; for x := 0 to 8 do begin sum := 0; for y := 0 to 8 do sum := sum + sudoku[x, y]; if sum <> 45 then exit; end; result := true; end;
function CheckRows: Boolean; var x, y, sum: Integer; begin result := false; for y := 0 to 8 do begin sum := 0; for x := 0 to 8 do sum := sum + sudoku[x, y]; if sum <> 45 then exit; end; result := true; end;
function CheckQuads: Boolean; var i, j, x, y: Integer; begin for i := 0 to 2 do for j := 0 to 2 do begin sum := 0; for x := 0 to 2 do for y := 0 to 2 do sum := sum + sudoku[i*3 + x, j*3 + y] if sum <> 45 then exit; end; result := true; end;
if CheckCols and CheckRows and CheckQuads then ShowMessage('Sudoku richtig gelöst'); |
€: wieder ungetestet!
MfG Bergmann.
Grimsch - Do 10.12.09 13:34
ok danke das sieht doch mal sehr gut aus :D
und nun bevor ich das nachprogrammiere: dies sind doch momentan nur funktionen, welche doch noch in eine procedure eingegeben werden müssen, da ich die richtigkeit ja per button klick überprüfen lassen will. nur wie füge ich diese funktionen dann in die procedure ein?
reicht da dies in die procedure einzufügen?
Delphi-Quelltext
1: 2:
| if checkcols=true and checkrows=true and checkquads=true then showmessage('Richtige Lösung'); |
hab das nun ausprobiert mit der 1. funktion allerdings kommt dann bei dieser zeile
Delphi-Quelltext
1:
| sum := sum + sudoku[x, y]; |
die Fehlermeldung: Incompatible types.
nur wo liegt nun der Fehler?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| function testspalte:boolean; var x, y, sum: integer; begin result:= false; for x:= 0 to 8 do begin sum:= 0; for y := 0 to 8 do sum:= sum+ sudoku[x,y]; if sum<>45 then exit; end; result:= true; end; |
Tilo - Do 10.12.09 16:35
Guck mal auf die Definition von sudoku[,].
Wenn dort string(Oder etwas anderes, was nicht kompatibel zu integer ist), dann kann es nicht klappen.
Du hast dann 2 Möglichkeiten:
a) Typenkovertierung vor Ort (z.B. strtoint(sudoku[x,y]))
b) Umdeklarieren.
bei b) musst Du dann aber den restlichen Code auch überarbeiten!
Bergmann89 - Do 10.12.09 21:19
Hey,
wenn du dein sudokuType genommen hast gehts nich weil du ja ein 3D Array aus Strings hast, meins is ein 2D Array aus Integer-Werten...
Und guck dir ma die letzten 2 Zeilen aus dem letzten Code an, da steht was in die ButtonClickProzedur rein muss. BTW: du musst einen Boolean nicht prüfen ob er wahr oder falsch ist. Kleines Bsp:
Delphi-Quelltext
1: 2: 3: 4: 5:
| var test: boolean; test := true; if test = true then ShowMessage('is wahr'); if test then ShowMessage('is wahr'); if not test then ShowMessage('is falsch'); |
MfG Bergmann.
Grimsch - So 13.12.09 11:51
ok danke für den tipp :)
nur weiß ich nicht wie ich diesen quelltext schreiben soll:
Delphi-Quelltext
1: 2: 3:
| sudoku[0,0,0]:='3'; sudoku[0,1,0]:='' ; sudoku[0,2,0]:=''; |
also bei den zahlen kann ich die zeichen ja einfach weglassen aber bei den stellen an denen nichts stehen soll geht das nicht. warum ich das da habe? damit ich per copy und paste schneller arbeiten kann um andere sudokus einzufügen :)
also ich hab an den stellen nun mit strtoint(w) gearbeitet wobei w:='' ist.
allerdings stellt sich mir nun das gleiche problem wie vorhin:
Delphi-Quelltext
1:
| sum:= sum+ sudoku[x,y]; |
da kommt wieder die fehlermeldung incompatible types. habe es bereits mit inttostr und strtoint vorm array ausprobiert geht aber alles nicht :S
ffgorcky - So 13.12.09 17:01
Also ich würde Deinen Anfang ja eher so schreiben:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| procedure TForm1.Button2Click(Sender: TObject); var i,j:integer; allesRichtig:Boolean; begin allesRichtig:=true; for i:=0 to 7 do for j:=0 to 8 do if (stringgrid1.cells[i,j]=stringgrid1.cells[i+1,j]) then allesRichtig:=false; if allesRichtig then showmessage('Richtig') else showmessage('Falsch'); end; |
Wobei Du damit ja nur immer die direkt nebeneinanderliegenden Zellen vergleichst - wenn also jeder zweite den gleichen Wert hat, merkt das Programm es nicht.
Grimsch - So 13.12.09 17:21
hmm naja aber das hilft mir nun aber nicht weiter bei meinem problem^^ trotzdem danke
und ich habe eben noch festgestellt dass strtoint(w) wobei w:='' ist doch nicht klappt >.< kommt dann beim starten eine fehlermeldung >,< jemand ne idee?^^
Bergmann89 - So 13.12.09 18:51
Hey,
wenn du's mit deinem Typ machen willst, dann musst du beim vergleich der Zellen einfach den String in ein Integer umwandeln. Da aber ein leerer String kein Integer werden kann musst du noch sowas wie n default-Wert einbauen, dafür gibts
StrToIntDef(sudoku[0,0,0], 0); wobei die letzte 0 der default-Wert ist.
Ansonsten schon wie oben vorgeschlagen, mach dir ne Liste aus mehreren sudokus, da kannst du einfach prüfen und erweitern wie du willst:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| type TSudoku = array[0..8, 0..8] of Integer;
var SudokuList: TList;
function LoadSudoku(FileName: String): TSudoku; begin end;
procedure Test; var neu: TSudoku; begin if OpenDialog.Execute then begin neu := LoadSudoku(OpenDialog.FileName); SudokuList.add(neu); end; end;
function GetSudokuFromList(index: Integer): TSudoku; begin result := TSudoku(SudokuList[index]); end; |
Das kann man alles noch weiter ausbauen. Und das gute is man kann immer mehr Sudokus hinzufügen, wenn du das übner das Array machst, dann geht das nich so gut. Das is aber durch die Zeiger in der Liste n bisl verzwickter als das Array, aber wenn man das einma verstanden hat is ganz easy^^
MfG Bergmann.
Grimsch - So 13.12.09 19:08
hmm das wäre doch aber auch einfach nur wieder ein anderer lösungsweg oder nicht? ich würde am liebsten nun aber einfach nur wissen was hier dran falsch ist:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46:
| function testspalte:boolean; var x, y, sum: integer; begin result:= false; for x:= 0 to 8 do begin sum:= 0; for y := 0 to 8 do sum:= sum+ sudoku[x,y]; if sum<>45 then exit; end; result:= true; end;
function testzeile:boolean; var x, y, sum: integer; begin result:=false; for x:= 0 to 8 do begin sum:=0; for y:= 0 to 8 do sum:= sum+ sudoku[x,y]; if sum<>45 then exit; end; result:= true; end;
function testquadrat:boolean; var p, q, x, y, sum:integer; begin result:= false; for p:= 0 to 2 do for q:= 0 to 2 do begin sum:= 0; for x:= 0 to 2 do for y:= 0 to 2 do sum:= sum + sudoku[p*3+x,q*3+y]; if sum<>45 then exit; end; result:= true; end; |
die fehlermeldungen kommen immer bei den zeilen von sum:= sum + sudoku[.....
würde diesen weg nun halt bevorzugen weil ich ihn verstanden habe.
zur info: habe mein array nun in ein Integer array umgewandelt.
Bergmann89 - So 13.12.09 23:00
Hey,
dann fehlt da der letzte Index vom array, da du ja ein 3D-Array hast un ich nur ein 2D-Array nutze: sum:= sum+ sudoku[x,y,aktivesSudoku];
Und ja es is am Ende nur ein anderer Lösungsweg mit der Liste, aber er ist meiner Meinung nach sinnvoller und effektiver. Aber is glaube auch besser, wenn de bei dem Weg bleibst, den du einma verstanden hast ^^ Die Listen kannst du ja probieren wenn du fertig bist un noch Lust hast was drann zu basteln ;)
MfG Bergmann
Grimsch - So 13.12.09 23:37
ok danke das scheint wohl schon zu klappen nur habe ich das problem dass nun wenn ich mein sudoku aufrufe an den stellen an denen nichts stehen sollte immer null steht.
Zitat: |
Da aber ein leerer String kein Integer werden kann musst du noch sowas wie n default-Wert einbauen, dafür gibts StrToIntDef(sudoku[0,0,0], 0); wobei die letzte 0 der default-Wert ist. |
da ich aber nun ein integer aus dem array gemacht habe geht das mit diesem StrToIntDef nicht und auch nicht mit IntToStrDef.
wäre super wenn ihr mir bei diesem problem nun noch helfen könntet^^ probleme über probleme :S und dienstag muss ich das spiel vorstellen >.<
Bergmann89 - Mo 14.12.09 00:03
Hey,
dann musst du dir wohl selbst eine passende Funktion schreiben ;)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| function IntToStrIfNotNull(int: Integer; def: String): String; begin if (int <> 0) then result := IntToStr(int) else result := def; end;
str := IntToStrIfNotNull(0, 'leer'); str := IntToStrIfNotNull(1, 'leer'); |
MfG Bergmann
Grimsch - Mo 14.12.09 00:21
hmm das funktioniert auch nicht oder ich hab was falsch gemacht^^
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| function IntToStrIfNotNull(int: Integer; def: String): String; begin if (int <> 0) then result := IntToStr(int) else result := def; end;
procedure TForm1.FormCreate(Sender: TObject); begin sudoku[0,0,0]:=3; sudoku[0,1,0]:=IntToStrIfNotNull(0, 'leer'); |
da kommt dann bei mir als fehlermeldung incompatible types integer und string.
außerdem verstehe ich die letzten beiden zeilen nicht ganz :S was genau soll das str darstellen?
ist das so richtig wie ich das eingesetzt hab? oder meintest du das noch anders?^^
Bergmann89 - Mo 14.12.09 01:37
Guck ma in einen Quelltext, irgendwo musst du ja die Zahlen in ein String umwandeln und dann irgendwo ausgeben. Und da benutzt du ja sicherlich die normale IntToStr-Funktion und er macht aus der 0 im array eine '0'. Also musst du nun die normale IntToStr-Funktion durch die IntToStrIfNotNull-Funktion ersetzen. Wenn du nun IntToStrIfNotNull(sudoku[x,y,active], ''); aufrufst, dann macht er aus der 0 im Array ein '', also einen LeerString un es steht nix anstatt der '0' da...
Grimsch - Mo 14.12.09 07:58
ok super danke hab ich nun auch hinbekommen :D
nun habe ich aber noch den fehler dass beim prüfen immer falsch steht... selbst nachdem ich überall einfach eine 5 reingeschrieben habe :S
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| procedure TForm1.Button2Click(Sender: TObject); begin if testspalte and testzeile and testquadrat then showmessage('Sie haben das Sudoku richtig gelöst!') else showmessage('Das Sudoku ist fehlerhaft.'); end; |
da vllt etwas falsch?
oder doch eher in der Funktion?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46:
| function testspalte:boolean; var x, y, sum: integer; begin result:= false; for x:= 0 to 8 do begin sum:= 0; for y := 0 to 8 do sum:= sum+ sudoku[x,y,a]; if sum<>45 then exit; end; result:= true; end;
function testzeile:boolean; var x, y, sum: integer; begin result:=false; for x:= 0 to 8 do begin sum:=0; for y:= 0 to 8 do sum:= sum+ sudoku[x,y,a]; if sum<>45 then exit; end; result:= true; end;
function testquadrat:boolean; var p, q, x, y, sum:integer; begin result:= false; for p:= 0 to 2 do for q:= 0 to 2 do begin sum:= 0; for x:= 0 to 2 do for y:= 0 to 2 do sum:= sum + sudoku[p*3+x,q*3+y,a]; if sum<>45 then exit; end; result:= true; end; |
Bergmann89 - Mo 14.12.09 18:01
Hey,
das einzige was mir aufgefallen is, is das testspalte und testzeile identisch sind, da musst du die schleifen tauschen.
Warum er jetzt aber aber immer false zurück gibt weiß ichnicht, musst du mal mit dem debuger durchgehen. Setzt dir n Haltepunkt (F5) auf die if-Zeile in deinem Button2Click. Und dann kannst du mit F7 jede Zeile einzelln durchgehen. Wenn du ne Variable markierst und Strg+F5 drückst kannst du sie dir in nem extra überwachungsfenster anzeigen lassen. So kannst du nachverfolgen wann, wo und warum er mit false raus springt.
MfG Bergmann.
Grimsch - Mo 14.12.09 18:37
hmm ich weiß nicht genau was du mit schleifen tauschen meintest hab das nun so verstanden dass ich einfach anstatt von for x... for y dann for y.... for x gemacht hab.
hab mal mein programm angehängt wäre super wenn du versuchen könntest den fehler zu finden. bin voll in bedrängnis :S muss das spiel morgen vorstellen und es kamen einfach immer mehr fehler >.<
Bergmann89 - Mo 14.12.09 20:00
Sry, aber ich hab auch wenig Zeit. Muss auch noch haufen HAs machen.
Un der Sinn der Sache is ja auch die Fehler selbst zu finden, so lernt man programmieren. Wenn du Probleme hast helf ich dir gern, aber bisl was musst du auch machen ;)
€: was mir grad noch einfällt, hast du das sodoku auch komplett gefüllt, bevor du die richtigkeit prüfst? wenn du das über die Summen machst muss jede Zelle einen Wert enthalten, sonst geht das nicht. Wenn du zwischendurch prüfen willst, dann musst du die andere Methode nehmen, die wir oben schon angesprochen haben...
MfG Bergmann.
p.s.: ja genau so hab ich das mit den schleifen gemeint, aber nur bei der einen funktion, bei der anderen nich...
Grimsch - Mo 14.12.09 20:56
ja ich habe jedes feld mit einer 5 gefüllt und auch einmal ein richtiges gelöstes sudoku verwendet
und nochmal zu dem anderen lösungsweg:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| type TSudoku = array[0..8, 0..8] of Integer;
var SudokuList: TList;
function LoadSudoku(FileName: String): TSudoku; begin end;
procedure Test; var neu: TSudoku; begin if OpenDialog.Execute then begin neu := LoadSudoku(OpenDialog.FileName); SudokuList.add(neu); end; end;
function GetSudokuFromList(index: Integer): TSudoku; begin result := TSudoku(SudokuList[index]); end; |
irgendwie seh ich das nur als aufrufen eines sudokus von einer datei oder so oder nicht?
eine überprüfung ob das sudoku richtig gelöst wurde ist das doch nicht oder? ich wüsste nich wo^^
Bergmann89 - Mo 14.12.09 23:44
Hey,
das war ja mein Vorschlag das Soduku zu laden.
Das hier [
http://www.delphi-forum.de/viewtopic.php?p=586399#586399] war der andere Lösungsweg. Da wird geprüft ob die Zahl doppelt in einer Reihe, Spalte oder Quad steht. Da musst du jetzt nur noch einbauen, das er die 0en außer acht lässt...
MfG Bergmann.
Grimsch - Di 15.12.09 19:33
ok vielen dank durch dich bin ich sehr gut vorran gekommen =) wird wohl noch trotz fehler am ende eine 2 werden hoffe ich mal^^ werd ich donnerstagb erfahren wie der lehrer es findet bzw fand
Bergmann89 - Di 15.12.09 23:43
OK, sag ma bescheid wenn du die Note weißt, interessiert mich auch ^^
MfG
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!