### Poker Logic

Posted on: June 7, 2016 1:31:50 AM

Another programming challenge that I decided to do was a poker challenge The goal of this challenge is to parse 1000 random poker hands of 2 players and determine how many times the first player wins. This was actually quite a fun challenge and I suggest you try to do it on your own even though I'm posting my code.

I decided to do this in a more TDD way than I normally do. So just as I started, I'll start by posting all of my unit tests. Granted, I didn't have them all at the time of development, but I don't think it's necessary to post what I did every step of the way.

PokerTests.cs
```using NUnit.Framework;
using Poker_Kata;

namespace Poker_Tests
{
[TestFixture]
public class PokerTests
{
private Player P1;
private Player P2;

[Test]
public void P13OfAKind()
{
P1.SetHand("3D", "3H", "3C", "4D", "7D");
P2.SetHand("2S", "2D", "2C", "AS", "KS");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(1));
Assert.That(winners[0].Player, Is.EqualTo(P1));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.ThreeKind));
}

[Test]
public void P1FourKind()
{
P1.SetHand("2D", "2S", "2C", "2H", "TD");
P2.SetHand("2S", "AS", "4S", "5S", "6S");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(1));
Assert.That(winners[0].Player, Is.EqualTo(P1));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.FourKind));
}

[Test]
public void P1HighCard()
{
P1.SetHand("2D", "3D", "4D", "5D", "8C");
P2.SetHand("2C", "3S", "4S", "5S", "7S");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(1));
Assert.That(winners[0].Player, Is.EqualTo(P1));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.HighCard));
}

[Test]
public void P1HighPair()
{
P1.SetHand("3D", "3H", "4D", "5D", "6D");
P2.SetHand("2S", "2C", "QS", "KD", "AS");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(1));
Assert.That(winners[0].Player, Is.EqualTo(P1));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.Pair));
}

[Test]
public void P1Pair()
{
P1.SetHand("2D", "2H", "4D", "5D", "7D");
P2.SetHand("2C", "3S", "4S", "5S", "7S");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(1));
Assert.That(winners[0].Player, Is.EqualTo(P1));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.Pair));
}

[Test]
public void P1RoyalFlush()
{
P2.SetHand("AS", "2S", "3S", "4S", "5S");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(1));
Assert.That(winners[0].Player, Is.EqualTo(P1));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.StraightFlush));
}

[Test]
public void P1Straight()
{
P1.SetHand("2D", "3H", "4C", "5D", "6D");
P2.SetHand("2S", "2D", "2C", "AS", "AS");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(1));
Assert.That(winners[0].Player, Is.EqualTo(P1));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.Straight));
}

[Test]
public void P1TwoPair()
{
P1.SetHand("2D", "2H", "3D", "3D", "7D");
P2.SetHand("2S", "3S", "4S", "AS", "AS");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(1));
Assert.That(winners[0].Player, Is.EqualTo(P1));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.TwoPair));
}

[Test]
public void P1TwoPairHighCard()
{
P2.SetHand("4S", "4D", "2S", "KS", "2C");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(1));
Assert.That(winners[0].Player, Is.EqualTo(P1));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.TwoPair));
}

[Test]
public void P2AceHighCard()
{
P1.SetHand("2D", "3D", "4S", "5D", "7D");
P2.SetHand("2S", "3S", "6D", "5S", "AS");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(1));
Assert.That(winners[0].Player, Is.EqualTo(P2));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.HighCard));
}

[Test]
public void P2Flush()
{
P2.SetHand("2S", "TS", "4S", "5S", "6S");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(1));
Assert.That(winners[0].Player, Is.EqualTo(P2));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.Flush));
}

[Test]
public void P2FullHouse()
{
P2.SetHand("2S", "2D", "2C", "3S", "3D");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(1));
Assert.That(winners[0].Player, Is.EqualTo(P2));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.FullHouse));
}

[Test]
public void P2FullHouse3CardHigher()
{
P2.SetHand("4S", "4D", "4C", "2S", "2D");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(1));
Assert.That(winners[0].Player, Is.EqualTo(P2));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.FullHouse));
}

[Test]
public void P2HighCard2()
{
P1.SetHand("8C", "TS", "KC", "9H", "4S");
P2.SetHand("7D", "2S", "5D", "3S", "AC");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(1));
Assert.That(winners[0].Player, Is.EqualTo(P2));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.HighCard));
}

[Test]
public void P2HighCard3()
{
P1.SetHand("4D", "5H", "TH", "QS", "KS");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(1));
Assert.That(winners[0].Player, Is.EqualTo(P2));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.HighCard));
}

[Test]
public void P2HighFlush()
{
P1.SetHand("4D", "KD", "QD", "JD", "TD");
P2.SetHand("2S", "AS", "4S", "5S", "6S");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(1));
Assert.That(winners[0].Player, Is.EqualTo(P2));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.Flush));
}

[Test]
public void P2LowStraight()
{
P2.SetHand("2D", "3H", "4C", "5D", "6D");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(1));
Assert.That(winners[0].Player, Is.EqualTo(P2));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.Straight));
}

[Test]
public void P2StraightFlush()
{
P2.SetHand("AS", "2S", "3S", "4S", "5S");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(1));
Assert.That(winners[0].Player, Is.EqualTo(P2));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.StraightFlush));
}

[Test]
public void P2TwoPair()
{
P1.SetHand("2D", "2H", "3D", "3D", "7D");
P2.SetHand("4S", "4D", "2S", "AS", "2C");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(1));
Assert.That(winners[0].Player, Is.EqualTo(P2));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.TwoPair));
}

[Test]
public void PairTie()
{
P1.SetHand("2D", "2H", "4D", "5D", "6D");
P2.SetHand("2S", "2C", "4S", "5S", "6S");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(2));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.Pair));
}

[OneTimeSetUp]
public void TestsSetup()
{
P1 = new Player { Name = "P1" };
P2 = new Player { Name = "P2" };
}

[Test]
public void Tie()
{
P1.SetHand("2D", "3D", "4D", "5D", "6D");
P2.SetHand("2S", "3S", "4S", "5S", "6S");

var winners = Poker.DetermineWinner(P1, P2);

Assert.That(winners.Length, Is.EqualTo(2));
Assert.That(winners[0].Hand, Is.EqualTo(Hand.StraightFlush));
}
}
}
```

