greendesire - Fr 13.03.09 12:56
Titel: Doppelte Zahlen bei Sudoku vermeiden
Ich programmiere gerade ein Sudoku und will nun zufällig Zahlen in die Felder einfügen.
Mit folgender Prozudur habe ich es hinbekommen, dass sich in den senkrechten Spalten keine Zahlen doppeln.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| with Stringgrid1 do Begin for i:=0 to 8 do Begin menges[i]:=[]; for j:=0 to 8 do Begin Repeat cells[i,j]:=IntToStr(random(9)+1); zahl:=StrToInt(cells[i,j]); Until not (zahl in menges[i]); menges[i]:=menges[i]+[zahl]; end; end; |
;
Nun habe ich aber das Problem, dass bei den waagerechten Zeilen, dann immer doppelte Zahlen kommen. Ich habe schon versucht, mir einen Algorhytmus dazu auszudenken, aber leider habe ich damit eine Endlosschleife gebaut. Habe schon ganz viel versucht, das umzustellen, aber ich bekomme es leider nicht hin!
Bitte helft mir, wie kann ich überprüfen, dass in den waagerechten Zeilen keine doppelten Zahlen sind?
hier mein Versuch:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| with Stringgrid1 do Begin for k:=1 to 9 do Begin mengeW[k]:=[]; for j:=0 to 8 do Begin for i:=0 to 8 do Begin mengeW[k]:=[StrToInt(cells[i,j])]; Repeat cells[i,j]:=IntToStr(random(9)+1); kontrolle:=StrToInt(cells[i,j]); Until not (zahl in mengew[k]); mengeW[k]:=mengeW[k]+[kontrolle]; |
ich hatte mir gedacht, dass ich in einer weiteren Menge, die schon vorhandenen Zahlen speichere und dann die Zeile durchlaufe und neue Zahlen einfüge, aber jetzt fügt er ja auch Zahlen dort ein, wo eigentlich welche stehen, die schon in der Menge sind. Wie mache ich, dass er diese Felder übergeht?
Es wäre nett, wenn ihr mir helfen könntet, denn ich komme nicht mit meinen Grundkenntnissen weiter.
LG
Moderiert von
Gausi: Code- durch Delphi-Tags ersetzt
Moderiert von
Narses: Titel geändert.
P-A-L - Fr 27.03.09 10:31
Ich hab dein Problem jetzt inhaltlich noch nicht so sehr durchdacht, aber dass das ne Endlosschleife ist, liegt m.E. an den markierten Variablennamen:
greendesire hat folgendes geschrieben : |
Nun habe ich aber das Problem, dass bei den waagerechten Zeilen, dann immer doppelte Zahlen kommen. Ich habe schon versucht, mir einen Algorhytmus dazu auszudenken, aber leider habe ich damit eine Endlosschleife gebaut. Habe schon ganz viel versucht, das umzustellen, aber ich bekomme es leider nicht hin!
Bitte helft mir, wie kann ich überprüfen, dass in den waagerechten Zeilen keine doppelten Zahlen sind?
hier mein Versuch:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| with Stringgrid1 do Begin for k:=1 to 9 do Begin mengeW[k]:=[]; for j:=0 to 8 do Begin for i:=0 to 8 do Begin mengeW[k]:=[StrToInt(cells[i,j])]; Repeat cells[i,j]:=IntToStr(random(9)+1); kontrolle:=StrToInt(cells[i,j]); Until not (zahl in mengew[k]); mengeW[k]:=mengeW[k]+[kontrolle]; |
Moderiert von Gausi: Code- durch Delphi-Tags ersetzt |
Narses - Fr 27.03.09 12:02
Moin!
Wie wir
in diesem Thread bereits herausgefunden haben [
http://www.delphi-forum.de/viewtopic.php?t=91062], geht sowas nur mit
BACKTRACKING. Dabei ist die Grundidee, vorhergehende Entscheidungen wieder rückgängig machen zu können/müssen, wenn man in eine Sackgasse "gelaufen" ist. :idea: Eine typische Implementation setzt allerdings voraus, dass man
REKURSION verstanden hat. Vielleicht kommst du ja mit diesem Stichwort weiter.
Ich sehe allerdings nur einen begrenzten Sinn darin, bei dem bereits bekannten Problem "wie implementiert man Backtracking beim Sudoku" noch einen Thread auf zu machen, nur weil in dem "alten" keiner mehr geantwortet hat. Ob das jetzt mit einem "neuen" Thread besser wird, wage ich mal zu bezweifeln. Einen weiteren Thread hierzu werde ich schließen. :|
cu
Narses
Tilo - Fr 27.03.09 19:45
Es müsste auch ohne Backtracking gehen.
Für jedes Feld am Anfang eine Liste mit allen möglichen Zahlen erstellen. Wird in einem Feld eine Zahl gesetzt so werden in den Zellen jedes Unterelement(im klassischen 9x9 die kleinen 3x3 felder), sowie jeder Zeile und Spalte die entsprechende Zahl entfernt.
Moderiert von
Narses: Komplett-Zitat des letzten Beitrags entfernt