I recently implemented a playing Card class and a five-card poker Hand class and a SingleDeck class using C#. I remember working on an old project where the goal was to determine the best five-card poker hand from seven cards. For example, if seven cards are (9d 5c 5h Qc Ah Jc Th) then the best five-card hand is (5c-5h-Jc-Qc-Ah), a pair of fives with A, Q, J kickers.
With all the helper functions already coded, I implemented a function that accepts seven cards and finds the best five-card poker hand. In pseudo-code:
get the source seven cards
initialize a curr best five-card hand
loop 21 times (each possible set of 2 from 7)
remove the indicated two cards
create candidate five-card hand
if candidate is better than curr best hand
best hand = candidate
end-if
end-loop
return curr best hand
There are only 21 ways to remove two cards from seven cards: (0,1), (0,2) . . (4,6), (5,6) and so for clarity I hard-coded the 21 pairs of indices. I could have used two for-loops instead.
Here’s my function:
static Hand BestFiveFromSeven(List"lt"Card"gt" listSeven)
{
int[][] removes = new int[21][];
removes[0] = new int[] { 0, 1 };
removes[1] = new int[] { 0, 2 };
removes[2] = new int[] { 0, 3 };
removes[3] = new int[] { 0, 4 };
removes[4] = new int[] { 0, 5 };
removes[5] = new int[] { 0, 6 };
removes[6] = new int[] { 1, 2 };
removes[7] = new int[] { 1, 3 };
removes[8] = new int[] { 1, 4 };
removes[9] = new int[] { 1, 5 };
removes[10] = new int[] { 1, 6 };
removes[11] = new int[] { 2, 3 };
removes[12] = new int[] { 2, 4 };
removes[13] = new int[] { 2, 5 };
removes[14] = new int[] { 2, 6 };
removes[15] = new int[] { 3, 4 };
removes[16] = new int[] { 3, 5 };
removes[17] = new int[] { 3, 6 };
removes[18] = new int[] { 4, 5 };
removes[19] = new int[] { 4, 6 };
removes[20] = new int[] { 5, 6 };
List"lt"Card"gt" bestFive =
listSeven.GetRange(0, count: 5);
Hand bestHand = new Hand(bestFive);
for (int j = 0; j "lt" 21; ++j) // each pair to remove
{
List"lt"Card"gt" listFive = new List"lt"Card"gt"();
for (int i = 0; i "lt" 7; ++i)
{
if (i == removes[j][0] || i == removes[j][1])
continue;
else
listFive.Add(listSeven[i]);
}
Hand candidate = new Hand(listFive);
if (Hand.Compare(candidate, bestHand) == +1)
{
// Console.WriteLine("New Best Hand Found!");
bestHand = candidate;
}
}
return bestHand;
}
Good fun on a Saturday morning.
Here are three examples of art where a deck of 52 cards has been cut by hand to create a kind of 3D sculpture.

Demo code. Replace “lt” (less-than), “gt”, “lte”, “gte”, “and” with Boolean operator symbols — my lame blog editor sometimes chokes on symbols.
using System;
using System.IO;
using System.Collections.Generic;
namespace Poker
{
internal class PokerProgram
{
static void Main(string[] args)
{
Console.WriteLine("\nBegin poker " +
"best five-card hand from seven cards ");
SingleDeck deck = new SingleDeck(seed: 15);
for (int i = 0; i "lt" 8; ++i)
{
deck.Shuffle();
List"lt"Card"gt" listSeven = deck.DealListCards(7);
Console.Write("\nSeven cards: ");
for (int j = 0; j "lt" 7; ++j)
Console.Write(listSeven[j] + " ");
Console.WriteLine("");
Hand h = BestFiveFromSeven(listSeven);
Console.WriteLine("Best hand : " + h +
" - " + h.GetHandTypeStr());
}
Console.WriteLine("\nEnd ");
Console.ReadLine();
} // Main
// -------------------------------------------------------
static Hand BestFiveFromSeven(List"lt"Card"gt" listSeven)
{
int[][] removes = new int[21][];
removes[0] = new int[] { 0, 1 };
removes[1] = new int[] { 0, 2 };
removes[2] = new int[] { 0, 3 };
removes[3] = new int[] { 0, 4 };
removes[4] = new int[] { 0, 5 };
removes[5] = new int[] { 0, 6 };
removes[6] = new int[] { 1, 2 };
removes[7] = new int[] { 1, 3 };
removes[8] = new int[] { 1, 4 };
removes[9] = new int[] { 1, 5 };
removes[10] = new int[] { 1, 6 };
removes[11] = new int[] { 2, 3 };
removes[12] = new int[] { 2, 4 };
removes[13] = new int[] { 2, 5 };
removes[14] = new int[] { 2, 6 };
removes[15] = new int[] { 3, 4 };
removes[16] = new int[] { 3, 5 };
removes[17] = new int[] { 3, 6 };
removes[18] = new int[] { 4, 5 };
removes[19] = new int[] { 4, 6 };
removes[20] = new int[] { 5, 6 };
// init best hand to first 5 cards
List"lt"Card"gt" bestFive =
listSeven.GetRange(0, count: 5);
Hand bestHand = new Hand(bestFive);
for (int j = 0; j "lt" 21; ++j) // each pair to remove
{
List"lt"Card"gt" listFive = new List"lt"Card"gt"();
for (int i = 0; i "lt" 7; ++i)
{
if (i == removes[j][0] || i == removes[j][1])
continue;
else
listFive.Add(listSeven[i]);
}
Hand candidate = new Hand(listFive);
if (Hand.Compare(candidate, bestHand) == +1)
{
// h1 "gt" h2 : +1
// Console.WriteLine("New Best Hand Found!");
bestHand = candidate;
}
}
return bestHand;
}
// ------------------------------------------------------
} // Program
public class Card : IComparable"lt"Card"gt"
{
// 0,1 not used. 11=J, 12=Q, 13=K, 14=A
public int rank;
// 0=clubs, 1=diamonds, 2=hearts, 3=spades
public int suit;
public Card(int rank, int suit)
{
this.rank = rank; this.suit = suit;
}
public Card(string c)
{
char rnk = c[0]; char sut = c[1];
if (rnk == 'T') this.rank = 10;
else if (rnk == 'J') this.rank = 11;
else if (rnk == 'Q') this.rank = 12;
else if (rnk == 'K') this.rank = 13;
else if (rnk == 'A') this.rank = 14;
else this.rank = int.Parse(rnk.ToString());
if (sut == 'c') this.suit = 0;
else if (sut == 'd') this.suit = 1;
else if (sut == 'h') this.suit = 2;
else if (sut == 's') this.suit = 3;
}
public override string ToString()
{
string rnk = ""; string sut = "";
if (this.rank == 10) rnk = "T";
else if (this.rank == 11) rnk = "J";
else if (this.rank == 12) rnk = "Q";
else if (this.rank == 13) rnk = "K";
else if (this.rank == 14) rnk = "A";
else rnk = this.rank.ToString();
if (this.suit == 0) sut = "c";
else if (this.suit == 1) sut = "d";
else if (this.suit == 2) sut = "h";
else if (this.suit == 3) sut = "s";
return rnk + sut;
}
public int CompareTo(Card other)
{
// sort cards in a hand from low (Two) to high (Ace)
if (this.rank.CompareTo(other.rank) == 0)
{
return this.suit.CompareTo(other.suit);
}
return this.rank.CompareTo(other.rank);
}
} // class Card
// --------------------------------------------------------
public class Hand
{
// 5-card poker hand
// Hand types: "RoyalFlush", "StraightFlush",
// "FourKind", "FullHouse", "Flush" , "Straight",
// "ThreeKind", "TwoPair", "OnePair", "HighCard"
public List"lt"Card"gt" cards;
public Hand(List"lt"Card"gt" lst)
{
this.cards = new List"lt"Card"gt"();
for (int i = 0; i "lt" 5; ++i)
this.cards.Add(lst[i]);
this.cards.Sort();
}
public Hand(Card c1, Card c2, Card c3,
Card c4, Card c5)
{
this.cards = new List"lt"Card"gt"();
this.cards.Add(c1); this.cards.Add(c2);
this.cards.Add(c3); this.cards.Add(c4);
this.cards.Add(c5);
this.cards.Sort();
}
public Hand(string s) // s like "Js3h7d7cAd"
{
this.cards = new List"lt"Card"gt"();
this.cards.Add(new Card(s.Substring(0, 2)));
this.cards.Add(new Card(s.Substring(2, 2)));
this.cards.Add(new Card(s.Substring(4, 2)));
this.cards.Add(new Card(s.Substring(6, 2)));
this.cards.Add(new Card(s.Substring(8, 2)));
this.cards.Sort();
}
public override string ToString()
{
string h = "";
for (int i = 0; i "lt" 4; ++i)
h += this.cards[i].ToString() + "-";
h += this.cards[4];
return h;
}
public string ToTerseString()
{
string h = "";
for (int i = 0; i "lt" 4; ++i)
h += this.cards[i].ToString();
h += this.cards[4];
return h;
}
// ------------------------------------------------------
// Hand Type methods:
// GetHandTypeStr(), GetHandTypeInt(),
//
// IsRoyalFlush(), IsStraightFlush(),
// IsFourKind(), IsFullHouse(), IsFlush(),
// IsStraight(), IsThreeKind(), IsTwoPair(),
// IsOnePair(), IsHighCard()
//
// helpers: HasFlush(), HasStraight(),
// ------------------------------------------------------
public string GetHandTypeStr()
{
if (IsRoyalFlush(this) == true)
return "RoyalFlush";
else if (IsStraightFlush(this) == true)
return "StraightFlush";
else if (IsFourKind(this) == true)
return "FourKind";
else if (IsFullHouse(this) == true)
return "FullHouse";
else if (IsFlush(this) == true)
return "Flush";
else if (IsStraight(this) == true)
return "Straight";
else if (IsThreeKind(this) == true)
return "ThreeKind";
else if (IsTwoPair(this) == true)
return "TwoPair";
else if (IsOnePair(this) == true)
return "OnePair";
else if (IsHighCard(this) == true)
return "HighCard";
else
return "Unknown";
}
// ------------------------------------------------------
public int GetHandTypeInt()
{
if (IsRoyalFlush(this) == true)
return 9;
else if (IsStraightFlush(this) == true)
return 8;
else if (IsFourKind(this) == true)
return 7;
else if (IsFullHouse(this) == true)
return 6;
else if (IsFlush(this) == true)
return 5;
else if (IsStraight(this) == true)
return 4;
else if (IsThreeKind(this) == true)
return 3;
else if (IsTwoPair(this) == true)
return 2;
else if (IsOnePair(this) == true)
return 1;
else if (IsHighCard(this) == true)
return 0;
else
return -1;
}
// ------------------------------------------------------
private static bool HasFlush(Hand h)
{
if ((h.cards[0].suit == h.cards[1].suit) "and"
(h.cards[1].suit == h.cards[2].suit) "and"
(h.cards[2].suit == h.cards[3].suit) "and"
(h.cards[3].suit == h.cards[4].suit))
return true;
return false;
}
// ------------------------------------------------------
private static bool HasStraight(Hand h)
{
// check special case of Ace-low straight
// 2, 3, 4, 5, A when sorted
if (h.cards[0].rank == 2 "and"
h.cards[1].rank == 3 "and"
h.cards[2].rank == 4 "and"
h.cards[3].rank == 5 "and"
h.cards[4].rank == 14)
return true;
// otherwise, check for 5 consecutive
if ((h.cards[0].rank == h.cards[1].rank - 1) "and"
(h.cards[1].rank == h.cards[2].rank - 1) "and"
(h.cards[2].rank == h.cards[3].rank - 1) "and"
(h.cards[3].rank == h.cards[4].rank - 1))
return true;
return false;
}
// ------------------------------------------------------
private static bool IsRoyalFlush(Hand h)
{
if (HasStraight(h) == true "and" HasFlush(h) == true
"and" h.cards[0].rank == 10)
return true;
else
return false;
}
// ------------------------------------------------------
private static bool IsStraightFlush(Hand h)
{
if (HasStraight(h) == true "and" HasFlush(h) == true
"and" h.cards[0].rank != 10)
return true;
else
return false;
}
// ------------------------------------------------------
private static bool IsFourKind(Hand h)
{
// AAAA B or B AAAA if sorted
if ((h.cards[0].rank == h.cards[1].rank) "and"
(h.cards[1].rank == h.cards[2].rank) "and"
(h.cards[2].rank == h.cards[3].rank) "and"
(h.cards[3].rank != h.cards[4].rank))
return true;
if ((h.cards[1].rank == h.cards[2].rank) "and"
(h.cards[2].rank == h.cards[3].rank) "and"
(h.cards[3].rank == h.cards[4].rank) "and"
(h.cards[0].rank != h.cards[1].rank))
return true;
return false;
}
// ------------------------------------------------------
private static bool IsFullHouse(Hand h)
{
// AAA BB or BB AAA if sorted
if ((h.cards[0].rank == h.cards[1].rank) "and"
(h.cards[1].rank == h.cards[2].rank) "and"
(h.cards[3].rank == h.cards[4].rank) "and"
(h.cards[2].rank != h.cards[3].rank))
return true;
// BB AAA
if ((h.cards[0].rank == h.cards[1].rank) "and"
(h.cards[2].rank == h.cards[3].rank) "and"
(h.cards[3].rank == h.cards[4].rank) "and"
(h.cards[1].rank != h.cards[2].rank))
return true;
return false;
}
// ------------------------------------------------------
private static bool IsFlush(Hand h)
{
if (HasFlush(h) == true "and"
HasStraight(h) == false)
return true; // no StraightFlush or RoyalFlush
else
return false;
}
// ------------------------------------------------------
private static bool IsStraight(Hand h)
{
if (HasStraight(h) == true "and"
HasFlush(h) == false) // no SF or RF
return true;
else
return false;
}
// ------------------------------------------------------
private static bool IsThreeKind(Hand h)
{
// AAA B C or B AAA C or B C AAA if sorted
if ((h.cards[0].rank == h.cards[1].rank) "and"
(h.cards[1].rank == h.cards[2].rank) "and"
(h.cards[2].rank != h.cards[3].rank) "and"
(h.cards[3].rank != h.cards[4].rank))
return true;
if ((h.cards[1].rank == h.cards[2].rank) "and"
(h.cards[2].rank == h.cards[3].rank) "and"
(h.cards[0].rank != h.cards[1].rank) "and"
(h.cards[3].rank != h.cards[4].rank))
return true;
if ((h.cards[2].rank == h.cards[3].rank) "and"
(h.cards[3].rank == h.cards[4].rank) "and"
(h.cards[0].rank != h.cards[1].rank) "and"
(h.cards[1].rank != h.cards[2].rank))
return true;
return false;
}
// ------------------------------------------------------
private static bool IsTwoPair(Hand h)
{
// AA BB C or AA C BB or C AA BB if sorted
if ((h.cards[0].rank == h.cards[1].rank) "and"
(h.cards[2].rank == h.cards[3].rank) "and"
(h.cards[1].rank != h.cards[2].rank) "and"
(h.cards[3].rank != h.cards[4].rank))
return true; // AA BB C
if ((h.cards[0].rank == h.cards[1].rank) "and"
(h.cards[3].rank == h.cards[4].rank) "and"
(h.cards[1].rank != h.cards[2].rank) "and"
(h.cards[2].rank != h.cards[3].rank))
return true; // AA C BB
if ((h.cards[1].rank == h.cards[2].rank) "and"
(h.cards[3].rank == h.cards[4].rank) "and"
(h.cards[0].rank != h.cards[1].rank) "and"
(h.cards[2].rank != h.cards[3].rank))
return true; // C AA BB
return false;
}
// ------------------------------------------------------
private static bool IsOnePair(Hand h)
{
// AA B C D or B AA C D or B C AA D or B C D AA
if ((h.cards[0].rank == h.cards[1].rank) "and"
(h.cards[1].rank != h.cards[2].rank) "and"
(h.cards[2].rank != h.cards[3].rank) "and"
(h.cards[3].rank != h.cards[4].rank))
return true; // AA B C D
if ((h.cards[1].rank == h.cards[2].rank) "and"
(h.cards[0].rank != h.cards[1].rank) "and"
(h.cards[2].rank != h.cards[3].rank) "and"
(h.cards[3].rank != h.cards[4].rank))
return true; // B AA C D
if ((h.cards[2].rank == h.cards[3].rank) "and"
(h.cards[0].rank != h.cards[1].rank) "and"
(h.cards[1].rank != h.cards[2].rank) "and"
(h.cards[3].rank != h.cards[4].rank))
return true; // B C AA D
if ((h.cards[3].rank == h.cards[4].rank) "and"
(h.cards[0].rank != h.cards[1].rank) "and"
(h.cards[1].rank != h.cards[2].rank) "and"
(h.cards[2].rank != h.cards[3].rank))
return true; // B C D AA
return false;
}
// ------------------------------------------------------
private static bool IsHighCard(Hand h)
{
if (HasFlush(h) == true)
return false;
else if (HasStraight(h) == true)
return false;
else
{
// all remaining have at least one pair
if ((h.cards[0].rank == h.cards[1].rank) ||
(h.cards[1].rank == h.cards[2].rank) ||
(h.cards[2].rank == h.cards[3].rank) ||
(h.cards[3].rank == h.cards[4].rank))
return false;
}
return true;
}
// ------------------------------------------------------
// Hand comparison methods
// Hand.Compare() calls:
// BreakTieStraightFlush(), BreakTieFourKind(),
// BreakTieFullHouse(), BreakTieFlush(),
// BreakTieStraight(), BreakTieThreeKind(),
// BreakTieTwoPair(), BreakTieOnePair(),
// BreakTieHighCard()
// ------------------------------------------------------
public static int Compare(Hand h1, Hand h2)
{
// -1 if h1 "lt" h2, +1 if h1 "gt" h2, 0 if h1 == h2
int h1Idx = h1.GetHandTypeInt(); // like 6
int h2Idx = h2.GetHandTypeInt();
// different hand types - easy
if (h1Idx "lt" h2Idx)
return -1;
else if (h1Idx "gt" h2Idx)
return +1;
else // same hand types so break tie
{
string h1HandType = h1.GetHandTypeStr();
string h2HandType = h2.GetHandTypeStr();
if (h1HandType != h2HandType)
Console.WriteLine("Logic error ");
if (h1HandType == "RoyalFlush")
return 0; // two Royal Flush always tie
else if (h1HandType == "StraightFlush")
return BreakTieStraightFlush(h1, h2);
else if (h1HandType == "FourKind")
return BreakTieFourKind(h1, h2);
else if (h1HandType == "FullHouse")
return BreakTieFullHouse(h1, h2);
else if (h1HandType == "Flush")
return BreakTieFlush(h1, h2);
else if (h1HandType == "Straight")
return BreakTieStraight(h1, h2);
else if (h1HandType == "ThreeKind")
return BreakTieThreeKind(h1, h2);
else if (h1HandType == "TwoPair")
return BreakTieTwoPair(h1, h2);
else if (h1HandType == "OnePair")
return BreakTieOnePair(h1, h2);
else if (h1HandType == "HighCard")
return BreakTieHighCard(h1, h2);
}
return -2; // error
}
// ------------------------------------------------------
private static int BreakTieStraightFlush(Hand h1,
Hand h2)
{
// check special case of Ace-low straight flush
// check one or two Ace-low hands
// h1 is Ace - low, h2 not Ace - low.h1 is less
if ((h1.cards[0].rank == 2 "and"
h1.cards[4].rank == 14) "and" // because sorted!
!(h2.cards[0].rank == 2 "and"
h2.cards[4].rank == 14))
return -1;
// h1 not Ace - low, h2 is Ace - low, h1 is better
else if (!(h1.cards[0].rank == 2 "and"
h1.cards[4].rank == 14) "and"
(h2.cards[0].rank == 2 "and"
h2.cards[4].rank == 14))
return +1;
// two Ace-low hands
else if ((h1.cards[0].rank == 2 "and"
h1.cards[4].rank == 14) "and" // Ace-low
(h2.cards[0].rank == 2 "and"
h2.cards[4].rank == 14)) // Ace-low
return 0;
// no Ace-low straight flush so check high cards
if (h1.cards[4].rank "lt" h2.cards[4].rank)
return -1;
else if (h1.cards[4].rank "gt" h2.cards[4].rank)
return 1;
else
return 0;
}
private static int BreakTieFourKind(Hand h1,
Hand h2)
{
// the off-card is at [0] or at [4]
// find h1 four-card and off-card ranks
int h1FourRank; int h1OffRank;
if (h1.cards[0].rank == h1.cards[1].rank)
{
// 1st two cards same so off-rank at [4]
h1FourRank = h1.cards[0].rank;
h1OffRank = h1.cards[4].rank;
}
else
{
// 1st two cards diff so off-rank at [0]
h1FourRank = h1.cards[4].rank;
h1OffRank = h1.cards[0].rank;
}
int h2FourRank; int h2OffRank;
if (h2.cards[0].rank == h2.cards[1].rank)
{
h2FourRank = h2.cards[0].rank;
h2OffRank = h2.cards[4].rank;
}
else
{
h2FourRank = h2.cards[4].rank;
h2OffRank = h2.cards[0].rank;
}
if (h1FourRank "lt" h2FourRank) // like 4K, 4A
return -1;
else if (h1FourRank "gt" h2FourRank)
return +1;
else // both hands have same four-kind (mult. decks)
{
if (h1OffRank "lt" h2OffRank)
return -1; // like 3c 9c9d9h9s "lt" Qd 9c9d9h9s
else if (h1OffRank "gt" h2OffRank)
return +1; // like Jc 4c4d4h4s "gt" 9s 4c4d4h4s
else if (h1OffRank == h2OffRank)
return 0;
}
throw new Exception("Fatal logic BreakTieFourKind");
}
private static int BreakTieFullHouse(Hand h1, Hand h2)
{
// determine high rank (3 kind) and low rank (2 kind)
// JJJ 55 or 33 KKK
// if [1] == [2] 3 kind at [0][1][2]
// if [1] != [2] 3 kind at [2][3][4]
int h1ThreeRank; int h1TwoRank;
if (h1.cards[1].rank == h1.cards[2].rank)
{
// if [1] == [2] 3 kind at [0][1][2]
h1ThreeRank = h1.cards[0].rank;
h1TwoRank = h1.cards[4].rank;
}
else
{
// if [1] != [2] 3 kind at [2][3][4]
h1ThreeRank = h1.cards[4].rank;
h1TwoRank = h1.cards[0].rank;
}
int h2ThreeRank; int h2TwoRank;
if (h2.cards[1].rank == h2.cards[2].rank)
{
// if [1] == [2] 3 kind at [0][1][2]
h2ThreeRank = h2.cards[0].rank;
h2TwoRank = h2.cards[4].rank;
}
else
{
// if [1] != [2] 3 kind at [2][3][4]
h2ThreeRank = h2.cards[4].rank;
h2TwoRank = h2.cards[0].rank;
}
if (h1ThreeRank "lt" h2ThreeRank)
return -1;
else if (h1ThreeRank "gt" h2ThreeRank)
return +1;
else // both hands same three-kind (mult. decks)
{
if (h1TwoRank "lt" h2TwoRank)
return -1; // like 3c3d 9c9d9h "lt" QdQs 9c9d9h
else if (h1TwoRank "gt" h2TwoRank)
return +1; // like 3c3d 9c9d9h "gt" 2d2s 9c9d9h
else if (h1TwoRank == h2TwoRank)
return 0;
}
throw new Exception("Fatal logic BreakTieFullHouse");
}
private static int BreakTieFlush(Hand h1, Hand h2)
{
// compare rank of high cards
if (h1.cards[4].rank "lt" h2.cards[4].rank)
return -1;
else if (h1.cards[4].rank "gt" h2.cards[4].rank)
return +1;
// high cards equal so check at [3]
else if (h1.cards[3].rank "lt" h2.cards[3].rank)
return -1;
else if (h1.cards[3].rank "gt" h2.cards[3].rank)
return +1;
// and so on
else if (h1.cards[2].rank "lt" h2.cards[2].rank)
return -1;
else if (h1.cards[2].rank "gt" h2.cards[2].rank)
return +1;
//
else if (h1.cards[1].rank "lt" h2.cards[1].rank)
return -1;
else if (h1.cards[1].rank "gt" h2.cards[1].rank)
return +1;
//
else if (h1.cards[0].rank "lt" h2.cards[0].rank)
return -1;
else if (h1.cards[0].rank "gt" h2.cards[0].rank)
return +1;
//
else
return 0; // all ranks the same!
}
private static int BreakTieStraight(Hand h1, Hand h2)
{
// both hands are straights but one could be Ace-low
// check special case of one or two Ace-low hands
// h1 is Ace-low, h2 not Ace-low. h1 is less
if ((h1.cards[0].rank == 2 "and" // Ace-low (sorted!)
h1.cards[4].rank == 14) "and"
!(h2.cards[0].rank == 2 "and"
h2.cards[4].rank == 14))
return -1;
// h1 not Ace-low, h2 is Ace-low, h1 is better
else if (!(h1.cards[0].rank == 2 "and"
h1.cards[4].rank == 14) "and"
(h2.cards[0].rank == 2 "and"
h2.cards[4].rank == 14))
return +1;
// two Ace-low hands
else if ((h1.cards[0].rank == 2 "and"
h1.cards[4].rank == 14) "and"
(h2.cards[0].rank == 2 "and"
h2.cards[4].rank == 14))
return 0;
// no Ace-low hands so just check high card
if (h1.cards[4].rank "lt" h2.cards[4].rank)
return -1;
else if (h1.cards[4].rank "gt" h2.cards[4].rank)
return +1;
else if (h1.cards[4].rank == h2.cards[4].rank)
return 0;
else
throw new
Exception("Fatal logic BreakTieStraight");
}
private static int BreakTieThreeKind(Hand h1, Hand h2)
{
// assumes multiple decks possible
// (TTT L H) or (L TTT H) or (L H TTT)
int h1ThreeRank = 0; int h1LowRank = 0;
int h1HighRank = 0;
if (h1.cards[0].rank == h1.cards[1].rank "and"
h1.cards[1].rank == h1.cards[2].rank)
{
h1ThreeRank = h1.cards[0].rank;
h1LowRank = h1.cards[3].rank;
h1HighRank = h1.cards[4].rank;
}
else if (h1.cards[1].rank == h1.cards[2].rank "and"
h1.cards[2].rank == h1.cards[3].rank)
{
h1LowRank = h1.cards[0].rank;
h1ThreeRank = h1.cards[1].rank;
h1HighRank = h1.cards[4].rank;
}
else if (h1.cards[2].rank == h1.cards[3].rank "and"
h1.cards[3].rank == h1.cards[4].rank)
{
h1LowRank = h1.cards[0].rank;
h1HighRank = h1.cards[1].rank;
h1ThreeRank = h1.cards[4].rank;
}
int h2ThreeRank = 0; int h2LowRank = 0;
int h2HighRank = 0;
if (h2.cards[0].rank == h2.cards[1].rank "and"
h2.cards[1].rank == h2.cards[2].rank)
{
h2ThreeRank = h2.cards[0].rank;
h2LowRank = h2.cards[3].rank;
h2HighRank = h2.cards[4].rank;
}
else if (h2.cards[1].rank == h2.cards[2].rank "and"
h2.cards[2].rank == h2.cards[3].rank)
{
h2LowRank = h2.cards[0].rank;
h2ThreeRank = h2.cards[1].rank;
h2HighRank = h2.cards[4].rank;
}
else if (h2.cards[2].rank == h2.cards[3].rank "and"
h2.cards[3].rank == h2.cards[4].rank)
{
h2LowRank = h2.cards[0].rank;
h2HighRank = h2.cards[1].rank;
h2ThreeRank = h2.cards[4].rank;
}
if (h1ThreeRank "lt" h2ThreeRank)
return -1;
else if (h1ThreeRank "gt" h2ThreeRank)
return +1;
// both hands three-kind same (mult. decks)
else if (h1HighRank "lt" h2HighRank)
return -1;
else if (h1HighRank "gt" h2HighRank)
return +1;
//
else if (h1LowRank "lt" h2LowRank)
return -1;
else if (h1LowRank "gt" h2LowRank)
return +1;
//
else // wow!
return 0;
}
private static int BreakTieTwoPair(Hand h1, Hand h2)
{
// (LL X HH) or (LL HH X) or (X LL HH)
int h1LowRank = 0; int h1HighRank = 0;
int h1OffRank = 0;
if (h1.cards[0].rank == h1.cards[1].rank "and"
h1.cards[3].rank == h1.cards[4].rank)
{
// (LL X HH)
h1LowRank = h1.cards[0].rank;
h1HighRank = h1.cards[4].rank;
h1OffRank = h1.cards[2].rank;
}
else if (h1.cards[0].rank == h1.cards[1].rank "and"
h1.cards[2].rank == h1.cards[3].rank)
{
// (LL HH X)
h1LowRank = h1.cards[0].rank;
h1HighRank = h1.cards[2].rank;
h1OffRank = h1.cards[4].rank;
}
else if (h1.cards[1].rank == h1.cards[2].rank "and"
h1.cards[3].rank == h1.cards[4].rank)
{
// (X LL HH)
h1LowRank = h1.cards[1].rank;
h1HighRank = h1.cards[3].rank;
h1OffRank = h1.cards[0].rank;
}
int h2LowRank = 0; int h2HighRank = 0;
int h2OffRank = 0;
if (h2.cards[0].rank == h2.cards[1].rank "and"
h2.cards[3].rank == h2.cards[4].rank)
{
// (LL X HH)
h2LowRank = h2.cards[0].rank;
h2HighRank = h2.cards[4].rank;
h2OffRank = h2.cards[2].rank;
}
else if (h2.cards[0].rank == h2.cards[1].rank "and"
h2.cards[2].rank == h2.cards[3].rank)
{
// (LL HH X)
h2LowRank = h2.cards[0].rank;
h2HighRank = h2.cards[2].rank;
h2OffRank = h2.cards[4].rank;
}
else if (h2.cards[1].rank == h2.cards[2].rank "and"
h2.cards[3].rank == h2.cards[4].rank)
{
// (X LL HH)
h2LowRank = h2.cards[1].rank;
h2HighRank = h2.cards[3].rank;
h2OffRank = h2.cards[0].rank;
}
if (h1HighRank "lt" h2HighRank)
return -1;
else if (h1HighRank "gt" h2HighRank)
return +1;
else if (h1LowRank "lt" h2LowRank)
return -1;
else if (h1LowRank "gt" h2LowRank)
return +1;
else if (h1OffRank "lt" h2OffRank)
return -1;
else if (h1OffRank "gt" h2OffRank)
return +1;
else
return 0;
}
private static int BreakTieOnePair(Hand h1, Hand h2)
{
// (PP L M H) or (L PP M H)
// or (L M PP H) or (L M H PP)
int h1PairRank = 0; int h1LowRank = 0;
int h1MediumRank = 0; int h1HighRank = 0;
if (h1.cards[0].rank == h1.cards[1].rank)
{
// (PP L M H)
h1PairRank = h1.cards[0].rank;
h1LowRank = h1.cards[2].rank;
h1MediumRank = h1.cards[3].rank;
h1HighRank = h1.cards[4].rank;
}
else if (h1.cards[1].rank == h1.cards[2].rank)
{
// (L PP M H)
h1PairRank = h1.cards[1].rank;
h1LowRank = h1.cards[0].rank;
h1MediumRank = h1.cards[3].rank;
h1HighRank = h1.cards[4].rank;
}
else if (h1.cards[2].rank == h1.cards[3].rank)
{
// (L M PP H)
h1PairRank = h1.cards[2].rank;
h1LowRank = h1.cards[0].rank;
h1MediumRank = h1.cards[1].rank;
h1HighRank = h1.cards[4].rank;
}
else if (h1.cards[3].rank == h1.cards[4].rank)
{
// (L M H PP)
h1PairRank = h1.cards[4].rank;
h1LowRank = h1.cards[0].rank;
h1MediumRank = h1.cards[1].rank;
h1HighRank = h1.cards[2].rank;
}
int h2PairRank = 0; int h2LowRank = 0;
int h2MediumRank = 0; int h2HighRank = 0;
if (h2.cards[0].rank == h2.cards[1].rank)
{
// (PP L M H)
h2PairRank = h2.cards[0].rank;
h2LowRank = h2.cards[2].rank;
h2MediumRank = h2.cards[3].rank;
h2HighRank = h2.cards[4].rank;
}
else if (h2.cards[1].rank == h2.cards[2].rank)
{
// (L PP M H)
h2PairRank = h2.cards[1].rank;
h2LowRank = h2.cards[0].rank;
h2MediumRank = h2.cards[3].rank;
h2HighRank = h2.cards[4].rank;
}
else if (h2.cards[2].rank == h2.cards[3].rank)
{
// (L M PP H)
h2PairRank = h2.cards[2].rank;
h2LowRank = h2.cards[0].rank;
h2MediumRank = h2.cards[1].rank;
h2HighRank = h2.cards[4].rank;
}
else if (h2.cards[3].rank == h2.cards[4].rank)
{
// (L M H PP)
h2PairRank = h2.cards[4].rank;
h2LowRank = h2.cards[0].rank;
h2MediumRank = h2.cards[1].rank;
h2HighRank = h2.cards[2].rank;
}
if (h1PairRank "lt" h2PairRank)
return -1;
else if (h1PairRank "gt" h2PairRank)
return +1;
//
else if (h1HighRank "lt" h2HighRank)
return -1;
else if (h1HighRank "gt" h2HighRank)
return +1;
//
else if (h1MediumRank "lt" h2MediumRank)
return -1;
else if (h1MediumRank "gt" h2MediumRank)
return +1;
//
else if (h1LowRank "lt" h2LowRank)
return -1;
else if (h1LowRank "gt" h2LowRank)
return +1;
//
else
return 0;
}
private static int BreakTieHighCard(Hand h1, Hand h2)
{
if (h1.cards[4].rank "lt" h2.cards[4].rank)
return -1;
else if (h1.cards[4].rank "gt" h2.cards[4].rank)
return +1;
//
else if (h1.cards[3].rank "lt" h2.cards[3].rank)
return -1;
else if (h1.cards[3].rank "gt" h2.cards[3].rank)
return +1;
//
else if (h1.cards[2].rank "lt" h2.cards[2].rank)
return -1;
else if (h1.cards[2].rank "gt" h2.cards[2].rank)
return +1;
//
else if (h1.cards[1].rank "lt" h2.cards[1].rank)
return -1;
else if (h1.cards[1].rank "gt" h2.cards[1].rank)
return +1;
//
else if (h1.cards[0].rank "lt" h2.cards[0].rank)
return -1;
else if (h1.cards[0].rank "gt" h2.cards[0].rank)
return +1;
//
else
return 0;
}
// ------------------------------------------------------
} // class Hand
// --------------------------------------------------------
public class SingleDeck
{
public List"lt"Card> deck;
private Random rnd;
public int currCardIdx;
public SingleDeck(int seed)
{
this.deck = new List"lt"Card>();
this.rnd = new Random(seed);
this.currCardIdx = 0;
for (int r = 2; r "lt" 15; ++r) // 0,1 not used
{
for (int s = 0; s "lt" 4; ++s)
{
Card c = new Card(r, s);
this.deck.Add(c); // 2c 2d . . Ah As
}
}
} // ctor
public void Shuffle()
{
for (int i = 0; i "lt" 52; ++i)
{
int rix = this.rnd.Next(i, 52);
Card tmp = this.deck[i];
this.deck[i] = this.deck[rix];
this.deck[rix] = tmp;
}
this.currCardIdx = 0;
}
public Hand DealHand()
{
// TODO: check if enough cards in deck, e.g.
// if (this.currCardIdx > 47)
// Console.WriteLine("Not enough cards in " +
// "deck to deal a hand ");
List"lt"Card> lst = new List"lt"Card>();
for (int i = 0; i "lt" 5; ++i)
{
Card c = this.deck[this.currCardIdx++];
lst.Add(c);
}
Hand h = new Hand(lst);
return h;
}
public List"lt"Card> DealListCards(int nCards)
{
// TODO: check if enough cards in deck, e.g.
// if (this.currCardIdx + nCards > 52)
// Console.WriteLine("Not enough cards in " +
// "deck to deal " + nCards);
List"lt"Card> result = new List"lt"Card>();
for (int i = 0; i "lt" nCards; ++i)
{
Card c = this.deck[this.currCardIdx++];
result.Add(c);
}
return result;
}
public void Show() // or do a ToString()
{
for (int i = this.currCardIdx; i "lt" 52; ++i)
Console.Write(this.deck[i] + " ");
Console.WriteLine("");
}
} // class SingleDeck
// --------------------------------------------------------
} // ns

.NET Test Automation Recipes
Software Testing
SciPy Programming Succinctly
Keras Succinctly
R Programming
2026 Visual Studio Live
2025 Summer MLADS Conference
2026 DevIntersection Conference
2025 Machine Learning Week
2025 Ai4 Conference
2026 G2E Conference
2026 iSC West Conference
You must be logged in to post a comment.