Now we'll need the Card, Player, and PokerHand helper classes. These are simple POCO helpers just to hold some information for whatever is utilizing the code.

Card.cs
```namespace Poker_Kata
{
public enum Faces
{
Club,
Diamond,
Heart
}

public class Card
{
public Card()
{
}

public Card(int value, Faces face)
{
Value = value;
Face = face;
}

public Card(string card)
{
switch (card[0])
{
case '2':
Value = 2;
break;

case '3':
Value = 3;
break;

case '4':
Value = 4;
break;

case '5':
Value = 5;
break;

case '6':
Value = 6;
break;

case '7':
Value = 7;
break;

case '8':
Value = 8;
break;

case '9':
Value = 9;
break;

case 'T':
Value = 10;
break;

case 'J':
Value = 11;
break;

case 'Q':
Value = 12;
break;

case 'K':
Value = 13;
break;

case 'A':
Value = 14;
break;
}

switch (card[1])
{
case 'H':
Face = Faces.Heart;
break;

case 'D':
Face = Faces.Diamond;
break;

case 'C':
Face = Faces.Club;
break;

case 'S':
break;
}
}

public Faces Face { get; set; }

public int Value { get; set; }

public override string ToString()
{
return Value + " " + Face.ToString();
}
}
}
```
Player.cs
```using System.Collections.Generic;

namespace Poker_Kata
{
public class Player
{
public Card[] Hand { get; set; }

public string Name { get; set; }

public void SetHand(params string[] cards)
{
List hand = new List();

foreach (string card in cards)
{
}

Hand = hand.ToArray();
}
}
}
```
PokerHand.cs
```namespace Poker_Kata
{
public class PokerHand
{
public Card[] Cards { get; set; }

public Hand Hand { get; set; }

public Player Player { get; set; }
}
}
```

