defmodule CardShark.Deck do @moduledoc """ Deck operations such as generating a new deck, shuffling, and dealing can be found here """ alias CardShark.Card @face_values [ {"ace", 14}, {"2", 2}, {"3", 3}, {"4", 4}, {"5", 5}, {"6", 6}, {"7", 7}, {"8", 8}, {"9", 9}, {"10", 10}, {"jack", 11}, {"queen", 12}, {"king", 13} ] @suits [:clubs, :hearts, :diamonds, :spades] # A full deck of cards ordered by rank @deck for suit <- @suits, {face, value} <- @face_values, do: %Card{face: face, suit: suit, value: value} @doc """ Returns an unshuffled deck ## Example iex> Deck.new() [ %Card{face: "ace", suit: :clubs, value: 14}, %Card{face: "2", suit: :clubs, value: 2}, %Card{face: "3", suit: :clubs, value: 3}, %Card{face: "4", suit: :clubs, value: 4}, %Card{face: "5", suit: :clubs, value: 5}, %Card{face: "6", suit: :clubs, value: 6}, %Card{face: "7", suit: :clubs, value: 7}, %Card{face: "8", suit: :clubs, value: 8}, %Card{face: "9", suit: :clubs, value: 9}, %Card{face: "10", suit: :clubs, value: 10}, %Card{face: "jack", suit: :clubs, value: 11}, %Card{face: "queen", suit: :clubs, value: 12}, %Card{face: "king", suit: :clubs, value: 13}, %Card{face: "ace", suit: :hearts, value: 14}, %Card{face: "2", suit: :hearts, value: 2}, %Card{face: "3", suit: :hearts, value: 3}, %Card{face: "4", suit: :hearts, value: 4}, %Card{face: "5", suit: :hearts, value: 5}, %Card{face: "6", suit: :hearts, value: 6}, %Card{face: "7", suit: :hearts, value: 7}, %Card{face: "8", suit: :hearts, value: 8}, %Card{face: "9", suit: :hearts, value: 9}, %Card{face: "10", suit: :hearts, value: 10}, %Card{face: "jack", suit: :hearts, value: 11}, %Card{face: "queen", suit: :hearts, value: 12}, %Card{face: "king", suit: :hearts, value: 13}, %Card{face: "ace", suit: :diamonds, value: 14}, %Card{face: "2", suit: :diamonds, value: 2}, %Card{face: "3", suit: :diamonds, value: 3}, %Card{face: "4", suit: :diamonds, value: 4}, %Card{face: "5", suit: :diamonds, value: 5}, %Card{face: "6", suit: :diamonds, value: 6}, %Card{face: "7", suit: :diamonds, value: 7}, %Card{face: "8", suit: :diamonds, value: 8}, %Card{face: "9", suit: :diamonds, value: 9}, %Card{face: "10", suit: :diamonds, value: 10}, %Card{face: "jack", suit: :diamonds, value: 11}, %Card{face: "queen", suit: :diamonds, value: 12}, %Card{face: "king", suit: :diamonds, value: 13}, %Card{face: "ace", suit: :spades, value: 14}, %Card{face: "2", suit: :spades, value: 2}, %Card{face: "3", suit: :spades, value: 3}, %Card{face: "4", suit: :spades, value: 4}, %Card{face: "5", suit: :spades, value: 5}, %Card{face: "6", suit: :spades, value: 6}, %Card{face: "7", suit: :spades, value: 7}, %Card{face: "8", suit: :spades, value: 8}, %Card{face: "9", suit: :spades, value: 9}, %Card{face: "10", suit: :spades, value: 10}, %Card{face: "jack", suit: :spades, value: 11}, %Card{face: "queen", suit: :spades, value: 12}, %Card{face: "king", suit: :spades, value: 13}, ] """ def new, do: @deck @doc """ Returns a full shuffled deck of cards (52 cards). ## Examples iex> Deck.shuffled() != Deck.new() true """ def shuffled, do: new() |> Enum.shuffle() @doc """ Returns `n_cards` from the `deck` and the rest of the `deck`. ## Example iex> deck = Deck.new() |> Enum.take(5) iex> Deck.deal(deck, 2) { [ %Card{face: "ace", suit: :clubs, value: 14}, %Card{face: "2", suit: :clubs, value: 2} ], [ %Card{face: "3", suit: :clubs, value: 3}, %Card{face: "4", suit: :clubs, value: 4}, %Card{face: "5", suit: :clubs, value: 5}, ]} """ @spec deal([%Card{}], integer) :: {[%Card{}], [%Card{}]} def deal(deck, n_cards) when is_list(deck) and is_integer(n_cards) do Enum.split(deck, n_cards) end end