Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien
Toon posts:

[logic] Poker handwaarden - puntensysteem

Pagina: 1
Acties:

Verwijderd

Topicstarter
Dag allen,

Ik werk momenteel aan een pokerprogramma.
Momenteel ben ik in staat om de handen te detecteren (dat wil zeggen, ik detecteer - per speler - of er sprake is van bijvoorbeeld een Full House, Two Pair of Three of a Kind).

Ik weet welke vijf kaarten (welke holecards + welke board cards) er gebruikt worden, dus dat weten we op dit moment.
Nu ben ik op een punt beland waar ik de handen een waarde moet toekennen.
Ik ben begonnen met een puntensysteem per type hand:

Royal Flush: 1000 ptn
Straight Flush: 900 ptn
4 of a kind: 800 ptn
...
3 of a kind: 400 ptn
2 paar: 300 ptn
1 paar: 200 ptn

Daarmee kan ik de verschillende handen van elkaar onderscheiden, en bepalen welke hand sterker is ( = welke hand meer punten heeft) ten opzichte van een andere hand.
Het probleem doet zich voor als x tegenstanders handen hebben die op elkaar lijken.

Een voorbeeld:
Speler A: Three of a Kind ('AAA75') (drie azen, een zeven en een vijf)
Speler B: Three of a Kind ('AAA74') (drie azen, een zeven en een vier)
Speler C: Three of a Kind ('KKK98') (drie koningen, een negen en een acht)

Hoe geef ik deze handen een waarde (tussen de 400 en 500 ptn) die aangeeft welke hand de sterkste is? Simpelweg de kaartwaarden (Aas=14, K=13, ... 2=2) optellen werkt uiteraard niet. Een hand als '222AA' ( = 34 ptn) zou dan winnen van een hand als '88833' ( = 30 punten ).

Dit probleem doet zich niet alleen voor bij Three of a Kind handen, maar ook bij handen als twee paar, een paar of zelfs bij 'high card' (laagst mogelijke hand).

Wellicht heeft iemand hier ervaring mee, alle input is welkom.

Ander voorbeeld:
Ook bij het hebben van slechts een high card doet dit probleem zich voor. Simpelweg de kaartwaarden optellen werkt niet:
Speler A: 'AT876' ( = 45 punten) (high card: Ace)
Speler B: 'KQJ87' ( = 51 punten) (high card: King)

Speler B zou winnen - hetgeen niet correct is (een high card Aas wint van een Koning).

[ Voor 9% gewijzigd door Verwijderd op 18-03-2011 14:24 ]


  • Cartman!
  • Registratie: April 2000
  • Niet online
Eerst sorteren op de hoogste match dus (AAA > 888) en daar dan een factor aan meegeven?

edit: overigens mis ik het punt van punten toekennen aan een handje, je wint of je wint niet bij poker.

[ Voor 38% gewijzigd door Cartman! op 18-03-2011 14:22 ]


  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 17-10 16:43
Dit is eigenlijk heel simpel.
Je hebt een basis score nodig voor het type hand. Bijvoorbeeld:

3 of a kind: 3000 punten
2 of a kind: 2000 punten.

Daarna tel je 10* kaart waarde van de kaarten die iets speciaals vormen er bij op.

Een 10,10,10, A, V wordt dan 3000 + 300 = 3300.

Nu moet je alleen nog 10,10,10, A, V en 10,10,10 A, B van elkaar onderscheiden.

Dus daarna tel je alle kaarten in de hand die niet iets speciaals vormen er nog bij op.

10, 10, 10, A, V wordt uiteindelijk dus 3000 + 300 + 14 + 12 = 3326
10, 10, 10, A, B wordt dan uiteindelijk dus 3000 + 300 + 14+ 11 = 3325.

Zo heb je dus een geschikte ordening die overeen komt met wie er wint.

Edit: de key hier is dus dat je elke match zo veel waard is zodat een minder belangrijke match met hogere kaarten nooit meer kan worden.

[ Voor 9% gewijzigd door roy-t op 18-03-2011 14:24 ]

~ Mijn prog blog!


Verwijderd

Topicstarter
Het probleem is minder simpel dan het lijkt.
In jouw voorbeeld gaat dit bijv. mis:

10 10 10 A 2 ( = 3000 + 300 + 14 + 2 = 3316 ptn)
10 10 10 K V ( = 3000 + 300 + 13 + 12 = 3325 ptn)