Next is the heart of the project, the Poker class. This class will hold all the of the logic and rules of poker and allow you to pass in a number of players with their hands and will determine what hands they hold along with who won the hand. I didn't make this work with just any poker game, although it wouldn't take much work to do so, I only did enough to handle each player having 5 cards.

Poker.cs
```using System.Linq;

namespace Poker_Kata
{
public enum Hand
{
HighCard,
Pair,
TwoPair,
ThreeKind,
FullHouse,
Straight,
Flush,
FourKind,
StraightFlush
}

public static class Poker
{
public static PokerHand[] DetermineWinner(params Player[] players)
{
PokerHand[] pokerHands = new PokerHand[players.Length];

for (int i = 0; i < players.Length; i++)
{
var hand = GetHand(players[i].Hand);
hand.Player = players[i];

pokerHands[i] = hand;
}

pokerHands = pokerHands.Where(p => p.Hand == pokerHands.Max(p1 => p1.Hand)).ToArray();

if (pokerHands.Length > 1)
{
pokerHands = FilterByHigherHand(pokerHands);

if (pokerHands.Length > 1)
{
pokerHands = FilterByHighCard(pokerHands);
}
}

return pokerHands;
}

public static PokerHand GetHand(Card[] hand)
{
PokerHand pokerHand = new PokerHand();
pokerHand.Cards = hand = hand.OrderByDescending(c => c.Value).ToArray();
pokerHand.Hand = (hand.CountBy(c => c.Face == hand[0].Face) >= 5) ? Hand.Flush : Hand.HighCard;

if (CheckIsStraight(hand))
{
pokerHand.Hand = pokerHand.Hand == Hand.Flush ? Hand.StraightFlush : Hand.Straight;
}

int previousCard = 0;

foreach (var card in hand)
{
if (previousCard == card.Value) continue;

int valueCount = hand.CountBy(c => c.Value == card.Value);

if (valueCount == 2)
{
if (pokerHand.Hand == Hand.Pair)
{
pokerHand.Hand = Hand.TwoPair;
}
else if (pokerHand.Hand == Hand.ThreeKind)
{
pokerHand.Hand = Hand.FullHouse;
}
else
{
pokerHand.Hand = Hand.Pair;
}
}
else if (valueCount == 3)
{
if (pokerHand.Hand == Hand.Pair)
{
pokerHand.Hand = Hand.FullHouse;
}
else
{
pokerHand.Hand = Hand.ThreeKind;
}
}
else if (valueCount == 4)
{
pokerHand.Hand = Hand.FourKind;
}

previousCard = card.Value;
}

return pokerHand;
}

private static bool CheckIsStraight(Card[] hand)
{
int previousValue = 0;

foreach (var card in hand.OrderBy(c => c.Value))
{
if (previousValue > 0)
{
if (card.Value == 14 && previousValue == 5) break;

if (card.Value != previousValue + 1)
{
return false;
}
}

previousValue = card.Value;
}

return true;
}

private static PokerHand[] FilterByHighCard(PokerHand[] pokerHands)
{
foreach (var hand in pokerHands)
{
hand.Cards = hand.Cards.OrderByDescending(c => c.Value).ToArray();

if ((hand.Hand == Hand.Straight || hand.Hand == Hand.StraightFlush) &&
(hand.Cards.Max(c => c.Value) == 14 && hand.Cards.Min(c => c.Value) == 2))
{
hand.Cards[0].Value = 1;
hand.Cards = hand.Cards.OrderByDescending(c => c.Value).ToArray();
}
}

for (int i = 0; i < pokerHands[0].Cards.Length; i++)
{
int highCard = pokerHands.Select(p => p.Cards[i]).Max(c => c.Value);

pokerHands = pokerHands.Where(p => p.Cards[i].Value == highCard).ToArray();

if (pokerHands.Length == 1) break;
}

return pokerHands;
}

private static PokerHand[] FilterByHigherHand(PokerHand[] pokerHands)
{
switch (pokerHands[0].Hand)
{
case Hand.Pair:
pokerHands = FilterBySet(pokerHands, 2);
break;

case Hand.TwoPair:
pokerHands = FilterBySet(pokerHands, 2);

if (pokerHands.Length > 1)
{
pokerHands = FilterBySet(pokerHands, 2, false);
}
break;

case Hand.ThreeKind:
case Hand.FullHouse:
pokerHands = FilterBySet(pokerHands, 3);
break;

case Hand.FourKind:
pokerHands = FilterBySet(pokerHands, 4);
break;
}

return pokerHands;
}

private static PokerHand[] FilterBySet(PokerHand[] pokerHands, int setCount, bool checkMax = true)
{
var groupedCards = pokerHands.Select(p => p.Cards.GroupBy(c => c.Value).Where(g => g.Count() == setCount));
int checkDigit;

if (checkMax)
{
checkDigit = groupedCards.SelectMany(g => g).Max(g => g.Key);
}
else
{
checkDigit = groupedCards.SelectMany(g => g).Min(g => g.Key);
}

pokerHands = pokerHands.Where(p => p.Cards.CountBy(c => c.Value == checkDigit) == setCount).ToArray();

return pokerHands;
}
}
}
```

