DEV Community

Discussion on: Daily Challenge #258 - Ranking Poker Hands

Collapse
 
sam_ferree profile image
Sam Ferree • Edited

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