...terwijl de hand met de Aas wint.
Zie ook mijn voorbeeld uit de TS met een highcard:
roy-t schreef op vrijdag 18 maart 2011 @ 14:22:

Ander voorbeeld:
Ook bij het hebben van slechts een high card doet dit probleem zich voor. Simpelweg de kaartwaarden optellen werkt niet:
Speler A: 'AT876' ( = 45 punten) (high card: Ace)
Speler B: 'KQJ87' ( = 51 punten) (high card: King)

Speler B zou winnen - hetgeen niet correct is (een high card Aas wint van een Koning).

[ Voor 104% gewijzigd door Verwijderd op 18-03-2011 14:40 ]


Verwijderd

Dan doe je er nog meer nullen bij ;)

Het slimste lijkt mij, om inderdaad een score toe te kennen aan de hand van een setje (bijv: 2 of a kind: 0x100000, hexadecimaal, 3 of a kind: 0x200000) Die nullen vervang je dan de waarde van een hand, bijvoorbeeld:

hand = A 5 4 3 2
hand2= K V J 3 2

sorteren, score toekennen:

hand1: score 0x000000, plus waarde van de kaarten (aas = 14 = E), ofwel een score van 0x0E5432
hand2: score 0x000000 plus waarde van de kaarten (K = 13 = D, ...) ofwel een totaal van 0x0DCB32

Voor meer kaarten voeg je gewoon meer bits toe.

Let er wel op dat je goed sorteert, ik heb geen idee wie er wint met de handen "99222" en "77744" (full house)

Verwijderd

Wat wil je met de waarden? Een AI schrijven of gewoon bepalen wie er wint? In het laatste geval is de waarde van een hand een 6-tupel; eerst komt de rang van de categorie (high card, one pair, two pair, three of a kind, etcetera), en dan de individuele kaartwaardes in dalende volgorde.

Je kunt dit wel platslaan tot een enkel getal, dan wordt het iets als
code:
1
(((((z * 13) + k1) * 13 + k2) * 13 + k3) * 13 + k4) * 13 + k5
waarbij z de waarde van de categorie is (0-8 ofzo voor high card tot straight flush) en k1-k5 de waarde van de kaart (0-12 voor 2 tot aas). (edit: dit is in essentie hetzelfde idee als Darkstone's verhaal)

[ Voor 5% gewijzigd door Verwijderd op 18-03-2011 15:35 ]


Verwijderd

^Precies hetzelfde als ik, maar dan met base 13 in plaats van 16.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op vrijdag 18 maart 2011 @ 14:39:
hand1 = A 5 4 3 2
hand1: score 0x000000, plus waarde van de kaarten (aas = 14 = E), ofwel een score van 0x0E5432
Sowieso is dat een straat. Waar je dus rekening moet houden met het feit dat een A zowel 1 als 14 kan betekenen. 23456 is een hogere straat dan A2345

Dat maakt ook dat de basis-13 van Tinctorius niet voldoende is, je hebt minstens basis-14 nodig. Het voordeel van basis-16 is natuurlijk dat je er makkelijk bit-operaties op los kunt laten.
Let er wel op dat je goed sorteert, ik heb geen idee wie er wint met de handen "99222" en "77744" (full house)
De three of a kind in een full house heeft een hogere waardering dan de pair. 77722 wint dus van 22299.
Verwijderd schreef op vrijdag 18 maart 2011 @ 14:50:
Wat wil je met de waarden? Een AI schrijven of gewoon bepalen wie er wint? In het laatste geval is de waarde van een hand een 6-tupel; eerst komt de rang van de categorie (high card, one pair, two pair, three of a kind, etcetera), en dan de individuele kaartwaardes in dalende volgorde.
Niet alleen in dalende volgorde, dus ook rekening houden met de weging van de kaart 65433 wint van een AKQ22, ookal heeft die laatste de hoogste kaarten).

