Search code examples
javascriptaggregationpoker

Building a poker probabilities calculator - how can I collect data about objects which keep getting deleted and recreated?


I'm currently working on a poker probabilities calculator, which basically exists to predict a user's odds of winning a game of poker, based on his/her starting hand. It 'plays' millions of games, then aggregates how often each starting hand resulted in its owner having the highest ranking hand.

I have a lot of the game-playing code already worked out, which you can see below:

function playPoker(tableSize) {

//Create the players, the deck and the card table which stores the 5 cards the players have in common
var players = createPlayers(tableSize);
var deck = createDeck();
var cardTable = new CardTable();

//Deal each player two cards
for (i = 0; i < 2; i++) {
    for (j = 0; j < players.length; j++) {
        deal(deck, players[j]);
    }
}

//Put five cards down on the table
for (k = 0; k < 5; k++) {
    deal(deck, cardTable);
}

//Check for various winning hands here for each player
for (m = 0; m < players.length; m++) {

    //Merge the player's two cards with the five cards on the table
    var subjectCards = (players[m].cards).concat(cardTable.cards);

    //Make an array of the values of each of the seven cards, which will be used to determine 4 of a kind, 3 of a kind and pairs
    var valuesInOrder = getValuesInOrder(subjectCards);

    //Create a dummy array, so that valuesInOrder remains unchanged
    var straightValues = valuesInOrder.slice();

    //Remove any duplicate card, meaning that the array contains only unique values (i.e. 2, 4, 5, 7, K ... NOT 2, 2, 2, 8, K, K, A)
    var straightValues = straightenUp(straightValues);

    //Calculate how many pairs are in the hand
    var numPairs = howManyPairs(valuesInOrder);

    //Check whether the player has a royal flush, the highest ranking hand - then check the other hands by ranking
    checkRoyalFlush(subjectCards, straightValues);

    checkStraightFlush(subjectCards, straightValues);

    checkFourOAK(valuesInOrder);

    checkFullHouse(valuesInOrder)

    checkFlush(subjectCards);

    checkStraight(straightValues);

    checkThreeOAK(valuesInOrder);

    checkTwoPairs(numPairs);

    checkPair(numPairs);

}

}`

Basically, each card is an object with a suit property (from 1 to 4) and a value property (from 2 to 14). I've got all the logic for calculating rankings working pretty effectively - but I don't know how to collate the data for each card object (i.e. how often K♥ K♠ led to the highest ranking hand, how many times out of 50 million?)

Obviously I could create if-statements which increment every time the right starting hand wins, but I'd need to make 52^2 of them. Does anyone have a more elegant solution to this? Thanks!


Solution

  • You only need a dictionary with 169 keys, all the unique starting hands. Their exact suits don't matter, only if they're suited, rainbow or a pair. With such a dictionary you can increment the corresponding value of the highest ranking hand.