DEV Community

dev.to staff
dev.to staff

Posted on

Daily Challenge #258 - Ranking Poker Hands

A famous casino is suddenly faced with a sharp decline of their revenues. They decide to offer Texas hold'em also online. Can you help them by writing an algorithm that can rank poker hands?

Create a poker hand that has a method to compare itself to another poker hand:
PokerHand.prototype.compareWith = function(hand){...};

A poker hand has a constructor that accepts a string containing 5 cards:
var hand = new PokerHand("KS 2H 5C JD TD");

The characteristics of the string of cards are:

  • Each card consists of two characters, where
  • The first character is the value of the card: 2, 3, 4, 5, 6, 7, 8, 9, T(en), J(ack), Q(ueen), K(ing), A(ce)
  • The second character represents the suit: S(pades), H(earts), D(iamonds), C(lubs)
  • A space is used as card separator between cards

The result of your poker hand compare can be one of these 3 options:

var Result = 
{
    "win": 1,
    "loss": 2,
    "tie": 3
}

Notes

  • Apply the Texas Hold'em rules for ranking the cards.
  • Low aces are NOT valid in this challenge.
  • There is no ranking for the suits.

Examples
("2H 3H 4H 5H 6H", "AS AD AC AH JD") => WIN "Straight flush wins of 4 of a kind"
("2H 3H 4H 5H 6H", "KS AS TS QS JS") => LOSS "Highest straight flush wins"

Tests
("2H 3H 5H 6H 7H", "2S 3H 4H 5S 6C")
("2S 3H 4H 5S 6C", "3D 4C 5H 6H 2S")
("2S AH 4H 5S KC", "AH AC 5H 6H 7S")

Good luck!


This challenge comes from FrankK on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

Discussion (17)

Collapse
sam_ferree profile image
Sam Ferree • Edited on

Sad this is a bit too difficult for me to do with Befunge, even Funge++, but I did think it could work quite well if done functionally.

This C# solution seems to work, have not tested beyond the initial to test cases

Edit: Did not add HighCard rules....

using System;
using System.Collections.Generic;
using System.Linq;
using HandRule = System.Func<string[], bool>;
namespace ConsoleSandbox
{
  public class PokerRanker
  {
    public static List<char> Ranks = new List<char> { '2', '3', '4', '5', '6', '7', '8',
      '9', 'T', 'J', 'Q', 'K', 'A' };
    public static List<char> Suits = new List<char> { 'S', 'H', 'D', 'C' };

    public List<HandRule> Rules = new List<HandRule>();

    public PokerRanker()
    {
      var ranksRanked = new List<char>(Ranks);
      ranksRanked.Reverse();

      char[] invalidStraightStarts = { 'J', 'Q', 'K', 'A' };

      Rules.AddRange(ranksRanked.Except(invalidStraightStarts).Select(rank =>
        StraightFlush(rank)));

      Rules.AddRange(ranksRanked.SelectMany(fourRank =>
        ranksRanked.Except(new[] {fourRank}).Select(highCard =>
          FourOfAKind(fourRank, highCard))));

      Rules.Add(Flush());

      Rules.AddRange(ranksRanked.Except(invalidStraightStarts).Select(rank =>
        Straight(rank)));

      Rules.AddRange(ranksRanked.SelectMany(threeRank =>
        ranksRanked.Except(new[] { threeRank }).Select(highCard =>
        ThreeOfAKind(threeRank, highCard))));

      Rules.AddRange(ranksRanked.SelectMany(pairRank =>
        ranksRanked.Except(new[] { pairRank }).Select(highCard =>
        Pair(pairRank, highCard))));

      Rules.AddRange(ranksRanked.Select(rank =>
        HighCard(rank)));
    }

    public string Rank(string[] myHand, string[] theirHand)
    {
      var mine = Rules.FindIndex(rule => rule(myHand));
      var theirs = Rules.FindIndex(rule => rule(theirHand));
      return mine < theirs
        ? "Win!"
        : theirs < mine
          ? "Lose!"
          : "Draw!";
    }

    public HandRule HighCard(char rank) => hand =>
      hand.Any(card => card[0] == rank);

    public HandRule Pair(char pairRank, char highCard) => hand =>
      hand.Count(card => card[0] == pairRank) == 2
      && HighCard(highCard)(hand);

    public HandRule ThreeOfAKind(char threeRank, char highCard) => hand =>
      hand.Count(card => card[0] == threeRank) == 3
      && HighCard(highCard)(hand);

    public HandRule Straight(char startingRank) => hand =>
    {
      var start = Ranks.IndexOf(startingRank);
      var ranks = Ranks.GetRange(start, 5);
      return ranks.All(rank => hand.Any(card => card[0] == rank));
    };

    public HandRule Flush() => hand =>
      hand.All(card => card[1] == hand[0][1]);

    public HandRule FullHouse(char threeRank, char pairRank) => hand =>
      ThreeOfAKind(threeRank, threeRank)(hand) &&
      Pair(pairRank, pairRank)(hand);

    public HandRule FourOfAKind(char fourRank, char highCard) => hand =>
      hand.Count(card => card[0] == fourRank) == 4
      && hand.Any(card => card[0] == highCard);

