Autor |
Beitrag |
jackie05
Beiträge: 357
|
Verfasst: So 10.01.10 17: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 17: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 17: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 09: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 22: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!
|
|
|