using System.Collections.Generic;
using System.ComponentModel;
private const int NumberOfPlayers = 4;
public static void Main()
var game = new Game(NumberOfPlayers);
Console.WriteLine(game.HandDescriptions());
Console.WriteLine(game.WinnerDescription());
private Deck Deck { get; set; }
private List<Player> Players { get; set; }
private const int NumberOfCardsPerPerson = 5;
public Game(int numberOfPlayers)
CreatePlayers(numberOfPlayers);
Players.ForEach(p => p.HandStrength = PokerService.DetermineHandStrength(p.Hand));
private void CreatePlayers(int numberOfPlayers)
Players = new List<Player>();
for (var i = 1; i <= numberOfPlayers; i++)
Name = string.Format("Player {0}", i)
if (NumberOfCardsPerPerson * Players.Count > Deck.CardCount)
throw new ArgumentException("There are not enough cards in the deck to deal to each player.");
for (var i = 1; i <= NumberOfCardsPerPerson; i++)
foreach (var player in Players)
player.ReceiveCard(Deck.TakeCard());
public string HandDescriptions()
var sb = new StringBuilder();
foreach (var player in Players)
public string WinnerDescription()
.OrderByDescending(p => p.HandStrength.Strength)
var tiedPlayers = Players.Where(p => p.HandStrength == winner.HandStrength).ToList();
if (tiedPlayers.Count() > 1)
var sb = new StringBuilder();
sb.AppendFormat("There is a {0}-way tie between ", tiedPlayers.Count());
for (var i = 0; i < tiedPlayers.Count(); i++)
sb.Append(i == tiedPlayers.Count - 1 ? " and " : ", ");
sb.AppendFormat(tiedPlayers[i].Name);
return string.Format("The winner is: {0} with a {1}", winner.Name, winner.HandStrength.Description);
private List<Card> Cards { get; set; }
get { return Cards.Count; }
throw new NullReferenceException("The deck is out of cards!");
var card = Cards.First();
for (var i = 0; i < Cards.Count; i++)
var randomCard = rnd.Next(i, Cards.Count);
Cards[i] = Cards[randomCard];
Cards[randomCard] = temp;
private void BuildFullDeck()
Cards = new List<Card>();
foreach (CardSuit suit in Enum.GetValues(typeof(CardSuit)))
foreach (CardValue value in Enum.GetValues(typeof(CardValue)))
public CardSuit Suit { get; set; }
public CardValue Value { get; set; }
public override string ToString()
return string.Format("[{0}{1}]", Value.Description(), Suit.Description());
public string Name { get; set; }
public IList<Card> Hand { get; set; }
public HandStrength HandStrength { get; set; }
public void ReceiveCard(Card card)
public override string ToString()
var s = new StringBuilder();
s.AppendLine(Name + ": ");
foreach (var card in Hand)
s.AppendLine("\nResult: " + HandStrength.Description);
public class HandStrength
public string Description { get; set; }
public float Strength { get; set; }
public static class PokerService
public static HandStrength DetermineHandStrength(IList<Card> cards)
var handdstength = new HandStrength();
var cardValuelist = cards.Select(c => (int)c.Value).ToList();
var category = HandCategory.NotSet;
var secondaryAddition = 0;
var terciaryAddition = 0;
var terciary2Addition = 0;
var terciary3Addition = 0;
var description = string.Empty;
var highCard = cardValuelist.Max();
var isStraight = cardValuelist.Max() - cardValuelist.Min() == 4;
var isFlush = cards.All(c => c.Suit == cards.First().Suit);
if (isStraight && isFlush)
category = HandCategory.StraightFlush;
primaryAddition = highCard;
description = ((CardValue)highCard == CardValue.Ace)? "Royal Flush" : "Straight Flush to the " + (CardValue)highCard;
category = HandCategory.Flush;
primaryAddition = highCard;
description = (CardValue)highCard + " high flush.";
category = HandCategory.Straight;
primaryAddition = highCard;
description = "Straight to the " + (CardValue)highCard;
var groups = cardValuelist.GroupBy(x => x).ToList();
var hasPairing = groups.Any(g => g.Count() > 1);
var fourOfAKind = groups.FirstOrDefault(g => g.Count() == 4);
var threeOfAKind = groups.FirstOrDefault(g => g.Count() == 3);
var pairs = groups.Where(g => g.Count() == 2).ToList();
category = HandCategory.FourOfAKind;
primaryAddition = fourOfAKind.Key;
secondaryAddition = cardValuelist.Where(x => x != fourOfAKind.Key).Max();
description = string.Format("Four of a Kind, {0}s", (CardValue)fourOfAKind.Key);
else if (threeOfAKind != null && pairs.Any())
category = HandCategory.FullHouse;
primaryAddition = threeOfAKind.Key;
secondaryAddition = pairs.First().Key;
description = string.Format("Full House, {0}s over {1}s", (CardValue)threeOfAKind.Key, (CardValue)pairs.First().Key);
else if (threeOfAKind != null)
category = HandCategory.ThreeOfAKind;
primaryAddition = threeOfAKind.Key;
secondaryAddition = cardValuelist.Where(x => x != threeOfAKind.Key).Max();
terciaryAddition = cardValuelist.Where(x => x != threeOfAKind.Key).Min();
description = string.Format("Set of {0}s", (CardValue)threeOfAKind.Key);
else if (pairs.Count() == 2)
category = HandCategory.TwoPair;
primaryAddition = pairs.Select(p => p.Key).Max();
secondaryAddition = pairs.Select(p => p.Key).Min();
terciaryAddition = groups.First(g => g.Count() == 1).Key;
description = string.Format("Two Pair, {0}s over {1}s", (CardValue)primaryAddition, (CardValue)secondaryAddition);
else if (pairs.Count == 1)
category = HandCategory.Pair;
primaryAddition = pairs.First().Key;
var otherCards = groups.Where(g => g.Count() == 1).Select(g => g.Key).OrderBy(x => x).ToList();
secondaryAddition = otherCards[0];
terciaryAddition = otherCards[1];
terciary2Addition = otherCards[2];
description = string.Format("Pair of {0}s", (CardValue)primaryAddition);
if (category == HandCategory.NotSet)
category = HandCategory.HighCard;
var orderedCards = cardValuelist.OrderByDescending(x => x).ToList();
primaryAddition = orderedCards[0];
secondaryAddition = orderedCards[1];
terciaryAddition = orderedCards[2];
terciary2Addition = orderedCards[3];
terciary3Addition = orderedCards[4];
description = (CardValue)primaryAddition + " High";
var score = ((int)category * 10000000000) +
(primaryAddition * 100000000) +
(secondaryAddition * 1000000) +
(terciaryAddition * 10000) +
(terciary2Addition * 100) +
handdstength.Description = description;
handdstength.Strength = score;
public static class EnumExtentions
public static string Description(this Enum enumVal)
var type = enumVal.GetType();
var memInfo = type.GetMember(enumVal.ToString());
var attributes = memInfo[0].GetCustomAttributes(typeof (DescriptionAttribute), false);
return ((DescriptionAttribute) attributes[0]).Description;