Added combination checks.

This commit is contained in:
Hans Goor 2024-08-15 20:35:16 +02:00
parent 4210670e9e
commit 4939d5fb09
Signed by: eyedevelop
SSH key fingerprint: SHA256:Td89veptDEwCV8J3fjqnknNk7SbwzedYhauyC2nFBYg
2 changed files with 110 additions and 0 deletions

View file

@ -0,0 +1,86 @@
defmodule PokerEx.Combination do
alias __MODULE__
alias PokerEx.Card, as: Card
@type score() ::
:high_card
| :pair
| :two_pair
| :three_of_a_kind
| :straight
| :flush
| :full_house
| :four_of_a_kind
| :straight_flush
| :royal_flush
@type t() :: %Combination{score: score(), cards: [Card.t()]}
defstruct score: :invalid, cards: []
def straight?(sorted_hand) do
# Grab the ranks of the card, have a sliding window and check if the
# difference between all cards is 1.
sorted_hand
|> Enum.map(& &1.rank)
|> Enum.map(
&case &1 do
:jack -> 11
:queen -> 12
:king -> 13
:ace -> 14
n -> n
end
)
|> Enum.chunk_every(2, 1, :discard)
|> Enum.map(
&case &1 do
[14, 2] -> 1 # Special case of A followed by a 2
[a, b] -> b - a
end
)
|> Enum.all?(& &1 == 1)
end
def flush?(hand) do
hand
|> Enum.map(& &1.suit)
|> Enum.frequencies()
|> Map.values()
|> Enum.any?(& &1 >= 5)
end
def evaluate_hand(hand) do
end
@doc ~S"""
Finds the highest combination that can be made using the hand and the cards
that are present.
## Examples
iex> PokerEx.Combination.find [%PokerEx.Card{suit: :diamonds, rank: 5}]
{:ok, %PokerEx.Combination{score: :high_card, cards: [%PokerEx.Card{suit: :diamonds, rank: 5}]}}
iex> PokerEx.Combination.find [%PokerEx.Card{suit: :diamonds, rank: 5}, %PokerEx.Card{suit: :hearts, rank: :ace}]
{:ok, %PokerEx.Combination{score: :high_card, cards: [%PokerEx.Card{suit: :hearts, rank: :ace}]}}
iex> comb = PokerEx.Combination.find [
...> %PokerEx.Card{suit: :spades, rank: :king},
...> %PokerEx.Card{suit: :spades, rank: :king},
...> %PokerEx.Card{suit: :spades, rank: :king},
...> %PokerEx.Card{suit: :spades, rank: :queen},
...> %PokerEx.Card{suit: :spades, rank: :queen}
...> ]
iex> comb.score == :full_house
true
iex> PokerEx.Combination.find []
{:error, :invalid_list}
iex> PokerEx.Combination.find ["Hello"]
{:error, :invalid_list}
"""
@spec find([Card.t()]) :: {:ok, Combination.t()} | {:error, atom}
def find([%Card{suit: s, rank: :ace}]) do
end
end

View file

@ -0,0 +1,24 @@
defmodule PokerEx.CombinationTest do
alias PokerEx.Combination
import PokerEx.Card
use ExUnit.Case
test "test straight" do
hand = [~p"C2", ~p"C3", ~p"C4", ~p"C5", ~p"C6"]
assert Combination.straight?(hand) == true
hand = [~p"C2", ~p"D3", ~p"S4", ~p"S5", ~p"C7"]
assert Combination.straight?(hand) == false
hand = [~p"D10", ~p"SJ", ~p"HQ", ~p"CK", ~p"DA"]
assert Combination.straight?(hand) == true
hand = [~p"SA", ~p"D2", ~p"H3", ~p"C4", ~p"S5"]
assert Combination.straight?(hand) == true
end
test "test flush" do
assert Combination.flush?([~p"CA", ~p"C10", ~p"C2", ~p"CK", ~p"C5"]) == true
assert Combination.flush?([~p"CA", ~p"C10", ~p"C2", ~p"CK", ~p"D5"]) == false
end
end