[ Voor 14% gewijzigd door .oisyn op 18-03-2011 15:08 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

offtopic:
Zoals je ziet ben ik niet zo'n held met poker :+

Verwijderd

.oisyn schreef op vrijdag 18 maart 2011 @ 15:03:
[...]

Niet alleen in dalende volgorde, dus ook rekening houden met de weging van de kaart 65433 wint van een AKQ22, ookal heeft die laatste de hoogste kaarten).
In dat geval wil ik weten waar ik die regels (kort en bondig) kan vinden. Op Wikipedia word ik er niet veel wijzer van, afgezien van een paar zinnen op de pagina over pokerhanden en hun waarden:
Hands are ranked first by category, then by individual card ranks; even the lowest hand that qualifies in a certain category defeats all hands in all lower categories. For example, 2♦ 2♠ 3♦ 3♣ 4♠, the lowest-valued two pair hand, defeats all hands with just one pair or high card (such as A♠ A♦ K♦ Q♥ J♣). Only between two hands in the same category are card ranks used to break ties.
(nadruk zelf toegevoegd)

Verwijderd

Daarom moet je ook goed sorteren, je verplaatst de kaarten die bij het setje horen eerst naar voren.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

Idd, het is heel simpel. Eerst komen de kaarten die de categorie bepalen, van hoog naar laag. De full house is hier de enige die nog een onderverdeling heeft: eerst de trips, daarna de pair. Daarna komen de overige kaarten, van hoog naar laag. Straight, flush, straight flush en full house hebben natuurlijk geen overige kaarten.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Waarom zou je de waardes per se naar een getal moeten mappen? Je kunt toch ook gewoon een comparator uitschrijven en de handen sorteren? Lijkt me veel duidelijker.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Verwijderd

Uiteindelijk is het sneller met integers, vooral als je het vaker dan één keer moet doen. Maar dat is hier niet zo'n goed excuus.

De code van de comparator zal waarschijnlijk sterk gaan lijken op het opbouwen van zo'n score, aangezien je mogelijk n (n tussen 0 en 5, inclusief) high cards moet gaan vergelijken.

[ Voor 12% gewijzigd door Verwijderd op 18-03-2011 15:56 ]


  • SLeddert
  • Registratie: December 2002
  • Laatst online: 27-10 12:59

SLeddert

SLeddert

Ik zou niet alles omrekenen naar punten, maar eerst per type beoordelen. ( 1pair = 1, 2pair = 2, 3oak = 3, etc.)
Pas bij gelijke typen zou ik naar punten omrekenen.

Bij AAA12 = omdat 't Azen zijn een waarde specifiek voor azen bijtellen ( bijv. + 1400 ). Deze waarde moet je wel zelf even inschatten. en dan de andere kaarten nog ( +1 +2 ) = 1403
Bij KKK89 = omdat 't 't Koningen zijn een waarde specifiek voor koningen bijtellen ( bijv. + 1300 ). en dan +8 +9 voor de losse kaarten = 1317

[ Voor 10% gewijzigd door SLeddert op 18-03-2011 16:17 ]

Karsten


  • MueR
  • Registratie: Januari 2004
  • Laatst online: 14:48

MueR

Admin Devschuur® & Discord

is niet lief

Simpelweg nummertjes tellen red je het niet mee, ook niet als je alle sets bij elkaar hebt. Die kaarten hebben ook kleurtjes.

Board: 9S 8S 7S AD KD
Speler 1: JD 10C
Speler 2: 6S 5S

Speler 2 wint, want straight flush.

[ Voor 17% gewijzigd door MueR op 18-03-2011 16:15 ]

Anyone who gets in between me and my morning coffee should be insecure.


Verwijderd

Je kan het toch gewoon op de manier doen van roy-t. Eerst bepalen wat iemand in zijn hand heeft (straight, flush, pair). Elke soort heeft zijn eigen waarde, als er spelers zijn die dan dezelfde waarde hebben dan ga je voor die spelers kijken naar hun resterende kaarten. De high card kan je dan bepalen door van elke speler zijn hoogste kaart te nemen. Als je elke kaart zijn eigen waarde heeft, dan kan je dus bepalen wie de hoogste kaart heeft. De truc is dus dat je niet voor elke speler alle waardes van zijn kaarten bij elkaar optelt. Maar dat je dat in stapjes doet op het moment dat niemand dezelfde score heeft stop je en heb je een ranglijst. Voor de spelers die een gelijke score hebben ga je verder vergelijken totdat je weet wie de hoogste kaart heeft.

[ Voor 14% gewijzigd door Verwijderd op 18-03-2011 16:22 ]


  • Vaan Banaan
  • Registratie: Februari 2001
  • Niet online

