Entwickler-Ecke

Multimedia / Grafik - Black Jack Programm


Disco-tru - Di 09.12.08 17:35
Titel: Black Jack Programm
Hey Leute!

Ich habe von meinem Professor das Projekt black jack zugeschrieben bekommen, jetzt weiß ich allerdings nicht mehr weiter....

Problem:

Computer lädt die Bilder nicht richtig
Die Karten sind unter "wert"+"farbe" gespeichert (bsp. 2c für Karo2)
ab Wert 10 ist 11 für bube usw., wert wird in der If schleife zum schluss wieder vermindert



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:
unit Game_Unit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;

type
  TKarten = Record
   bild : TBitmap;
   wert : integer;
   benutzt : boolean;
  end;
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Image1: TImage;
    Image2: TImage;
    Image3: TImage;
    Image4: TImage;
    Image5: TImage;
    Image6: TImage;
    Image7: TImage;
    Image8: TImage;
    Image9: TImage;
    Image10: TImage;
    start_btn: TButton;
    karte_btn: TButton;
    stand_btn: TButton;
    Label3: TLabel;
    Label4: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure start_btnClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  Karte: array [1..52of TKarten;
  WertComp, WertSpieler: integer;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
randomize;
WertComp:= 0;
end;

procedure TForm1.start_btnClick(Sender: TObject);
var ran:integer;
    i,j,count : integer;
    farbstr,cardstr: string;
    bmp: TBitmap;
begin
count:=1;
 for i:= 2 to 14 do
 begin
 cardstr:= inttostr(i);
  for j:= 1 to 4 do
  begin
   case j of
    1: farbstr:='c';
    2: farbstr:='d';
    3: farbstr:='h';
    4: farbstr:='s';
   end;
  bmp:= TBitmap.Create;
  bmp.LoadFromFile('C:\Users\Günther\Desktop\Projekt\Cards\'+cardstr+farbstr+'.bmp');
  Karte[count].benutzt:= false;
  Karte[count].bild:= bmp;
  bmp.free;
   if i < 10 then Karte[count].wert:=i;
   if i > 10 then Karte[count].wert:=10;
   if i = 14 then Karte[count].wert:=11;
  inc(count);
  end;
  label3.caption:= inttostr(count)
 end;
ran:= random(52)+1;
 if Karte[ran].benutzt then start_btnClick(Sender)
    else WertComp:= WertComp + Karte[ran].wert;
 image1.Picture.Bitmap:= Karte[ran].bild;
 Karte[ran].benutzt := true;
// image2.Picture.Bitmap:= Karte[6].bild;
label3.caption:= inttostr(ran);
end;

end.



Freue mich schon auf Hilfe,

lg, Günther


Disco-tru - So 14.12.08 15:41

ach bitte^^

kann mir nicht vl. jemand helfen, weiß nicht weiter ^^?

lg


jaenicke - So 14.12.08 16:14

Du kannst ruhig schon nach 24 Stunden an deine Frage erinnern, nur früher ist es nicht erlaubt. ;-)

Was mir als allererstes auffällt ist dein fester Pfad, auf einem anderen Rechner würde der ja anders lauten. Wie es besser geht steht hier, du solltest das Projektverzeichnis auslesen und als Grundlage nehmen:
http://www.delphi-library.de/viewtopic.php?p=499701

user profile iconDisco-tru hat folgendes geschrieben Zum zitierten Posting springen:
Problem:

Computer lädt die Bilder nicht richtig
Inwiefern? Was passiert denn (nicht)?


Disco-tru - So 14.12.08 16:52

ok, du hast recht

damit fängts mal an...
ich versteh allerdings deine erklärung zum pfad überhaupt nicht :(

wie müsste ich es in diesem fall machen?

lg


jaenicke - So 14.12.08 16:55

Was ist daran misszuverstehen? :nixweiss:
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Worum es geht ist folgendes. Angenommen, man möchte die Konfigurationsdatei im selben Verzeichnis wie das Programm auslesen:
Falsch:

Delphi-Quelltext
1:
  Memo1.Lines.LoadFromFile('config.ini');                    

Richtig:

Delphi-Quelltext
1:
  Memo1.Lines.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'config.ini');                    
Das Speichern im eigenen Verzeichnis ist sowieso nicht so gut, aber dazu sage ich am Ende noch etwas.
Der Pfad der eigenen Anwendung ist ExtractFilePath(ParamStr(0)) und das setzt du an die Stelle deines festen Pfades.

Es wäre hilfreicher, wenn du konkrete Fragen stellen würdest zu etwas was du daran nicht verstehst. ;-)


