Packages

Library for doing playing card-type things. Shuffling a deck and finding the highest value card in a trick

Current section

Files

Jump to
card_shark lib compare.ex
Raw

lib/compare.ex

defmodule CardShark.Compare do
@moduledoc "Module for comparing various cards and determining a 'winner'"
alias CardShark.Card
@doc """
Return the high card from the given set, along with it's index.
Accepts an optional trump suit atom
The list of cards given should be in the order played, and it is assumed
that the first card played determines the suit other cards need to be to be
the high card (or be a trump card)
## Examples
iex> cards = [%Card{face: "3", suit: :spades, value: 3}]
iex> Compare.high_card(cards)
{%Card{face: "3", suit: :spades, value: 3}, 0}
iex> cards = [
...> %Card{face: "3", suit: :spades, value: 3},
...> %Card{face: "6", suit: :diamonds, value: 6}
...> ]
iex> Compare.high_card(cards)
{%Card{face: "3", suit: :spades, value: 3}, 0}
iex> cards = [
...> %Card{face: "3", suit: :clubs, value: 3},
...> %Card{face: "8", suit: :clubs, value: 8}
...> ]
iex> Compare.high_card(cards)
{%Card{face: "8", suit: :clubs, value: 8}, 1}
iex> cards = [
...> %Card{face: "3", suit: :clubs, value: 3},
...> %Card{face: "ace", suit: :spades, value: 14},
...> %Card{face: "king", suit: :clubs, value: 13}
...> ]
iex> Compare.high_card(cards)
{%Card{face: "king", suit: :clubs, value: 13}, 2}
iex> cards = [
...> %Card{face: "3", suit: :clubs, value: 3},
...> %Card{face: "2", suit: :spades, value: 2},
...> %Card{face: "king", suit: :clubs, value: 13}
...> ]
iex> Compare.high_card(cards, :spades)
{%Card{face: "2", suit: :spades, value: 2}, 1}
iex> cards = [
...> %Card{face: "2", suit: :spades, value: 2},
...> %Card{face: "3", suit: :clubs, value: 3},
...> %Card{face: "king", suit: :clubs, value: 13}
...> ]
iex> Compare.high_card(cards, :spades)
{%Card{face: "2", suit: :spades, value: 2}, 0}
iex> cards = [
...> %Card{face: "2", suit: :spades, value: 2},
...> %Card{face: "3", suit: :clubs, value: 3},
...> %Card{face: "king", suit: :spades, value: 13}
...> ]
iex> Compare.high_card(cards, :diamonds)
{%Card{face: "king", suit: :spades, value: 13}, 2}
"""
@spec high_card([%Card{}], atom | nil) :: {}
def high_card(cards, trump \\ nil) when is_list(cards) and is_atom(trump) do
[first | rest] = Enum.with_index(cards)
compare(first, rest, trump)
end
@spec compare({%Card{}, integer}, [%Card{}], atom) :: {%Card{}, integer}
defp compare({_card, _index} = high, [], _trump), do: high
# when a trump card is encountered and it isn't the suit of the high card
defp compare({%Card{suit: h_suit}, _}, [{%Card{suit: trump}, _} = card | rest], trump)
when h_suit != trump do
compare(card, rest, trump)
end
# when the card suits match then values are compared
defp compare(
{%Card{suit: suit, value: h_value}, _},
[{%Card{suit: suit, value: value}, _} = card | rest],
trump
)
when value > h_value do
compare(card, rest, trump)
end
defp compare({%Card{}, _} = high, [{%Card{}, _} | rest], trump) do
compare(high, rest, trump)
end
end