Vaan Banaan

Heeft ook Apache ontdekt

Ja je zou het bijvoorbeeld in een 32bit kunnen steken.
0000ccccxxxxyyyy00zzzzzzzzzzzzz0
Waarbij cccc de cagetorie is (0000 = High card, 0001 = 1 pair, 0010 = 2 pair enz.)
xxxx is de waarde (2 t/m 14) van de hoogste kaart van die categorie (Triple kaart bij full house, 5 bij Straight met aas)
yyyy is de waarde (2 t/m 14) van de (2de) pair indien van toepassing (2 pair en full house)
zzzzzzzzzzzzz is de bitmask van de overige kaarten die over zijn (indien van toepassing)

[ Voor 0% gewijzigd door Vaan Banaan op 18-03-2011 16:27 . Reden: Iets met 1 t/m 13, of 2 t/m 14, ik kan niet kiezen :( ]

500 "The server made a boo boo"


Verwijderd

SLeddert schreef op vrijdag 18 maart 2011 @ 16:13:
Ik zou niet alles omrekenen naar punten, maar eerst per type beoordelen. ( 1pair = 1, 2pair = 2, 3oak = 3, etc.)
Dat is dus hetzelfde als mijn z, Ivy's 1000/900/800/..., roy-t's 3000/2000, etcetera. En 1, 2, 3 zijn nog steeds punten, toch?
MueR schreef op vrijdag 18 maart 2011 @ 16:14:
Simpelweg nummertjes tellen red je het niet mee, ook niet als je alle sets bij elkaar hebt. Die kaarten hebben ook kleurtjes.
Of de kaartkleuren meetellen in de waarden van de individuele kaarten hangt af van de gespeelde pokervariant. Ik dacht dat de meest voorkomende varianten de kleuren compleet negeerden, behalve bij (straight) flushes natuurlijk.

[ Voor 7% gewijzigd door Verwijderd op 18-03-2011 16:31 ]


  • MueR
  • Registratie: Januari 2004
  • Laatst online: 14:48

MueR

Admin Devschuur® & Discord

is niet lief

Verwijderd schreef op vrijdag 18 maart 2011 @ 16:24:
Of de kaartkleuren meetellen in de waarden van de individuele kaarten hangt af van de gespeelde pokervariant. Ik dacht dat de meest voorkomende varianten de kleuren compleet negeerden,
Dus...
behalve bij (straight) flushes natuurlijk.
.. moet je het er toch inbakken, want zonder heb je dikke kans op oepsjes.

Anyone who gets in between me and my morning coffee should be insecure.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

MueR schreef op vrijdag 18 maart 2011 @ 16:14:
Simpelweg nummertjes tellen red je het niet mee, ook niet als je alle sets bij elkaar hebt. Die kaarten hebben ook kleurtjes.
Bij het bepalen van de categorie gebruik je niet louter nummertjes. Voor de score binnen de categorie, waar de hele topic over gaat, hoef je niet meer naar kleuren te kijken. Voor de veelgespeelde pokervarianten iig (hold 'em, omaha, 7 card stud, 5 card draw, raz, etc)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Xuj
  • Registratie: November 2009
  • Laatst online: 05-06 11:08

Xuj

Wat je zou kunnen doen en wat geloof ik toch vreselijk snel is, is een look-up table genereren?

  • kunnen
  • Registratie: Februari 2004
  • Niet online
Verwijderd schreef op vrijdag 18 maart 2011 @ 19:50:
[...]
Ik ben erg gecharmeerd van die priem-"hash" :D
De TwoPlusTwo evaluator?

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// The "chessboard" / lookup table.
int HR[32487834];

// Navigate the lookup table
int GetHandValue(int* pCards)
{
    int p = HR[53 + *pCards++];
    p = HR[p + *pCards++];
    p = HR[p + *pCards++];
    p = HR[p + *pCards++];
    p = HR[p + *pCards++];
    p = HR[p + *pCards++];
    return HR[p + *pCards++];
}


Die is inderdaad erg handig en snel (vooral bij equity calculations(==enumerations, alle mogelijke vervolgkaarten doorlopen), aangezien je dan steeds de eerste paar lookups kunt onthouden), enige nadeel is dat je er ~128mb geheugen voor kwijt bent.

Edit:
Oh, ik zie dat je de CactusKev variant bedoelt. Nadeel daarvan is dat hij niet direct in pokersimulators gebruikt kan worden aangezien hij is gemaakt voor 5-card evaluation en niet voor 7-card evaluation. (Dus hij kan niet na een ronde direct bepalen welke hand wint)

[ Voor 18% gewijzigd door kunnen op 18-03-2011 20:01 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

Feitelijk gewoon een finite-state automaton dus, hoe logisch :)
Nadeel daarvan is dat hij niet direct in pokersimulators gebruikt kan worden aangezien hij is gemaakt voor 5-card evaluation en niet voor 7-card evaluation.
Niet elke poker-variant gebruikt een 7-card evaluation, da's alleen bij hold'em en 7 card stud. Voor Omaha bijvoorbeeld moet je kiezen uit 2 van de 4 hole cards en 3 van de 5 community cards.

[ Voor 97% gewijzigd door .oisyn op 19-03-2011 11:57 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Ik heb bij wijze van vingeroefening een implementatie geschreven in Python. De handwaardes worden bepaald door tuple van 2 elementen, een vaste handwaarde en een lijst met tie breakers. Bij vergelijken wordt eerste de handwaarde vergeleken, als die gelijk is worden de tie breakers vergeleken.

Bij het bepalen van de te spelen hand genereert de speler alle combinaties, sorteert die op waarde en kiest de hoogste, op die manier is de evaluation feitelijk onafhankelijk van de spelvorm.

Alle combinaties van handen (2,598,960) genereren, shufflen en sorteren kostte me op mijn PC 2m30s. Heb het gevoel dat dat vrij rap is. Ik kan me (afgezien van eventuele overhead die je met python sowieso hebt) slecht voorstellen dat het berekenen van een hash heel veel sneller is. Nadeel is wel dat je niet zo makkelijk strategieën kunt kiezen, mocht je een AI willen bouwen.

Feedback uiteraard welkom :)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • kunnen
  • Registratie: Februari 2004
  • Niet online
drm schreef op woensdag 23 maart 2011 @ 10:46:
Ik heb bij wijze van vingeroefening een implementatie geschreven in Python. De handwaardes worden bepaald door tuple van 2 elementen, een vaste handwaarde en een lijst met tie breakers. Bij vergelijken wordt eerste de handwaarde vergeleken, als die gelijk is worden de tie breakers vergeleken.

Bij het bepalen van de te spelen hand genereert de speler alle combinaties, sorteert die op waarde en kiest de hoogste, op die manier is de evaluation feitelijk onafhankelijk van de spelvorm.

Alle combinaties van handen (2,598,960) genereren, shufflen en sorteren kostte me op mijn PC 2m30s. Heb het gevoel dat dat vrij rap is. Ik kan me (afgezien van eventuele overhead die je met python sowieso hebt) slecht voorstellen dat het berekenen van een hash heel veel sneller is. Nadeel is wel dat je niet zo makkelijk strategieën kunt kiezen, mocht je een AI willen bouwen.

Feedback uiteraard welkom :)
Ik heb het even opgezocht, die HR[..]-oplossing die ik hierboven quote doet in VB6 (:+) ~300 miljoen (7-card) lookups per seconde, bij enumeratie O-) (5-card is nog een stuk sneller)