Disco-tru - So 14.12.08 17:49

bmp.LoadFromFile(ExtractFilePath(ParamStr(0))+'cards\'+cardstr+farbstr+'.bmp');


jaenicke - So 14.12.08 17:51

Du hängst doch die einzelnen Teile des Pfades aneinander und genauso machst du auch das:

Delphi-Quelltext
1:
bmp.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Cards\' + cardstr + farbstr + '.bmp');                    


Disco-tru - So 14.12.08 17:56

so, nun funktionert das mal, vielen dank!

allerdings sehe ich jetzt, dass überhaupt keine bilder geladen werden...

habs projekt mal in anhang gesetzt


jaenicke - So 14.12.08 18:04

Du entfernst ja auch alle Bilder nach dem Laden sofort wieder aus dem Speicher:
Zitat:

Delphi-Quelltext
1:
  bmp.free;                    
Wie wäre es so?

Delphi-Quelltext
1:
2:
3:
  Karte[count].bild := TBitmap.Create;
  Karte[count].bild.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Cards\' + cardstr + farbstr + '.bmp');
  Karte[count].benutzt := false;
Irgendwo müsstest du die Karten auch wieder aus dem Speicher entfernen. Deshalb wäre es sinnvoller das Laden in FormCreate zu machen statt jedesmal beim Klicken auf den Button. Dann kannst du die in FormDestroy auch wieder aus dem Speicher entfernen und lädst die nicht x-mal neu. ;-)


Disco-tru - Mo 15.12.08 11:23

Ok, jetzt funktioniert das mal :)

aber die

procedure Karteermitteln(wer:integer); (im interface)

[DCC Fehler] Game_Unit.pas(35): E2065 Ungenügende Forward- oder External-Deklaration: 'TForm1.Karteermitteln'

Prozedur sieht so aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure Karteermitteln(wer:integer);
begin
ran:= random(52)+1;
 if Karte[ran].benutzt then Karteermitteln(wer)
    else
    begin
     case wer of
      0: WertComp:= WertComp + Karte[ran].wert;
      1: WertSpieler:= WertSpieler + Karte[ran].wert;
      end;
    Karte[ran].benutzt := true;
    end;
end;


jaenicke - Mo 15.12.08 13:39

Vergleich mal die beiden Zeilen:

Delphi-Quelltext
1:
2:
procedure TForm1.start_btnClick(Sender: TObject);
procedure Karteermitteln(wer:integer);
Fällt dir was auf? Das TForm1. fehlt, Delphi ordnet die Prozedur also nicht deinem Formular zu, oben im Formular ist die aber deklariert und deshalb bringt Delphi beides nicht in Zusammenhang. Und deshalb fehlt Delphi die für das Formular oben deklarierte (angekündigte) Prozedur.

Oben bei der Deklaration ist das ohne TForm1. richtig, denn du schreibst es ja in die Deklaration von TForm1. Bei der Implementierung fehlt die Angabe dann.

Delphi-Quelltext
1:
2:
procedure TForm1.Karteermitteln(wer:integer);
begin


baka0815 - Mo 15.12.08 13:45

Du könntest dir natürlich auch für jede "Farbe" eine TImageList machen.


Delphi-Quelltext
1:
2:
var
  Karo, Piek, Herz, Kreuz: TImageList;


und dir dann ImageMap und Index merken. Index 1-10 sind dann die Zahl-Karten, 11 Bube, etc.
Dann hast du die Bilder in deinen Ressource-Daten und brauchst dich nicht um Pfade kümmern. Nachteil: Die EXE wird recht groß.


Disco-tru - Mo 15.12.08 14:25

so, und jetzt hab ich ein problem ^^

der computer zeigt keinen fehler, allerdings kann ich das projekt nichtmehr kompilieren, keine ahnung warum....

ich setz das prog mal in den anhang...

EDIT:

notebook rebootet, problem weg!


Disco-tru - Di 16.12.08 19:32

soooooooo... im großen und ganzen funktioniert das programm jetzt ;-)

allerdings hab ich noch das problem, dass ich nicht weiß, wie ich mit den assen vorgehe:

