RS
RS
Joined: Feb 11, 2014
  • Threads: 62
  • Posts: 8624
May 27th, 2015 at 6:15:01 PM permalink
So let's say I want to write a function (or several functions) to incorporate proper VP strategy. I'm not too sure how to write the code (efficiently) to check for each possible draw.

I can think of a few ways to go about doing this, but, none of them seem to be too efficient, even with a simple strategy like 9/6 JOB. I am not trying to generate a strategy.


Sure, I could first check for a dealt royal flush. Then check for a dealt straight flush, then dealt 4-of-a-kind and dealt FH. Then check for 4-to-royal. Then keep going down the list.


Any ideas or help? Thanks.
JB
Administrator
JB
Joined: Oct 14, 2009
  • Threads: 334
  • Posts: 2089
May 27th, 2015 at 6:55:09 PM permalink
Is it for a specific game and paytable which will never change? Or is it for an arbitrary game and paytable, requiring an accurate, generic function?

Is it for a simulation?
Wizard
Administrator
Wizard
Joined: Oct 14, 2009
  • Threads: 1458
  • Posts: 25448
May 27th, 2015 at 6:56:04 PM permalink
I wrote a whole page about it: My Methodology for Video Poker Analysis.
“Extraordinary claims require extraordinary evidence.” -- Carl Sagan
RS
RS
Joined: Feb 11, 2014
  • Threads: 62
  • Posts: 8624
May 27th, 2015 at 6:57:21 PM permalink
Quote: JB

Is it for a specific game and paytable which will never change? Or is it for an arbitrary game and paytable, requiring an accurate, generic function?

Is it for a simulation?



That's part of the problem. Right now I'm doing it for a simulation on 9/6 JOB. But I'm hoping to include other paytables/strategies in the future like DW and DDB primarily.


Quote: Wizard

I wrote a whole page about it: My Methodology for Video Poker Analysis.



Yes, I read that (partially). But if I'm not mistaken, that was for generating a strategy and iterating through each possible dealt hand to determine the best hold.

I already know the best hold. I don't know how to code the best hold strategy, other than hard-coding it. ie:

Quote:


ten = 0;
jack = 0;
queen =0;
king = 0;
ace = 0;

spade = 0;
club = 0;
heart = 0;
diamond = 0;

for (i = 0; i < 5; i++) {
if (rank == "T")
ten++;
elseif (rank == "J")
jack++;
....etc

if (suite == "s")
spade++;
elseif (suite == "d")
diamond++;
}

if (spade == 5 or diamond == 5 or heart == 5 or club == 5)
if (ten == 1 and jack == 1 and queen == 1 and king == 1 and ace == 1)
echo "Dealt royal flush!\n";




that's a lot of code for a fairly simple hand.

other hands get more complex (haven't gotten or attempted those yet). i'd assume hands like 3-card straight flush draws would be a total b****.


edit edit:

the [i] in my code/quote above don't show up properly. click "edit/quote" on my post to see the [i ] properly.
JB
Administrator
JB
Joined: Oct 14, 2009
  • Threads: 334
  • Posts: 2089
May 27th, 2015 at 7:16:23 PM permalink
Quote: RS

That's part of the problem. Right now I'm doing it for a simulation on 9/6 JOB. But I'm hoping to include other paytables/strategies in the future like DW and DDB primarily.


The reason I ask is because you don't need to go through much trouble at all for a simulation.

1) Create a static array holding the probability of each outcome when optimal strategy is used.

2) For the simulation itself, repeatedly generate a random double r such that 0 <= r < 1 and determine which outcome it corresponds to. Use the outcome however you need (such as adding its payoff to a running total, etc.)

The following code snippets are in C# but you should be able to adapt the code to whatever language you use:

    static Random RNG = new Random();

static int[] Paytable = { 800, 50, 25, 9, 6, 4, 3, 2, 1, 0 };

static double[] ProbabilityTable =
{
0.0000247582680375947, // Royal Flush
0.000109309090371472, // Straight Flush
0.00236254568587687, // Four of a Kind
0.0115122073362865, // Full House
0.0110145109680315, // Flush
0.0112293672413438, // Straight
0.0744486985711364, // Three of a Kind
0.129278902480178, // Two Pair
0.214585031125644, // Jacks or Better
0.545434669233094 // All Other
};

// the probabilities don't quite sum to exactly 1 but are close enough

//////////////////////////////////////////////////////////////////////

