Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Randomize und Überprüfung
Avalon - Do 11.03.04 15:03
Titel: Randomize und Überprüfung
Wir haben im Informatikunterricht ein Memory programmiert, aber dieses tolle teil kann nicht mischen....sehr schön, nur gespiegelte Bilder. Der anspruch ließe sich durch Mischen steigern! Also wollen wir eine Random-Funktion einbauen...nur zu dumm, dass unser Lehrer auch nicht weiß, wie! Und dann müsste noch jede Karte garantiert 2 mal da sein, nicht mehr und nicht weniger. Kann jemand sagen, wie das geht??? Bitte!!!
Unser Quelltext:
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: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs , jpeg, ExtCtrls, StdCtrls, Buttons;
type TKarte = class(TImage) constructor create(owner:TWinControl; x,y: integer; ICO : String); public procedure turn(sender: TObject); procedure zeigeBild; procedure zeigeRueckseite; procedure click(sender: TObject); private isbild: Boolean; Bild: TPicture; Rueckseite: TPicture; bildname:string; end;
TForm1 = class(TForm) Rueckseite: TButton; Bild: TButton; closeButton: TBitBtn; procedure FormCreate(Sender: TObject); procedure BildClick(Sender: TObject); procedure RueckseiteClick(Sender: TObject); procedure closeButtonClick(Sender: TObject); procedure Playmemory (Sender:TObject);
private
public end;
var Form1: TForm1; IcoPath: String; implementation
{$R *.dfm}
constructor TKarte.create(owner:TWinControl; x,y: integer; ICO : String); begin inherited create(owner); parent:= Owner; Top:= y; Left:= x; AutoSize:= true; Rueckseite:=TPicture.create; Rueckseite.LoadFromFile('u:/delphi-programme/memory/bilder/icon0.ico'); Bild:=TPicture.Create; Bild.LoadFromFile('U:\Delphi-Programme\Memory\bilder\'+ico); Picture:=Rueckseite; IsBild:= false; onClick:=click; bildname:= ico; end;
procedure TKarte.turn; begin if isbild then Zeigerueckseite else zeigeBild; end;
procedure TKarte.zeigeRueckseite; begin hide; Picture:=Rueckseite; show; isbild:=false; end;
procedure TKarte.zeigeBild; begin hide; Picture:=Bild; show; isbild:=true; end;
procedure TForm1.BildClick(Sender: TObject); var i: integer; begin for i:=0 to Componentcount-1 do if Components[i] is TKarte then (Components[i] as TKarte).zeigeBild; end;
procedure TForm1.RueckseiteClick(Sender: TObject); var i: integer; begin for i:=0 to Componentcount-1 do if Components[i] is TKarte then (Components[i] as TKarte).zeigeRueckseite; end;
procedure TForm1.FormCreate(Sender: TObject); const IconZahl =20; Var x, y : integer; i : integer; icoName: String;
procedure NextPos(Var x, y: integer); begin if x >= 320 Then begin x := 0; y:= y+40; end; x:= x+40; end;
begin x:= 0; y:= 10; for i:= 1 to iconZahl do begin nextpos(x,y); IcoName:='icon' + intToStr(i)+'.ico'; TKarte.create(Form1, x, y, IcoName); end; for i:=iconZahl downto 1 do begin NextPos(x,y); IcoName:='icon' + intToStr(i)+'.ico'; TKarte.create(Form1, x,y, iconame); end; end;
procedure TForm1.closeButtonClick(Sender: TObject); begin close; end;
procedure TKarte.Click(Sender:TObject); begin Form1.Playmemory(Sender); if isbild=false then Turn(Sender); end;
procedure TForm1.playmemory(sender:TObject);
procedure Abraeumen; var i: integer; begin i:=0; while i < Form1.ComponentCount do if Form1.Components[i] is TKarte then if TKarte(Form1.Components[i] as TKarte).IsBild then TKarte(Form1.Components[i]).free else inc(i) else inc(i); end;
function zweiaufgedeckt: boolean; var i,n: integer; begin n:=0; for i:=0 to Form1.ComponentCount-1 do with TKarte(Components[i])do if Form1.Components[i] is TKarte then if IsBild then inc(n); zweiaufgedeckt:= n=2; end;
function gleicheBilder: boolean; var i: integer; n: string; begin n:=''; gleicheBilder:= false; for i:=0 to Form1.ComponentCount-1 do with TKarte(Form1.components[i]) do if Form1.Components[i] is TKarte then if IsBild then if BildName <> n then n:= BildName else gleicheBilder:= true; end;
procedure AlleRueckseite; var i: integer; begin for i:=0 to Form1.ComponentCount-1 do if Form1.Components[i] is TKarte then if TKarte(Form1.Components[i]).IsBild then TKarte(Form1.Components[i]).zeigeRueckseite; end;
begin if zweiaufgedeckt then if gleichebilder then Abraeumen else AlleRueckseite; end;
end. |
Danke im Vorraus !
Cu later
Pascal - Do 11.03.04 19:41
Ich würde im Create-Teil die Koordinaten zufällig vergeben, bzw den Koordinaten zufällige Karten geben. dafür würde ich die Kartennummern in eine Stringlist einlesen und dann statt der Laufvariablen eine zufällige Zeile als Kartennummer nehmen und diese dann löschen.
also so:
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:
| procedure TForm1.FormCreate(Sender: TObject); const IconZahl =5; Var x, y : integer; i,i2,rand : integer; icoName: String; List:TStringlist;
procedure NextPos(Var x, y: integer); begin if x >= 320 Then begin x := 0; y:= y+40; end; x:= x+40; end;
begin x:= 0; y:= 10; list:=TStringlist.create; for i:= 1 to iconZahl do list.Add(inttostr(i));
for i2:= 1 to iconZahl do begin randomize; rand:=random(list.count); i:=strtoint(list[rand]); list.Delete(rand); nextpos(x,y); IcoName:='icon' + intToStr(i)+'.ico'; TKarte.create(Form1, x, y, IcoName); end; for i:=iconZahl downto 1 do begin NextPos(x,y); IcoName:='icon' + intToStr(i)+'.ico'; TKarte.create(Form1, x,y, iconame); end;
list.Free; end; |
Seniman - Do 11.03.04 21:09
Hallo,
ich hatte mal ein ähnlichen Problem, als ich versucht habe ein Kartenspiel zu programmieren. Da sollten alle Karten auch genau ein mal da sein. Ich hab das dann so gelöst:
Erstelle ersteinmal alle Karten in geordneter Reihenfolge. Schreibe dann eine Prozedur, die zwei Karten zufällig auswählt und sie dann vertauscht. Diese Prozedur solltest du dann ca. 1000 mal ausführen, dann sind die Karten gut gemischt.
Grüße
Seniman
Pascal - Do 11.03.04 21:57
Das ist sicher auch eine Möglichkeit, aber ich glaube, die ist in dem Fall schwieriger. Die Frage ist ja wie man bei einer variablen Kartenzahl die zu vertauschende Karte herausfindet. Ich wüsste nur findcomponent().
oder diese Möglichkeit:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| procedure TForm1.Button1Click(Sender: TObject); var t,rnd:integer;list:TStringlist; begin list:=TStringlist.Create; for t:= 0 to componentcount-1 do if (components[t] is tKarte) then begin list.add(inttostr((components[t] as tKarte).top)); list.add(inttostr((components[t] as tKarte).left)); end; for t:= 0 to componentcount-1 do if (components[t] is tKarte) then begin randomize; rnd:=random(list.count div 2); (components[t] as tKarte).top:=strtoint(list[rnd*2]); (components[t] as tKarte).left:=strtoint(list[rnd*2+1]); list.Delete(rnd*2); list.Delete(rnd*2); end; list.Free;
end; |
Die vertauscht aber auch gleich alle auf einmal.
Vorteile zu meiner anderen Version ist, dass man diese auch wärend des Programms ausführen kann, dass man Diese Procedure einfach in das Programm einfügen kann und man nichts ersetzen muss und ich finde sie schaut professioneller aus,
was aber auch gleich ein Nachteil ist, denn bisher habe ich noch niemanden gefunden, der sie wirklich verstanden hat.
(Ich habe sie mal für nen Freund geschrieben, der auch so ne Art Memory programmiert hat)
Avalon - Fr 12.03.04 17:19
Vielen vielen Dank.
Jetzt muss ich das nur noch verstehen, einproggen und erklären können, und schon ist mit die 1+ sicher !
Thx very much !
Avalon
catweasel - Fr 12.03.04 21:08
Das gleiche Problem habe ich auch bei meinem Memory gehabt.. Ich hab es folgendermassen gelöst... (So grob in etwa)
Ausgangssituation: Bilderliste mit den Kartenotiven (keine doppelten Bilder)..
Erstellen eines Arrays in die jedes Bild zweimal eingetragen wird...
Es entste also ein array das doppelt so gross ist und jedes Bild zweimal enthält.
Ob man die Bilderliste zweimal hintereinander in einem Rutsch ablegt, (array = bild1,bild2,bild3,bild1,bild2,bild3) oder direkt jedes Bild zweimal (array = bild1,bild1,bild2,bild2,bild3,bild3) ist zunächst erstmal egal...
Dann wird das array per Zufall nurnoch umdortiert. Damit idt die Problemstellung ähnlich dem Ziehen von Lottozahlen ohne doppelte gezogene Zahlen...
(Dazu hatte ich hier auchmal was gepostet,
http://www.delphi-forum.de/viewtopic.php?t=20163 )
Danach hast du ein array mit zwei Exemplaren jedes Bildes in einer zufälligen Reihenfolge..
hierbei muss auch nur sovielmal gemischt werden wie Karten vorhanden sind, also nix mit random Schleifen "oft genug" aufgerufen werden müssen...
Ich kann dir mein Memory ja mal schicken..
Bei Interesse einfach ne PN mit emailadresse (hab immernoch keinen Webspace)
Catweasel
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!