Die implementatie (en vele andere, waaronder straight-forward implementaties zoals die van jou) komt overigens oorspronkelijk van deze thread: http://archives1.twoplust...906&page=0&fpart=all&vc=1

[ Voor 6% gewijzigd door kunnen op 23-03-2011 14:46 ]


  • DrClaw
  • Registratie: November 2002
  • Laatst online: 15-10 14:49
even terug naar het originele probleem. is het _echt_ nodig om voor alle mogelijke hands een waarde uit te rekenen, zodat je daarna een vergelijking kunt doen? ik denk van niet.

als wel, dan kom je dus te zitten met een enorme lookup table, waarvan heel veel entries overbodig zijn omdat het toch geen hand is die wat zou kunnen opleveren.

menselijke spelers hebben ook geen lookup table in hun hoofd om de waarde van hun hand te berekenen. die sorteren (in hun hoofd misschien of in het echt) de 5 kaarten, en gaan mentaal het rijtje mogelijke combinaties af (heb ik een pair, heb ik een three-of-a-kind, heb ik een full house, enzovoort). stel je hebt 15 van dat soort vergelijkingen, dan kost je dat gemiddeld 7 vergelijkingen per speler, terwijl je 0 extra geheugen nodig hebt voor een lookup table. kan het ook nog eens op je telefoon draaien.

  • kunnen
  • Registratie: Februari 2004
  • Niet online