    public HandRule StraightFlush(char startingRank) => hand =>
      Straight(startingRank)(hand)
      && Flush()(hand);
  }
}
Collapse
sam_ferree profile image
Sam Ferree

I think I also missed flush with high card... hrmm

Collapse
miketalbot profile image
Mike Talbot • Edited on

function PokerHand(hand) {
    this.hand = hand
}
PokerHand.prototype.compareWith = function(hand) {
    return compareHands(this.hand, hand.hand || hand)
}

const order = "23456789TJQKA"
function getHandDetails(hand) {
    const cards = hand.split(" ")
    const faces = cards.map(a => String.fromCharCode([77 - order.indexOf(a[0])])).sort()
    const suits = cards.map(a => a[1]).sort()
    const counts = faces.reduce(count, {})
    const duplicates = Object.values(counts).reduce(count, {})
    const flush = suits[0] === suits[4]
    const first = faces[0].charCodeAt(0)
    //Also handle low straight
    const lowStraight = faces.join("") === "AJKLM"
    const straight = lowStraight || faces.every((f, index) => f.charCodeAt(0) - first === index)
    let rank =
        (flush && straight && 1) ||
        (duplicates[4] && 2) ||
        (duplicates[3] && duplicates[2] && 3) ||
        (flush && 4) ||
        (straight && 5) ||
        (duplicates[3] && 6) ||
        (duplicates[2] > 1 && 7) ||
        (duplicates[2] && 8) ||
        9

    return { rank, value: faces.sort(byCountFirst).join("") }

    function byCountFirst(a, b) {
        //Counts are in reverse order - bigger is better
        const countDiff = counts[b] - counts[a]
        if (countDiff) return countDiff // If counts don't match return
        if (lowStraight) {
            a = a === "A" ? "N" : a
            b = b === "A" ? "N" : b
        }
        return b > a ? -1 : b === a ? 0 : 1
    }
    function count(c, a) {
        c[a] = (c[a] || 0) + 1
        return c
    }
}

function compareHands(h1, h2) {
    let d1 = getHandDetails(h1)
    let d2 = getHandDetails(h2)
    if (d1.rank === d2.rank) {
        if (d1.value < d2.value) {
            return "WIN"
        } else if (d1.value > d2.value) {
            return "LOSE"
        } else {
            return "DRAW"
        }
    }
    return d1.rank < d2.rank ? "WIN" : "LOSE"
}

Collapse
miketalbot profile image
Mike Talbot
Collapse
mellen profile image
Matt Ellen • Edited on

Created a python version

link to gist if embed isn't working

use it like:

python rank.py AS AC 2H 2C KD JC JD QH JH AS
Collapse
jameshewitt38 profile image
James Hewitt

Whether you want to play live in joker slot 123 a casino or card room, play at home with an app like ClubGG, or play online at sites like PokerStars, 888Poker, or partypoker, you must learn the sequence of poker hands from best to worst.

What is the total number of poker hands? Royal flush, straight flush, four of a kind, full house, flush, straight, three of a kind, two pair, one pair, and high card are the ten potential five-card poker hands. In joker slot 123 Texas Hold'em, there are 1,326 possible two-card starting hands. Pocket aces is the finest beginning hand, while seven-two offsuit is the worst.

Is a three-pair hand considered a poker hand? Three pair isn't a poker hand at all. Poker hands are made up of five cards, not six. If your hand is 7-6 and the board reads 7-6-A-A-2, you don't have three pairs. With a six kicker, you have two pair, aces, and sevens. What is the best joker slot 123 poker hand? A royal flush is the best hand in poker, consisting of an Ace, King, Queen, Jack, and Ten in the same suit. Royal flushes are unrivaled and incredibly difficult to come by.

Collapse
jameshewitt38 profile image
James Hewitt • Edited on

The poker-hand rankings are a useful tool for making in-game decisions because they classify the power of the various hands you can play.
All varieties of the game are underpinned by a common poker-hand rankings system that classifies the relative strength of different sorts of poker hands so that players may choose which hand is the best.

It's employed in popular poker games like Texas Holdem and Omaha, as well as poker-based casino games like 3-card poker. If you're serious about winning, you'll need to know it.

Scroll down to see our guide to poker hand rankings, which includes a useful chart that you can save to your phone as a cheat sheet.

It's worth noting that not all poker games determine the best hand based on the poker hand rankings' highest ranked hand. In most game types in agensloto, poker-hand rankings determine the best poker hand in one of three ways.

'Hi' games, perhaps the most obvious use of rankings, are those in which the best poker hand is determined by the hand that ranks highest on the chart above.

Texas Holdem and Seven-Card Stud are two popular variants.

Collapse
apostoins profile image
apostoins • Edited on

OH! So this is how it really works. Thank you for explaining to me. I am new to gambling, and I am very interested in this. It brings me true satisfaction and happiness when I wing something. I started with making small slot deposits and playing on online casinos. Recently I was in a real casino and watched how my friend was playing poker. I understood that I need to learn how to play this game. It seemed to be so interesting. I have never thought that a person who was contra gambling like me will love going to casinos.


cisdetroit.org/

Collapse
bravemaster619 profile image
bravemaster619

I once implemented with Node.js. It was a little bit complicated as I remember. I think there is no quick and easy solution.