denn die ASS zählt entweder für 11, oder im falle des überschreitens des wertes 21 für 1
also muss ich eine abfrage einbauen, falls eine ass gezogen wird, dass diese auch für 1 zählen kann....

ich habe allerdings 0 ahnung wie ^^


lg


baka0815 - Mi 17.12.08 17:04


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
var
  Hand: array of TKarte;

function BerechneSumme: Byte;
var
  I: Integer;
  Wert: Byte;
begin
  Result := 0;
  for I := 0 to Length(Hand) - 1 do
  begin
    Wert := Hand.Wert;
    // Wenn es ein Ass ist, dann 11 oder 1 als Wertigkeit
    if (Wert  = 11and (Result + Wert  > 21then Wert := 1;    

    Result := Result + Wert;
  end;
end;


Ungetestet, aber so oder ähnlich sollte es klappen.


Disco-tru - Do 18.12.08 09:58

ja schon klar, aber wie frage ich ab ob es ein ass ist, bzw. wieviele assen schon verwendet wurden?

bsp: AAA ergibt ja den wert 13 , kommt ein bube bleibts bei 13....


baka0815 - Do 18.12.08 12:26

Kannst dir ja die Werte auf der Hand vorsortieren, das sollte schon mal ein bisschen helfen.

Btw. AA => Black Jack, AAA ist also sinnlos ;)

A7A wären ja 19, A7AB sind dann ebenfalls 19. Sortiert wäre das 7BAA. Dann würde er beim ersten Ass schon merken, dass die Grenze überschritten ist.

Ansonsten könntest du einfach alle Punkte auf der Hand addieren ungeachtet der Asse. Wenn du nun mehr als 21 Punkte hast, ziehst du für das erste Ass 10 Punkte ab (1 statt 11 Punkte). Wenn du dann noch immer mehr als 21 Punkte und noch ein weiteres Ass auf der Hand hast, dann ziehst du wieder 10 Punkte ab.


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:
var
  Hand: array of TKarte;

function BerechneSumme: Byte;
var
  I: Integer;
  Wert: Byte;
  AnzahlAsse: Byte;
begin
  Result := 0;
  AnzahlAsse := 0;

  // Zuerst prüfen, wieviele Asse insgesamt vorkommen
  for I := 0 to Length(Hand) - 1 do
  begin
    if (Hand[I].Wert) = 11 then Inc(AnzahlAsse);
    Inc(Wert, Hand[I].Wert);
  end;

  {
    Sonderfall 2 Asse:
    Wenn die Hand aus 2 Assen besteht, zählt dies
    auch als Black Jack
  }

  if (Length(Hand) = 2and (AnzahlAsse = 2then
  begin
    Result := 21;
    Exit;
  end;

  {
    Wenn mehr als 21 Punkte auf der Hand sind, 
    aber Asse vorhanden, dann können diese als
    1 statt 11 Punkte zählen, also so lange
    pro Ass 10 Abziehen bis ein Wert unter 21
    erreicht ist oder keine Asse mehr vorhanden.
  }

  while (Wert > 21and (AnzahlAsse > 0do
  begin
    Dec(Wert, 10);
    Dec(AnzahlAsse, 1);
  end;

  Result := Wert;
end;


Disco-tru - Do 18.12.08 14:27

AA ist der wert 12 ;-), da eine Ass den wert 11 oder 1 hat ^^

A + 10/J/Q/K ist ein black jack :P

aja, übergibt man also der variable Hand jede karte die jeweils der Spieler und der Computer erhalten haben?


sorry für klugscheisserei ;-)


baka0815 - Do 18.12.08 17:17

Hand ist in meinem Beispiel ja als array of TKarte definiert und beinhaltet sämtliche Karten die der Spieler auf der Hand hat.

In TKarte sind dann eben die Werte der Karte (1-11), sowie die "Farbe" (Pik, Kreuz, ...) und evtl. das Bild der Karte gespeichert.

Ich kenne die Black Jack Regeln nun nicht genau, muss ich zugeben, sondern nur von 17+4 (oder zumindest so, wie "wir" es immer gespielt haben :)), wobei ich davon ausgegangen bin, dass diese "zwei Asse = 21" Regel auch beim Black Jack angewendet würde. Na gut, wieder was gelernt. :)

Dann kannst du den Teil der Prüfung auf 2xA = 21 einfach rausnehmen.

Es ist eine Hand-Variable pro Spieler angedacht. Schöner ist es dann 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:
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:
type TFarbe = (Kreuz, Pik, Herz, Karo);
type TKarte = record
  Wert: 1..11;
  Farbe: TFarbe;
  Bild: TImage;
end;
type THand = array of TKarte;

var
  SpielerHand,
  GeberHand: THand;
  SpielerWert, 
  GeberWert: Byte;

function BerechneSumme(Hand: THand, Sonderbehandlung2Asse: Boolean = False): Byte;
var
  I: Integer;
  Wert: Byte;
  AnzahlAsse: Byte;
begin
  Result := 0;
  AnzahlAsse := 0;

  // Zuerst prüfen, wieviele Asse insgesamt vorkommen
  for I := 0 to Length(Hand) - 1 do
  begin
    if (Hand[I].Wert) = 11 then Inc(AnzahlAsse);
    Inc(Wert, Hand[I].Wert);
  end;

  {
    Sonderfall 2 Asse:
    Wenn die Hand aus 2 Assen besteht, zählt dies
    auch als Black Jack
  }

  if Sonderbehandlung2Asse and (Length(Hand) = 2and (AnzahlAsse = 2then
  begin
    Result := 21;
    Exit;
  end;

  {
    Wenn mehr als 21 Punkte auf der Hand sind, 
    aber Asse vorhanden, dann können diese als
    1 statt 11 Punkte zählen, also so lange
    pro Ass 10 Abziehen bis ein Wert unter 21
    erreicht ist oder keine Asse mehr vorhanden.
  }

  while (Wert > 21and (AnzahlAsse > 0do
  begin
    Dec(Wert, 10);
    Dec(AnzahlAsse, 1);
  end;

  Result := Wert;
end;

function KarteGeben(Hand: THand, Karte: TKarte): Byte;
begin
  SetLength(Hand, Length(Hand)+1);
  Hand[Length(Hand)-1] := Karte;
  Result := BerechneSumme(Hand);
end;

begin
  [...]
  SpielerWert := KarteGeben(SpielerHand, {zufällige Karte});  
  // Spieler Wert in GUI anzeigen
  [...]
end;


btw. auf Wikipedia [http://de.wikipedia.org/wiki/Black_Jack] steht: "Asse zählen nach Belieben ein oder elf Punkte.", also kann man danach die Wertigkeit nicht automatisch berechnen, sondern müsste dem Spieler die Möglichkeit geben, selber zu entscheiden ob er mit 2 Assen nun 12 oder 2 Punkte auf der Hand hat.


jaenicke - Do 18.12.08 17:26

user profile iconbaka0815 hat folgendes geschrieben Zum zitierten Posting springen:
btw. auf Wikipedia [http://de.wikipedia.org/wiki/Black_Jack] steht: "Asse zählen nach Belieben ein oder elf Punkte.", also kann man danach die Wertigkeit nicht automatisch berechnen, sondern müsste dem Spieler die Möglichkeit geben, selber zu entscheiden ob er mit 2 Assen nun 12 oder 2 Punkte auf der Hand hat.
Es reicht auch, die beste Variante anzunehmen. :lol:
Wenn ich drei Asse und eine 8 habe, dann werde ich bestimmt nicht sagen, nein, das sind nicht 11 + 1 + 1 + 8 = 21, sondern 1 + 1 + 1 + 8 = 11. ;-)


baka0815 - Do 18.12.08 18:17

Meine Funktion liefert ja die "beste" Variante.

Möglich wäre es natürlich, weiß ja nicht, wie der Rest deines Programms aussieht, die Hand als Objekt abzubilden. Dann könntest du eine Hand.Add(Karte) Methode erstellen, die der Hand eine Karte hinzufügt und eine Hand.Wert Funktion, die die aktuelle Wertigkeit des Blatts auf der Hand liefert.


Disco-tru - Di 03.03.09 16:09

So, ich hab die Datei erst jetzt aktualisiert, nachdem ich lange keine Zeit hatte, weiterzuarbeiten...

Folgende Probleme:
- Manchmal (Möglicherweise wenn ich eine Ass ziehe) und auf Stand klicke, initialisiert der PC neu...

der Quelltext dazu: (vielleicht kann man den noch ein wenig vereinfachen, bitte um Tips ;-) )


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:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
unit Game_Unit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;

type
  TKarten = Record
   bild : TBitmap;
   wert : integer;
   benutzt : boolean;
  end;
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Image1: TImage;
    Image2: TImage;
    Image3: TImage;
    Image4: TImage;
    Image5: TImage;
    Image6: TImage;
    Image7: TImage;
    Image8: TImage;
    Image9: TImage;
    Image10: TImage;
    start_btn: TButton;
    karte_btn: TButton;
    stand_btn: TButton;
    lblpc: TLabel;
    lblsp: TLabel;
    btn_neu: TButton;
    SiegeComp: TLabel;
    SiegeSpiel: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure start_btnClick(Sender: TObject);
    procedure Karteermitteln(wer:integer);
    procedure karte_btnClick(Sender: TObject);
    procedure stand_btnClick(Sender: TObject);
    procedure btn_neuClick(Sender: TObject);
    procedure init;
    procedure labels;
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  Karte: array [1..52of TKarten;
  WertComp,WertSpieler,ran,imgstelle,imgstelle2,Swin,Cwin,AssCom,Assspiel: integer;
  Ass_used: boolean;

implementation

{$R *.DFM}

procedure TForm1.btn_neuClick(Sender: TObject);
begin
 cwin:=0;
 swin:=0;
 labels;
 init;
end;

procedure TForm1.FormCreate(Sender: TObject);
var i,j,count : integer;
    farbstr,cardstr: string;
begin
init;
randomize;
count:=1;
cwin:=0;
swin:=0;
 for i:= 2 to 14 do
 begin
 cardstr:= inttostr(i);
  for j:= 1 to 4 do
  begin
   case j of
    1: farbstr:='c';
    2: farbstr:='d';
    3: farbstr:='h';
    4: farbstr:='s';
   end;
  Karte[count].bild := TBitmap.Create;
  Karte[count].bild.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Cards\' + cardstr + farbstr + '.bmp');
  Karte[count].benutzt := false;
   if i < 10 then Karte[count].wert:=i;
   if i >= 10 then Karte[count].wert:=10;
   if i = 14 then Karte[count].wert:=11;
  inc(count);
  end;
 end;
end;

procedure TForm1.stand_btnClick(Sender: TObject);
begin
 Karteermitteln(0);
  case imgstelle2 of
   7: image7.Picture.Bitmap:= Karte[ran].bild;
   8: image8.Picture.Bitmap:= Karte[ran].bild;
   9: image9.Picture.Bitmap:= Karte[ran].bild;
   10: image10.Picture.Bitmap:= Karte[ran].bild;
  end;
 inc(imgstelle2);
 karte_btn.Enabled:=false;
 lblpc.caption:= inttostr(wertcomp);
 if (wertcomp < 16or (wertcomp<wertspieler) then
  stand_btnClick(Sender);
 if (wertcomp > 15and (wertcomp>=wertspieler) then
  begin
    if wertcomp <= 21  then
     begin
      showmessage('Der Computer hat mit dem Wert '+inttostr(wertcomp)+' gewonnen!');
      inc(Cwin);
     end
    else
     begin
      if asscom > 0 then
       begin
        dec(wertcomp, 10);
        dec(asscom);
        lblpc.Caption:= inttostr(wertcomp);
       end
      else
       begin
        showmessage('Der Computer hat mit dem Wert '+inttostr(wertcomp)+' verloren!');
        inc(Swin);
       end;
     end;
  init;
  end;
labels;
end;

procedure TForm1.start_btnClick(Sender: TObject);
begin
WertComp:= 0;
WertSpieler:= 0;
karte_btn.Enabled:=true;
stand_btn.Enabled:=true;
start_btn.Enabled:=false;
  Karteermitteln(0);
   image1.Picture.Bitmap:= Karte[ran].bild;
  Karteermitteln(1);
   image2.Picture.Bitmap:= Karte[ran].bild;
  Karteermitteln(1);
   image3.Picture.Bitmap:= Karte[ran].bild;
lblsp.caption:= inttostr(wertspieler);
lblpc.caption:= inttostr(wertcomp);
 if wertspieler = 21 then
  begin
   showmessage('Der Spieler hat einen Black Jack! GEWONNEN! ');
   inc(Swin);
   init;
   labels;
  end;
end;

procedure TForm1.Karteermitteln(wer:integer);
begin
ran:= random(52)+1;
 if Karte[ran].benutzt then Karteermitteln(wer)
    else
    begin
     case wer of
      0begin
          WertComp:= WertComp + Karte[ran].wert;
          if (ran<=52and (ran>48)   then
          inc(asscom);
         end;
      1begin
          WertSpieler:= WertSpieler + Karte[ran].wert;
          if (ran<=52and (ran>48)   then
          inc(assspiel);
         end;
      end;
    Karte[ran].benutzt := true;
    end;
end;

procedure TForm1.karte_btnClick(Sender: TObject);
begin
 Karteermitteln(1);
  case imgstelle of
  4: image4.Picture.Bitmap:= Karte[ran].bild;
  5: image5.Picture.Bitmap:= Karte[ran].bild;
  6: image6.Picture.Bitmap:= Karte[ran].bild;
  end;
 lblsp.caption:= inttostr(wertspieler);
 inc(imgstelle);
 if wertspieler = 21 then
  begin
   showmessage('Der Spieler hat einen Black Jack! GEWONNEN! ');
   inc(Swin);
   init;
  end;
 if wertspieler > 21 then
  begin
  if assspiel>0 then
   begin
    dec(wertspieler, 10);
    dec(assspiel);
    lblsp.Caption:= inttostr(wertspieler);
   end
  else
  begin
   showmessage('Der Spieler hat mit dem Wert '+inttostr(wertspieler)+' verloren!');
   inc(Cwin);
   init;
  end;
 end;
labels;
end;

procedure TForm1.init;
var i: integer;
begin
  for i := 1 to 52 do
  karte[i].benutzt:= false;
  asscom:=0;
  assspiel:=0;
  karte_btn.Enabled:=false;
  stand_btn.Enabled:=false;
  start_btn.Enabled:=true;
  imgstelle2:=7;
  WertComp:= 0;
  WertSpieler:= 0;
  imgstelle:= 4;
  lblpc.Caption:= '';
  lblsp.Caption:= '';
  image1.Picture.Bitmap.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Cards\ruecken.bmp');
  image2.Picture.Bitmap.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Cards\ruecken.bmp');
  image3.Picture.Bitmap.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Cards\ruecken.bmp');
  image4.Picture.Bitmap.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Cards\ruecken.bmp');
  image5.Picture.Bitmap.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Cards\ruecken.bmp');
  image6.Picture.Bitmap.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Cards\ruecken.bmp');
  image7.Picture.Bitmap.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Cards\ruecken.bmp');
  image8.Picture.Bitmap.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Cards\ruecken.bmp');
  image9.Picture.Bitmap.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Cards\ruecken.bmp');
  image10.Picture.Bitmap.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Cards\ruecken.bmp');
end;

procedure TForm1.labels;
begin
   SiegeComp.Caption:= 'Gewonnen: '+inttostr(Cwin);
   SiegeSpiel.Caption:= 'Gewonnen: '+inttostr(Swin);
end;

end.


jaenicke - Di 03.03.09 16:30

Der Stacküberlauf kann eigentlich auf den ersten Blick nur hier verursacht werden:

Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.Karteermitteln(wer:integer);
begin
ran:= random(52)+1;
 if Karte[ran].benutzt then Karteermitteln(wer)
Ich vermute einmal, dass benutzt bei allen Karten True ist, und dann gibts ne Endlosrekursion. Und auch, wenn z.B. noch eine Karte nicht benutzt ist, kann die genau nicht getroffen werden...

So ist das keine gute Idee. Entweder schaut man wieviele Karten noch da sind, zieht eine entsprechende Zahl und geht die möglichen Zahlen durch, nimmt also die x-te mögliche dann, oder man nimmt gleich die schon genutzten raus.

In jedem Fall musst du eine Abbruchbedingung benutzen, zudem kannst du auch einfach eine Schleife statt Rekursion benutzen.


Disco-tru - Di 17.03.09 16:01

habe nun oben den sourcecode geupdatet, habe allerdings noch dass problem, dass mir der computer manchmal (vermutlich hängt es damit zusammen, wenn der computer assen zieht), dass er sich selbst neu initialisiert und keinen gewinner ausgibt... dies passiert natürlich wenn ich auf den Stand_btn klicke...

woran könnte das liegen?

lg