DrClaw schreef op woensdag 23 maart 2011 @ 14:57:
even terug naar het originele probleem. is het _echt_ nodig om voor alle mogelijke hands een waarde uit te rekenen, zodat je daarna een vergelijking kunt doen? ik denk van niet.

[..]

menselijke spelers hebben ook geen lookup table in hun hoofd om de waarde van hun hand te berekenen. die sorteren (in hun hoofd misschien of in het echt) de 5 kaarten, en gaan mentaal het rijtje mogelijke combinaties af (heb ik een pair, heb ik een three-of-a-kind, heb ik een full house, enzovoort). stel je hebt 15 van dat soort vergelijkingen, dan kost je dat gemiddeld 7 vergelijkingen per speler, terwijl je 0 extra geheugen nodig hebt voor een lookup table. kan het ook nog eens op je telefoon draaien.
Natuurlijk is zo'n look-up table niet altijd nodig. Een naive straight-forward implementatie zoals jij beschrijft werkt ook, maar de lookup-table versies zijn honderden keren sneller. Wanneer je equity calculaties wilt doen (berekenen hoe groot de kans is dat een bepaalde hand wint tegen een range andere handen, vanaf de flop) moet je enorm veel keren opzoeken wie wint, en met zo'n lookup table kan dit enorm snel. Bij het schrijven van een poker AI (bijvoorbeeld het berekenen van een nash equilibrium, of een monte-carlo tree search implementatie) kost deze operatie het meeste tijd, dus die wil je ook het snelst hebben. In bijvoorbeeld een simpel pokerspelletje waar geen sprake is van enige AI of whatever kun je natuurlijk een naive implementatie gebruiken, aangezien het dan niet uitmaakt of het 10 milliseconden of 10 microseconden duurt.
als wel, dan kom je dus te zitten met een enorme lookup table, waarvan heel veel entries overbodig zijn omdat het toch geen hand is die wat zou kunnen opleveren.
Dat is overigens niet waar, de tabellen worden slim gemaakt zodat elke entry nuttig is en slechts een keer voor komt.

[ Voor 12% gewijzigd door kunnen op 23-03-2011 15:12 ]


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Is zo'n lookup van 123MB nou echt het snelste? Ik kan me voorstellen dat dat bij elke lookup 5 cache misses zijn, in welke tijd je ruim het met wat logica had kunnen uitrekenen. Misschien ook niet hoor, maar dat vroeg ik me af.

  • kunnen
  • Registratie: Februari 2004
  • Niet online
Zoijar schreef op woensdag 23 maart 2011 @ 15:13:
Is zo'n lookup van 123MB nou echt het snelste? Ik kan me voorstellen dat dat bij elke lookup 5 cache misses zijn, in welke tijd je ruim het met wat logica had kunnen uitrekenen. Misschien ook niet hoor, maar dat vroeg ik me af.
Als ik het mij goed herinner is hij voor een look-up niet het snelst, maar voor een enumeratie wel. Hij werkt als volgt:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// The "chessboard" / lookup table.
int HR[32487834];

// Navigate the lookup table
int GetHandValue(int* pCards)
{
    int p = HR[53 + *pCards++];
    p = HR[p + *pCards++];
    p = HR[p + *pCards++];
    p = HR[p + *pCards++];
    p = HR[p + *pCards++];
    p = HR[p + *pCards++];
    return HR[p + *pCards++];
}

Je doet dus voor elke kaart een look-up. Op het moment dat je een enumeratie doet, bijvoorbeeld als je op de turn zit en wilt kijken hoe vaak je verwacht te winnen tegen een bepaalde hand, dan kun je zoiets doen:
code:
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
int HR[32487834];

