Skip to content

Instantly share code, notes, and snippets.

@misterspeedy
Created October 8, 2013 19:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save misterspeedy/6890374 to your computer and use it in GitHub Desktop.
Save misterspeedy/6890374 to your computer and use it in GitHub Desktop.
Comparing two hands
/// Compare two hands, the first of which can Win, Draw or Lose against the second.
let CompareHands (hand1 : Hand) (hand2 : Hand) =
match hand1, hand2 with
| RoyalFlush, RoyalFlush ->
raise (ArgumentException("Impossible combination: two Royal Flushes"))
| RoyalFlush, _ -> Win
| _, RoyalFlush -> Lose
| StraightFlush, StraightFlush ->
let rank1, rank2 = hand1.Cards.[0].Rank, hand2.Cards.[0].Rank
Outcome.FromRanks rank1 rank2
| StraightFlush, _ -> Win
| _, StraightFlush -> Lose
| FourOfAKind, FourOfAKind
| FullHouse, FullHouse ->
let rank1, rank2 = (hand1.Cards, hand2.Cards) |> Tuple.Map2 CommonestRank
Outcome.FromRanks rank1 rank2
| FourOfAKind, _ -> Win
| _, FourOfAKind -> Lose
| FullHouse, _ -> Win
| _, FullHouse -> Lose
| Flush, Flush ->
// Although normally we would determine on highest rank card, tie breakers
// may be needed right down to the lowest card so it's easiest to think
// of the flush as consisting entirely of kickers.
let kickers1, kickers2 = (hand1.Cards, hand2.Cards) |> Tuple.Map2 SoloRanks
CompareKickers kickers1 kickers2
| Flush, _ -> Win
| _, Flush -> Lose
| Straight, Straight ->
let rank1, rank2 = hand1.Cards.[0].Rank, hand2.Cards.[0].Rank
Outcome.FromRanks rank1 rank2
| Straight, _ -> Win
| _, Straight -> Lose
| ThreeOfAKind, ThreeOfAKind ->
let rank1, rank2 = (hand1.Cards, hand2.Cards) |> Tuple.Map2 CommonestRank
Outcome.FromRanks rank1 rank2
| ThreeOfAKind, _ -> Win
| _, ThreeOfAKind -> Lose
| TwoPair, TwoPair ->
let ranks1, ranks2 = (hand1.Cards, hand2.Cards)
|> Tuple.Map2 (PairRanks >> SortRanks)
if ranks1 <> ranks2 then
let topRank1, topRank2 = ranks1.[0], ranks2.[0]
let topPairOutcome = Outcome.FromRanks topRank1 topRank2
if topPairOutcome <> Draw then
topPairOutcome
else
let secondRank1, secondRank2 = ranks1.[1], ranks2.[1]
Outcome.FromRanks secondRank1 secondRank2
else
let kickers1, kickers2 = (hand1.Cards, hand2.Cards) |> Tuple.Map2 SoloRanks
CompareKickers kickers1 kickers2
| TwoPair, _ -> Win
| _, TwoPair -> Lose
| OnePair, OnePair ->
let rank1, rank2 = (hand1.Cards |> PairRanks).[0], (hand2.Cards |> PairRanks).[0]
if rank1 <> rank2 then
Outcome.FromRanks rank1 rank2
else
let kickers1, kickers2 = (hand1.Cards, hand2.Cards) |> Tuple.Map2 SoloRanks
CompareKickers kickers1 kickers2
| OnePair, _ -> Win
| _, OnePair -> Lose
| _, _ ->
let kickers1, kickers2 = (hand1.Cards, hand2.Cards) |> Tuple.Map2 SoloRanks
CompareKickers kickers1 kickers2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment