Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I evaluate Texas Hold' em hands with Javascript?

Tags:

javascript

I'm not sure what the best course of action is from here. For each player, I have created an array that holds both the community cards and its own cards, the one thing I have left to do is to evaluate the results.

I could of course brute force check every seven card combination, but a) that wouldn't be very elegant and quick, and b) I wouldn't know how to handle a tie, since then you'd have to look at the remaining high cards.

Here is the fiddle, I've used document.write() for everything, for testing purposes:

https://jsfiddle.net/bjp11yjb/1/

If anyone could point me in the right direction, without confusing me too much, I'd be much obliged!

var suits = ['Clubs', 'Spades', 'Hearts', 'Diamonds'];
var ranks = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King', 'Ace'];
var combinations = ['Royal Flush', 'Straight Flush', 'Four of a Kind', 'Full House', 'Flush', 'Straight', 'Three of a Kind', 'Two Pair', 'One Pair'];
var deck = [];
var players = [new Player(), new Player()];
var table = [];

function Player()  {
    this.hand = [];
    this.result;
}

function Card(suit, rank)   {
    this.suit = suit;
    this.rank = rank;
    this.name = rank + ' of ' + suit;
}


function initDeck() {
    deck = [];

    for(var i = 0; i < 4; i++)   {
        for(var j = 0; j < 13; j++)   {
            deck.push(new Card(suits[i], ranks[j]));
        }
    }

}

function drawCard() {
    var randNumber = Math.floor(Math.random() * deck.length);
    var drawnCard = deck[randNumber];
    deck.splice(randNumber, 1);

    return drawnCard;
}


function dealCards()    {
    for(var i = 0; i < 2; i++)   {
        for(var j = 0; j < players.length; j++)   {
            var drawnCard = drawCard();
            players[j].hand.push(drawnCard);
        }
    }
}

function flop() {
    for(var i = 0; i < 3; i++)   {
        var drawnCard = drawCard();
        table.push(drawnCard);
    }
}

function turn()    {
    var drawnCard = drawCard();
    table.push(drawnCard);
}

function river()    {
    var drawnCard = drawCard();
    table.push(drawnCard);
}

function showDown() {
    for(var i = 0; i < players.length; i++)   {        

        evaluate(i);
        document.write("<br>");   

    }

}

function evaluate(player)  {
    var totalHand = players[player].hand.concat(table);

    for(var i = 0; i < totalHand.length; i++)   {

    }

}


initDeck();
dealCards();
document.write("Player 1: " + players[0].hand[0].name + ' and ' + players[0].hand[1].name + '<br>');
document.write("Player 2: " + players[1].hand[0].name + ' and ' + players[1].hand[1].name + '<br><br>');
flop();
document.write("Flop: " + table[0].name + ', ' + table[1].name + ' and ' + table[2].name + '<br>');
turn();
document.write("Turn: " + table[0].name + ', ' + table[1].name + ', ' + table[2].name + ' and ' + table[3].name + '<br>');
river();
document.write("River: " + table[0].name + ', ' + table[1].name + ', ' + table[2].name + ', ' + table[3].name + ' and ' + table[4].name + '<br>');
showDown();
like image 331
Ryan Wennekes Avatar asked Oct 30 '22 11:10

Ryan Wennekes


1 Answers

My advice would be to implement a series of functions, each function knowing how to test for one particular condition. (Yes, there will be some seemingly redundant code. No, don't worry about it until you're done.)

For example: has_royal_flush(player).

You can then separate the detection logic from the scoring logic. Your scoring logic can be structured however you want. Be aware, however, that the rules can vary here. You will want to write down the exact rules you are using before you start.

You may need to track "best combo card" and "highest non-combo card" as part of your detection, so that a tie-breaking routine can use those fields if both players have the same "base" hand.

For example:

Common:  4 7 8
Player 1: Q 4
Player 2: 10 4

Player 1: Pair
Player 2: Pair
Player 1's best combo card (e.g., "pair of whats"): 4
Player 2's best combo card: 4
Player 1's best non-combo card (i.e., "high card"): Q
Player 2's best non-combo card: 10

In this example, both players have the same "base" - one pair. So to break the tie, you might first ask, "A pair of what?" And in this example, pathologically, both players have a pair of 4's. So you go on to ask, "Okay, since the combo's are tied, what's the highest card?" And the tie is broken on that. It's possible there could be a tie at that level, in which case you'd have to implement another rule.

Because of this expectation of common behaviors, you might consider the different scoring evaluators as objects of some base class.

like image 176
aghast Avatar answered Nov 14 '22 02:11

aghast