// Navigate the lookup table
double GetWinProbability(int* pCards, int opponent_strength)
{
    int p = HR[53 + *pCards++];
    p = HR[p + *pCards++];
    p = HR[p + *pCards++];
    p = HR[p + *pCards++];
    p = HR[p + *pCards++];
    p = HR[p + *pCards++];

    double wins = 0.0;
    foreach(river in (1..52)) {
        if(!pCards.Contains(river)) {
            int our_strength = HR[p + river];
            if(our_strength>=opponent_strength) {
                wins += 0.5;
                if(our_strength>opponent_strength)
                    wins += 0.5;
            }
        }
    } 
    return wins/46;
}

Zo kost het per lookup al zo'n 90% minder tijd.

[ Voor 8% gewijzigd door kunnen op 23-03-2011 23:11 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

Sowieso kun je de tussentijdse 'p' opslaan. Je hoeft alleen nog de lookup te doen van de kaarten die nog komen gaan.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

ThomasB schreef op woensdag 23 maart 2011 @ 15:20:
Als ik het mij goed herinner is hij voor een look-up niet het snelst, maar voor een enumeratie wel. Hij werkt als volgt:
Ah ok, dat scheelt ja. Dat is ook cache vriendelijker. Ik snap dat dit voornamelijk gebruikt wordt om handen te "stoven".
offtopic:
Ah, de goeie oude pokertijd... equity op hand-ranges, dat is toch waar veel mensen afhaakten

[ Voor 12% gewijzigd door Zoijar op 23-03-2011 15:26 ]


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Ah, even goed kijken naar wat dat ding precies doet verklaart wel, ehm, "enige" snelheidswinst, ik begrijp nu pas hoe die werkt 8)7. Als ik het tenminste goed begrijp, je wandelt eigenlijk door een boom waar in staat wat de mogelijke volgende kaartwaarden, en elke uitkomst van de mogelijkheden (na 5 stappen) heeft een eindwaarde die de waarde t.o.v. de andere handen bepaalt.

Dan zit de kunst dus eigenlijk in het opbouwen van die boom.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

Dat zei ik, een finite-state automaton ;). Elke volgende kaart is een transitie naar een volgende staat, en uiteindelijk krijg je je equivalence waarde eruit. De boom kan denk ik wel wat kleiner als je eerst de kaarten sorteert, maar ik vraag me af hoeveel je daarmee wint (ik neem aan dat gelijke states al gemerged zijn).

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

.oisyn:
Dat zei ik, een finite-state automaton ;).
Die opmerking snap ik nu dus ook beter :P

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 19-11 09:49

Bosmonster

*zucht*

Kun je een hand niet onderverdelen in [type], [value] en [kickers] en daarop sorteren? Dat lijkt me ook een stuk eenvoudiger.

Dus bijvoorbeeld: [trips], [A], [7,5] voor trips A met 7,5 kicker
of [flush], [K], [7,6,5,4] voor een flush K7654 hoog

etc.

Een dergelijke structuur is makkelijk te maken uit een hand en is ook eenvoudig te sorteren zonder eerst helemaal naar punten om te zetten. Uiteindelijk zijn in de praktijk dat ook de 3 factoren waar je op vergelijkt namelijk.

[ Voor 6% gewijzigd door Bosmonster op 23-03-2011 23:42 ]


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Bosmonster:
Kun je een hand niet onderverdelen in [type], [value] en [kickers] en daarop sorteren? Dat lijkt me ook een stuk eenvoudiger.

Dus bijvoorbeeld: [trips], [A], [7,5] voor trips A met 7,5 kicker
of [flush], [K], [7,6,5,4] voor een flush K7654 hoog
da's ongeveer wat mijn implementatie doet. De value en de kicker staan in 1 lijst, want ze moeten op volgorde van waarde vergeleken worden, 't maakt dus niet uit of iets een kicker is of niet en hoe lang die lijst is, ze zijn voor dezelfde handwaardes toch allemaal even lang. Zie de evaluator en de comparator

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 19-11 09:49

Bosmonster

*zucht*

Het voordeel volgens mij van de kickers los houden is, dat er ook pokervarianten zijn waarin lagere kickers beter zijn en het dus flexibeler is (bijvoorbeeld lowball-varianten) en zelfs gecombineerde varianten (hi-lo).

Maar misschien dat dat in de praktijk in jouw implementatie ook mogelijk is.

[ Voor 28% gewijzigd door Bosmonster op 24-03-2011 12:50 ]


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Maakt in principe niet uit nee, want de eerste uit de lijst is altijd de hand-waarde.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz

Pagina: 1