| 
| Autor | Beitrag |  
| jackie05 
          Beiträge: 357
 
 
 
 
 | 
Verfasst: So 10.01.10 16:21 
 
Hallo,
ich möchte in Delphi versuchen die Karten zu berechnen wieviel Punkte der Spieler hat.
 
 z.B. auf dem Tisch liegen 5 Karten:
 [Bube Schippe] [7 Kreuz] [7 Karo] [4 Schippe] [2 Kreuz]
 
 und die 2 Karten die der Spieler in der Hand hat:
 [8 Schippe] [2 Herz]
 
 in dem Fall hat der Spieler 2 Paare und die 2 getroffen.
 
 Wie rechne ich jetzt eigentlich die Punkte zusammen die der Spieler hat?
 
 Ich Spiele erst seit Paar Tagen Poker und weiss noch nicht so richtig wie hoch die Punktzahl bei bestimmten Karten sind, z.B. wieviele Punkte die 2 Paare zusammen gerechnet haben und wieviel Punkte ich bei der 2 bekomme die ich getroffen habe?
 
 Gibt es Vielleicht fertige Unit die das berechnen der Karte vereinfacht?
 
 Oder wie könnte ich das am einfachsten berechnen lassen in Delphi?
 
 Ich bedanke mich schonmal im Voraus.
 
 MfG
 |  |  |  
| Tilman 
          Beiträge: 1405
 Erhaltene Danke: 51
 
 Win 7, Android
 Turbo Delphi, Eclipse
 
 | 
Verfasst: So 10.01.10 16:49 
 
Du hältst 2 Karten in der Hand, ich nehme also mal an dass wir von "Texas Holdem" sprechen    (BTW: Regeln kann man z.B. bei Wikipedia finden).
 "Punkte" gibts in Texas Holdem nicht. Was du meinst ist vielleicht der "Rang". Folgende Ränge gibts bei Texas Holdem:
 Rang 1    keine Figur
 Rang 2    Ein Paar
 Rang 3    Zwei Paare
 Rang 4    Drilling 
 usw.
 Wenn zwei Spieler ein Paar halten (Rang 2), so gewinnt der Spieler welcher das höchste Paar hält, bzw - sollten beide das selbe Paar halten - der jenige Spieler welcher die höchste Beikarte hält. Und das runter bis zur 5. Karte in er Hand bzw. 3. Beikarte.
 //edit 
 Ich hab mal so ein Programm geschrieben welches unter anderem die Funktionalität enthält zwei Blätter zu vergleichen. Der Source ist aber nicht ganz einfach, und ehrlich gesagt auch nciht besonders schön ^^ (schon ein paar Jährchen her^^).
www.delphi-forum.de/...amp;highlight=prodds_________________Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen. 
(Koreanisches Sprichwort) |  |  |  
| Gravitar 
          Beiträge: 41
 
 Win XP
 D6 Ent
 
 | 
Verfasst: Di 19.01.10 16:15 
 
	  |  jackie05 hat folgendes geschrieben  : |  	  | Hallo, ich möchte in Delphi versuchen die Karten zu berechnen wieviel Punkte der Spieler hat......
 
 | 
 Hi jackie05,
 ich habe mir selbst eine Unit geschrieben, die den jeweiligen Rang des Blattes und die Gewinnwahrscheinlichkeit ermittelt.
 War übrigens gar nicht so einfach. Ich habe mir die Sourcen von Tilmann angeschaut und fand sie ziemlich kompliziert und auch nicht besonders schön.
 Außerdem wollte ich verschiedene Pocket-Hands hinsichtlich der Gewinnwahrscheinlichkeit vergleichen. Also z.B. Ac Kh  gegen  Qh Jh bei 2 Spielern.
 Also flugs selbst ran und losprogrammiert.... im Ergebnis ist mein Source allerdings auch ziemlich kompliziert und nicht sonderlich schön geworden    .
 Das liegt vermutlich daran, dass es nicht so einfach ist, den jeweils höchsten Rang eines Blattes (best 5 of 7) zu ermitteln.
 Egal, jetzt funktioniert es. Wenn Interesse besteht, kann ich gern die Unit hochladen.
 Gruß, Andreas |  |  |  