In order for this code to compile, you'll need one more helper class that holds the extension CountBy.

Extensions.cs
```using System;
using System.Collections.Generic;

namespace Poker_Kata
{
public static class Extensions
{
public static int CountBy(this IEnumerable source, Func comparer)
{
int count = 0;

foreach (var s in source)
{
if (comparer(s))
{
count++;
}
}

return count;
}
}
}
```

I believe this logic should be able to handle any 5 card poker hand, if not, please post a comment on what hand it fails on and I will happily take a look.

Now that we have all the logic and the unit tests passing, we need to read in the .txt document that the challenge provides that holds all the hands. I did this in the Program class, so when the program executes, it completes the challenge assuming you give the argument of the .txt document.

Program.cs

```using System;
using System.IO;
using System.Linq;

namespace Poker_Kata
{
internal class Program
{
{
string[] contents;

using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read))
using (var sr = new StreamReader(fs))
{
contents = sr.ReadToEnd().Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
}

return contents;
}

private static void Main(string[] args)
{
if (args.Length > 0)
{
int p1Wins = 0;
int p2Wins = 0;
int ties = 0;

Player p1 = new Player() { Name = "P1" };
Player p2 = new Player() { Name = "P2" };

foreach (var hand in cards)
{
var game = hand.Split(' ');

p1.SetHand(game.Take(5).ToArray());
p2.SetHand(game.Skip(5).Take(5).ToArray());

var winners = Poker.DetermineWinner(p1, p2);

p1.Hand = p1.Hand.OrderBy(c => c.Value).ToArray();
p2.Hand = p2.Hand.OrderBy(c => c.Value).ToArray();

if (winners.Length == 2)
{
ties++;
}
else if (winners[0].Player.Equals(p1))
{
p1Wins++;
}
else
{
p2Wins++;
}
}

Console.WriteLine("P1: {0}\r\nP2: {1}\r\nTies: {2}", p1Wins, p2Wins, ties);
}
}
}
}
```

I do hope, once again, that you attempt this challenge properly without just using my code to get the answer. I know that my code could be optimized further, but I see no need to do so at this time. Thanks for reading and happy coding.

ffree gay chat [url="https://chatcongays.com"]free gay chat room[/url] google zoom gay chat rooms

GenniesrPa September 16, 2022 4:57:41 AM

