Entwickler-Ecke
Sonstiges (Delphi) - Zufällige Zahlen für Sudoku erzeugen
Ottchen - Di 28.02.06 23:22
Titel: Zufällige Zahlen für Sudoku erzeugen
Ich habe jetzt erst das Spiel entdeckt, habe schon im Delphi-Forum gestöbert und konnte aber mit den Hinweisen noch nicht so viel anfangen.
Ich möchte in einer Tabelle (StringGrid) jede Zelle mit einer zufälligen Zahl beschreiben und dann auf Knopfdruck bzw. über ein PullDown-Menü einige Zahlen wegblenden, wenn das denn geht.
Also das Beschreiben habe ich ja noch hinbekommen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| procedure TForm1.BitBtn1Click(Sender: TObject); const cMax=9; var vi,vj:integer; vz1: Array[1..cMax] of Integer; begin with StringGrid1 do begin for vi:=1 to cMax do for vj:=1 to cMax do Cells[vi-1,vj-1]:=IntToStr(random(9)+1);
end;
end;
procedure TForm1.FormCreate(Sender: TObject); begin Randomize; end; |
Aber das erste Problem ist, dass manche Zufallszahlen doppelt vorkommen. Wie kann man das ändern?
Und wie kann man zufällig eine vorher bestimmte Zahl von Feldern ausblenden?
Wer kann mir helfen? Vielleicht gehe ich das Problem ja völlig falsch an...?
Ottchen
PS: Wie kann ich denn hier Quelltext als "Code" einfügen,, so dass er wie in anderen Beiträgen grün und eingerückt dargestellt wird?
Moderiert von
Christian S.: Delphi-Tags hinzugefügt
Moderiert von
Tino: Title geändert.Moderiert von
raziel: Topic aus Multimedia / Grafik verschoben am Fr 03.03.2006 um 18:52
JayEff - Mi 01.03.06 01:14
benutze [*delphi] *code* [/delphi] tags (ohne stern). das sieht dann so aus:
procedure hallo(du:String);
Zu deinem Problem: wenn du Zufallszahlen willst, bei denen keine doppelt vorkommt, musst du die benutzten in ein array speichern. beispiel:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| var zahlen:array of integer;
function gibmirneneueZufallszahl:integer; begin Result:=random(80)+1; while Result in zahlen do Result:=random(80)+1; SetLength(zahlen,length(zahlen)); zahlen[length(zahlen]-1]:=Result; end; |
so sollte das klappen...
Ottchen - Do 02.03.06 21:32
JayEff hat folgendes geschrieben: |
benutze [*delphi] *code* [/delphi] tags (ohne stern). das sieht dann so aus: procedure hallo(du:String);
Zu deinem Problem: wenn du Zufallszahlen willst, bei denen keine doppelt vorkommt, musst du die benutzten in ein array speichern. beispiel:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| var zahlen:array of integer;
function gibmirneneueZufallszahl:integer; begin Result:=random(80)+1; while Result in zahlen do Result:=random(80)+1; SetLength(zahlen,length(zahlen)); zahlen[length(zahlen]-1]:=Result; end; | so sollte das klappen... |
Danke erst einmal für die Antwort!
Wo und wie rufe ich die Funktion denn auf? Bewirkst du also mit deiner Funktion, dass man die Zahlen im Array abspeichert und schaut, ob eine Zahl in der Zelle schon vorhanden ist?
JayEff - Fr 03.03.06 02:28
Die Funktion macht nichts weiter als jede neue Zufallszahl ins Array speichern und sich so lange eine neue generieren lassen, bis eine raus kommt, die noch nicht im array ist. ACHTUNG sobald das array alle zahlen im Bereich 1-80 enthält, CRASHT DEIN PROGRAMM beim nächsten aufruf. Es läuft dann auf eine endlosschleife hinaus! das musst du beachten, und dem entsprechend verändern. z.B. muss natürlich das Array ab und zu geleert werden. etwa so:
SetLength(zahlen, 0); Dabei wird die Anzahl der Einträge im Array auf 0 gesetzt. Der rest sollte mit der Delphi OH und der Forumssuche lösbar sein.
alzaimar - Fr 03.03.06 08:13
Neee! Eine zufällige Folge von Zahlen 1..N macht man so: Erzeuge ein Array mit den Zahlen 1..N und mische es (am Besten nach Miller-Yates):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| Procedure ShuffleMillerYates (Var A :TArray); Var I, J, T : Integer;
begin For I := Low (A) to High (A) do begin J := I + Random (Length(A) - I); T := A[J]; A[J] := A[I]; A[I] := T; end; end; |
In einem Sudoku-Spiel darf in jeder Reihe, jeder Spalte und jedem 3x3 Quadranten die Zahl nur 1x vorkommen. Da kommt man mit dem Mischen aber nicht weit.
Du musst anders vorgehen: Ich habe es mit Mengen gemacht:
Sei
Z[i] die Menge der zur Verfügung stehenden Zahlen der Zeile #i,
S[j] die Menge der zur Verfugung stehenden Zahlen der spalte #j und
Q[x] die Menge der zur Verfügung stehenden Zahlen des Quadranten x.
Die Nr. des Quadranten an Zelle x,y wird so berechnet : q(x,y) = 3*(x div 3) + y div 3;
Zelle i,j kann dann nur Zahlen annehmen, die in Z[i], S[j] und Q[q(i,j)] enthalten sind, also in der Schnittmenge der drei Mengen. Damit ist die Lösung ganz einfach.
JayEff - Fr 03.03.06 14:38
alzaimar hat folgendes geschrieben: |
| Neee! Eine zufällige Folge von Zahlen 1..N macht man so:[...] |
Ööööhm ja. Aber meine klappt genauso. Oder in deinen Worten: "NE! Deine is falsch! Nur meine is richtig!" Verstehst du worauf ich hinaus will? ;>
Also ich hab nur auf seine Frage geantwortet ^^
alzaimar - Fr 03.03.06 15:31
JayEff hat folgendes geschrieben: |
Ööööhm ja. Aber meine klappt genauso. ... |
Ööööhm nö:
Delphi-Quelltext
1:
| For i:=1 to 82 do gibmirneneueZufallszahl; |
hängt, weil Du nur 80 (N) Zahlen erzeugen kannst, bei Frage nach der N+1. Zufallszahl ballert es eben,.
Und trotzdem macht man das so nicht, weil die Performance in den Keller geht...
Manchmal ist meine Ausdrucksweise aber wohl 'zu persönlich'. War nicht so gemeint.
JayEff - Sa 04.03.06 00:27
alzaimar hat folgendes geschrieben: |
hängt, weil Du nur 80 (N) Zahlen erzeugen kannst, bei Frage nach der N+1. Zufallszahl ballert es eben,.[*1]
Und trotzdem macht man das so nicht, weil die Performance in den Keller geht...[*2]
|
1: Das hatte ich bereits erwähnt und bin davon ausgegangen, dass er das selbst abfangen kann ;>
JayEff hat folgendes geschrieben: |
ACHTUNG sobald das array alle zahlen im Bereich 1-80 enthält, CRASHT DEIN PROGRAMM beim nächsten aufruf. Es läuft dann auf eine endlosschleife hinaus! das musst du beachten, und dem entsprechend verändern. z.B. muss natürlich das Array ab und zu geleert werden. etwa so:
|
2: bei n=9 zahlen? Öööhm nö. ^^ *auch nich bei n=9*9 zahlen, wies in nem Sudoku üblich is. Auch erst bei n=10^4 oder so ^^
Einigen wir uns drauf: beides geht prima in diesem Beispiel.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 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!