Autor Beitrag
Disco-tru
Hält's aus hier
Beiträge: 12



BeitragVerfasst: Di 09.12.08 17:35 
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


ausblenden volle Höhe 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 Threadstarter
Hält's aus hier
Beiträge: 12



BeitragVerfasst: So 14.12.08 15:41 
ach bitte^^

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

lg
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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:
www.delphi-library.d...ewtopic.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 Threadstarter
Hält's aus hier
Beiträge: 12



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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:
ausblenden Delphi-Quelltext
1:
  Memo1.Lines.LoadFromFile('config.ini');					

Richtig:
ausblenden 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 Threadstarter
Hält's aus hier
Beiträge: 12



BeitragVerfasst: So 14.12.08 17:49 
bmp.LoadFromFile(ExtractFilePath(ParamStr(0))+'cards\'+cardstr+farbstr+'.bmp');


Zuletzt bearbeitet von Disco-tru am So 14.12.08 17:52, insgesamt 2-mal bearbeitet
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 14.12.08 17:51 
Du hängst doch die einzelnen Teile des Pfades aneinander und genauso machst du auch das:
ausblenden Delphi-Quelltext
1:
bmp.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Cards\' + cardstr + farbstr + '.bmp');					
Disco-tru Threadstarter
Hält's aus hier
Beiträge: 12



BeitragVerfasst: 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
Einloggen, um Attachments anzusehen!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 14.12.08 18:04 
Du entfernst ja auch alle Bilder nach dem Laden sofort wieder aus dem Speicher:
Zitat:
ausblenden Delphi-Quelltext
1:
  bmp.free;					
Wie wäre es so?
ausblenden 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 Threadstarter
Hält's aus hier
Beiträge: 12



BeitragVerfasst: 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:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 15.12.08 13:39 
Vergleich mal die beiden Zeilen:
ausblenden 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.
ausblenden Delphi-Quelltext
1:
2:
procedure TForm1.Karteermitteln(wer:integer);
begin
baka0815
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 489
Erhaltene Danke: 14

Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
BeitragVerfasst: Mo 15.12.08 13:45 
Du könntest dir natürlich auch für jede "Farbe" eine TImageList machen.

ausblenden 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 Threadstarter
Hält's aus hier
Beiträge: 12



BeitragVerfasst: 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!
Einloggen, um Attachments anzusehen!
Disco-tru Threadstarter
Hält's aus hier
Beiträge: 12



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 489
Erhaltene Danke: 14

Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
BeitragVerfasst: Mi 17.12.08 17:04 
ausblenden 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 Threadstarter
Hält's aus hier
Beiträge: 12



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 489
Erhaltene Danke: 14

Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
BeitragVerfasst: 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.

ausblenden volle Höhe 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 Threadstarter
Hält's aus hier
Beiträge: 12



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 489
Erhaltene Danke: 14

Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
BeitragVerfasst: 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:

ausblenden volle Höhe 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 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 18.12.08 17:26 
user profile iconbaka0815 hat folgendes geschrieben Zum zitierten Posting springen:
btw. auf Wikipedia 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. ;-)