help on college essay [url="https://au-bestessays.org"]essay writer generator[/url] help writing a argumentative essay

MarrissrPa September 20, 2022 1:10:35 AM

buy essay papers online [url="https://bestcampusessays.com"]write my history essay[/url] essay writing service ratings

DorolisasrPa September 20, 2022 8:21:53 PM

easy essay writer [url="https://besteasyessays.org"]essay writers[/url] custom essays online

MartysrPa September 21, 2022 6:42:51 PM

will someone write my essay for me [url="https://bestessayreviews.net"]college essay writing help[/url] cheapest essay writing service

MerolasrPa September 22, 2022 2:43:49 PM

custom essay writer [url="https://bestessaysden.com"]community service essay[/url] help in essay writing

AshlensrPa September 23, 2022 10:29:13 AM

essay homework help online [url="https://bestsessays.org"]analysis essay help[/url] mba essay writing service

CharitasrPa September 25, 2022 12:03:26 AM

NanicesrPa September 25, 2022 7:01:29 PM

ChelsaesrPa September 26, 2022 2:41:41 PM

essaywriting service [url="https://buytopessays.com"]essay editor service[/url] famous essay writers

PennysrPa September 27, 2022 9:52:30 AM

essay cheap [url="https://cheapessaywritingservice1.com"]help with writing essays at university[/url] buy essay papers online

TammiesrPa September 28, 2022 5:39:24 AM

AntoniesrPa September 29, 2022 1:35:56 AM

best essay writing service [url="https://customessays-writing.org"]best essay writing websites[/url] help writing a narrative essay

RhiamonsrPa September 29, 2022 9:13:41 PM

essay writing website [url="https://customessaywwriting.com"]write my history essay[/url] write my essay help

CharosrPa September 30, 2022 4:04:26 PM

english essay writing help [url="https://customs-essays-writing.org"]best admission essay editing service[/url] essay writer helper

DronasrPa October 1, 2022 10:45:05 AM

professional custom essays [url="https://firstessayservice.net"]essay help pros[/url] can you write my essay

TwylasrPa October 2, 2022 6:14:31 AM

professional essay writing help [url="https://geniusessaywriters.net"]best mba essay editing service[/url] cheap essay buy

LeilahsrPa October 3, 2022 2:59:50 AM

help with writing essay [url="https://howtobuyanessay.com"]help writing college essays[/url] best custom essay service

CthrinesrPa October 4, 2022 12:52:58 AM

essay custom [url="https://lawessayhelpinlondon.com"]buy cheap essays online[/url] i need help writing an essay for college

GinniesrPa October 9, 2022 12:47:10 PM

essay on social service [url="https://ukessayservice.net"]essay writer cheap[/url] buy an essay

VivienesrPa October 11, 2022 7:05:08 PM

college entrance essay writing service [url="https://writemyessaycheap24h.com"]community service essay sample[/url] where to buy essays

EastersrPa October 13, 2022 10:09:31 AM

medical school essay service [url="https://bestcampusessays.com"]what is a good essay writing service[/url] what can i write my essay on

DorolisasrPa November 19, 2022 7:18:11 AM

custom admission essay [url="https://besteasyessays.org"]professional college application essay writers[/url] writing an essay help

MartysrPa November 20, 2022 2:09:20 PM

essay service [url="https://bestessayreviews.net"]essay writing help for students[/url] custom essays review

MerolasrPa November 21, 2022 9:55:10 PM

online essay writers [url="https://bestessaysden.com"]essays custom[/url] essay revision help online

AshlensrPa November 23, 2022 6:51:30 AM

customized essays [url="https://bestsessays.org"]help writing essay[/url] best essay

CharitasrPa November 24, 2022 2:31:10 PM

online essay help chat [url="https://buyacademicessay.com"]us based essay writing service[/url] college essay writers block

NanicesrPa November 25, 2022 11:54:12 PM

Contact Me
Recent Blog Activity
Blog Archive