Autor |
Beitrag |
Avalon
Hält's aus hier
Beiträge: 8
Win 98, Win ME, Win XP
D7 Pers
|
Verfasst: Do 11.03.04 15:03
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:
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
_________________ All computers wait the same speed
|
|
Pascal
      
Beiträge: 155
Win 98, Win XP
Delphi 2005, Delphi 5
|
Verfasst: 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: 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
      
Beiträge: 42
D6 Pers
|
Verfasst: 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
      
Beiträge: 155
Win 98, Win XP
Delphi 2005, Delphi 5
|
Verfasst: 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 
Hält's aus hier
Beiträge: 8
Win 98, Win ME, Win XP
D7 Pers
|
Verfasst: 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
_________________ All computers wait the same speed
|
|
catweasel
      
Beiträge: 487
Erhaltene Danke: 1
Win 7 64bit
Delphi 7 Second Sedition V7.2
|
Verfasst: 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, 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
_________________ Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
|
|
|