| JoelH 
          Beiträge: 806
 Erhaltene Danke: 17
 
 Win10
 Delphi Alexandria 11.2 Patch 1
 
 | 
Verfasst: Mi 20.01.10 08:29 
 
	  |  Gravitar hat folgendes geschrieben  : |  	  | 
 Wenn Interesse besteht, kann ich gern die Unit hochladen.
 
 | 
 *Hand heb*
 Da ich das auch schon mal programmiert habe würde mich dein Code interessieren, vor allem dein Ansatz. 
 Wieviele Iterationen schafft dein Programm in der Sekunde?_________________ mfg. Joel
 |  |  |  
| Gravitar 
          Beiträge: 41
 
 Win XP
 D6 Ent
 
 | 
Verfasst: Mi 20.01.10 21:24 
 
	  | Zitat: |  	  |  JoelH *Hand heb*
 
 Da ich das auch schon mal programmiert habe würde mich dein Code interessieren, vor allem dein Ansatz.
 
 Wieviele Iterationen schafft dein Programm in der Sekunde?
 | 
 Hi,
 na dann wollen wir die Hand nicht verhungern lassen! Unit liegt im Anhang.
 Die zentrale Procedure zur Ermittlung des Ranges ist diese hier:
 												| 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:
 
 | procedure Rank(var Cards:TPocket);var
 ranks : array [TRank] of boolean;
 bestcards : array [TRank,0..4] of TCards;
 x,y,z,kind,straight_count,n : integer;
 c,flushcolor : TColor;
 straightflag : Tbits;
 rf_flag : boolean;
 r : TRank;
 begin
 straightflag := tbits.create;
 straightflag.Size := 15;
 
 for r := low(TRank) to high(TRank) do
 ranks[r] := false;
 ranks[rkHighCard] := true;
 
 for x := 0 to 1 do
 myCards[x] := cards.cards[x];
 
 for x := 2 to 6 do
 myCards[x] := community.cards[x-2];
 
 kind := 1;
 for x := 0 to 5 do
 for y := x+1 to 6 do
 if mycards[x].Value < mycards[y].Value then
 swapcards(mycards[x],mycards[y]);
 flushcolor := null;
 c := null;
 repeat
 c := succ(c);
 n := 0; x:= 0;
 repeat
 if  mycards[x].Color = c then
 begin
 bestcards[rkflush,n] := mycards[x];
 inc(n);
 end;
 inc(x);
 until (n > 4) or (x > 6);
 if n = 5 then
 begin
 ranks[rkflush] := true;
 flushcolor := c;
 end;
 until (flushcolor > null) or (c = kreuz);
 
 for x := 0 to 6 do
 begin
 straightflag[mycards[x].Value] := true;
 if mycards[x].value = 14 then
 straightflag[1] := true;
 end;
 
 straight_count := 0;
 x := 14;
 repeat
 if straightflag[x] then
 begin
 for y := 0 to 6 do
 if mycards[y].value = x then
 bestcards[rkstraight,straight_count] := mycards[y];
 inc(straight_count)
 end
 else
 straight_count := 0;
 if straight_count = 5 then
 ranks[rkstraight] := true;
 dec(x);
 until (x < 1) or ranks[rkstraight];
 
 if ranks[rkStraight] and ranks[rkFlush] then
 begin
 straight_count := 0;
 for x := 14 downto 10 do
 begin
 if straightflag[x] then
 begin
 for y := 0 to 6 do
 if (mycards[y].Value = x) and
 (mycards[y].Color = flushcolor) then
 begin
 bestcards[rkRoyalFlush,straight_count] := mycards[y];
 inc(straight_count);
 end;
 end
 else
 straight_count := 0;
 end;
 if straight_count = 5 then
 ranks[rkRoyalFlush] := true;
 end;
 
 if ranks[rkStraight] and ranks[rkFlush] then
 begin
 straight_count := 0;
 for x := 1 to 14 do
 begin
 rf_flag := false;
 if straightflag[x] then
 for y := 0 to 6 do
 if (mycards[y].Value = x) and
 (mycards[y].Color = flushcolor) then
 begin
 rf_flag := true;
 bestcards[rkStraightFlush,straight_count] := mycards[y];
 end;
 if straightflag[x] and rf_flag then
 inc(straight_count)
 else
 straight_count := 0;
 if straight_count = 5 then
 begin
 ranks[rkStraightFlush] := true;
 break;
 end;
 end;
 end;
 
 for x := 0 to 5 do
 begin
 for y := x+1 to 6 do
 if (myCards[x].Value = myCards[y].Value) and
 (myCards[x].value > 1) then
 inc(kind);
 if kind = 4 then
 begin
 ranks[rk4OfaKind] := true;
 n:= 0;
 for y := 0 to 6 do
 if mycards[y].Value = mycards[x].Value then
 begin
 bestcards[rk4OfaKind,n] := mycards[y];
 inc(n);
 end;
 DeletemyCards(myCards[x].value);
 y := 0;
 repeat
 bestcards[rk4OfaKind,4] := mycards[y];
 inc(y);
 until (mycards[y-1].Value > 1) or (y > 6);
 end;
 if kind = 3 then
 begin
 ranks[rkSet] := true;
 n := 0;
 for y := 0 to 6 do
 if mycards[y].Value = mycards[x].Value then
 begin
 bestcards[rkSet,n] := mycards[y];
 inc(n);
 end;
 DeletemyCards(myCards[x].value);
 y := 0; n := 0;
 repeat
 if mycards[y].value > 1 then
 begin
 bestcards[rkSet,n+3] := mycards[y];
 inc(n);
 end;
 inc(y);
 until (n = 2) or (y > 6);
 end;
 if kind = 2 then
 begin
 y := 0; n:= 0;
 if (ranks[rkPair]) and (not ranks[rkDoublePair]) then
 begin
 ranks[rkDoublePair] := true;
 for y := 0 to 6 do
 if mycards[y].Value = mycards[x].value then
 begin
 bestcards[rkDoublePair,n+2] := mycards[y];
 inc(n);
 end;
 for y := 0 to 1 do
 bestcards[rkDoublePair,y] := bestcards[rkPair,y];
 deletemyCards(myCards[x].value);
 y := 0;
 repeat
 bestcards[rkDoublePair,4] := mycards[y];
 inc(y);
 until (mycards[y-1].Value > 1) or (y>6)
 end;
 if (not ranks[rkPair]) and (not ranks[rkDoublePair]) then
 begin
 ranks[rkPair] := true;
 for y := 0 to 6 do
 if mycards[y].Value = mycards[x].value then
 begin
 bestcards[rkPair,n] := mycards[y];
 inc(n);
 end;
 deletemyCards(myCards[x].value);
 y := 0; n := 0;
 repeat
 if mycards[y].value > 1 then
 begin
 bestcards[rkPair,n+2] := mycards[y];
 inc(n);
 end;
 inc(y);
 until (n = 3) or (y > 6);
 end;
 end;
 kind := 1;
 end;
 
 if (ranks[rkSet]) and (ranks[rkPair]) then
 begin
 ranks[rkFullHouse] := true;
 for y := 0 to 2 do
 bestcards[rkFullHouse,y] := bestcards[rkSet,y];
 for y := 3 to 4 do
 bestcards[rkFullHouse,y] := bestcards[rkPair,y-3];
 end;
 
 
 r := rkRoyalFlush;
 repeat
 if ranks[r] then cards.Rank := r;
 dec(r);
 until ranks[succ(r)];
 
 for y := 0 to 4 do
 cards.bestfive[y] := bestcards[cards.rank,y];
 
 straightflag.Free;
 end;
 |  Wie gesagt, nicht gerade einfach und sicherlich zu verbessern.
 Rekursionen schaffe ich so ca. 380.000 Hände/sek (also austeilen, Flop/Turn/River, Rang ermitteln). Rechner ist ein i7 940, wobei der Quad-Core keine Rolle spielt, da das Ganze nur auf einem Prozessor läuft.
 Aus dem Source läßt sich der Ansatz - glaube ich - ganz gut rauslesen.
 Gruß, Andreas
Einloggen, um Attachments anzusehen!
 |  |  |  |