while (true)
{
int outcome = 0;

double r = RNG.NextDouble();

for (int x = 0; x < 10; x++)
{
double p = ProbabilityTable[x];

if (r < p)
{
outcome = x;
break;
}

r -= p;
}

int prize = Paytable[outcome];

// use the outcome or prize however you need
}


This will also let you run many more trials per second than if you actually shuffled a deck, dealt a hand, decoded it, applied optimal strategy, drew replacement cards, and scored the final hand for each trial.
RS
RS
Joined: Feb 11, 2014
  • Threads: 62
  • Posts: 8624
May 27th, 2015 at 7:32:58 PM permalink
Quote: JB

The reason I ask is because you don't need to go through much trouble at all for a simulation.

1) Create a static array holding the probability of each outcome when optimal strategy is used.

2) For the simulation itself, repeatedly generate a random double r such that 0 <= r < 1 and determine which outcome it corresponds to. Use the outcome however you need (such as adding its payoff to a running total, etc.)

The following code snippets are in C# but you should be able to adapt the code to whatever language you use:

    static Random RNG = new Random();

static int[] Paytable = { 800, 50, 25, 9, 6, 4, 3, 2, 1, 0 };

static double[] ProbabilityTable =
{
0.0000247582680375947, // Royal Flush
0.000109309090371472, // Straight Flush
0.00236254568587687, // Four of a Kind
0.0115122073362865, // Full House
0.0110145109680315, // Flush
0.0112293672413438, // Straight
0.0744486985711364, // Three of a Kind
0.129278902480178, // Two Pair
0.214585031125644, // Jacks or Better
0.545434669233094 // All Other
};

// the probabilities don't quite sum to exactly 1 but are close enough

//////////////////////////////////////////////////////////////////////

while (true)
{
int outcome = 0;

double r = RNG.NextDouble();

for (int x = 0; x < 10; x++)
{
double p = ProbabilityTable[x];

if (r < p)
{
outcome = x;
break;
}

r -= p;
}

int prize = Paytable[outcome];

// use the outcome or prize however you need
}


This will also let you run many more trials per second than if you actually shuffled a deck, dealt a hand, decoded it, applied optimal strategy, drew replacement cards, and scored the final hand for each trial.



I've already done this in single-line (what you described).

But now I'm working on multi-line. As far as I know, you can't do the same thing, can you?

I'm looking at the variance (ie: bankroll requirement to play X coin in)...not so much as for the EV.
JB
Administrator
JB
Joined: Oct 14, 2009
  • Threads: 334
  • Posts: 2089
May 27th, 2015 at 7:33:39 PM permalink
Ah. In that case, the simple approach would not work.

Stay tuned, another idea is coming forth...
JB
Administrator
JB
Joined: Oct 14, 2009
  • Threads: 334
  • Posts: 2089
May 27th, 2015 at 7:47:36 PM permalink
What language are you using?
Wizard
Administrator
Wizard
Joined: Oct 14, 2009
  • Threads: 1458
  • Posts: 25448
May 27th, 2015 at 7:55:39 PM permalink
Putting video poker strategy into code is both tedious and error prone. I avoid it as much as I can. Fortunately, JB is really good at it.
“Extraordinary claims require extraordinary evidence.” -- Carl Sagan
MathExtremist
MathExtremist
Joined: Aug 31, 2010
  • Threads: 88
  • Posts: 6526
May 27th, 2015 at 8:08:52 PM permalink
Quote: RS

I already know the best hold. I don't know how to code the best hold strategy, other than hard-coding it.


It doesn't matter whether *you* know the best hold, your software has to know the best hold. That means you either enter it or let the computer figure it out -- those are the only two options, really. If you don't want to let your computer figure it out then you've got to commit to at least entering in 134459 hold instructions (that's 52c5, discounting suit-coloring differences).

How to represent the hold may hinge on how you represent the cards in the first place. If you use a 64-bit int with only 5 bits set (representing the cards in the hand) then you could just represent the hold with only the bits to keep, from 0 to all 5 bits. If you have the hand's cards in an array, I'd first sort them and then use a 5-bit number to indicate which cards to hold. Binary 11111 (0x1F) would be hold everything, etc. As with many such problems, the data structures and algorithms you use are tightly intertwined.
"In my own case, when it seemed to me after a long illness that death was close at hand, I found no little solace in playing constantly at dice." -- Girolamo Cardano, 1563

  • Jump to: