Skip to content

Instantly share code, notes, and snippets.

@johnhamelink
Created December 21, 2016 21:00
Show Gist options
  • Save johnhamelink/890bf1fa168469c34d7a23a793233fb6 to your computer and use it in GitHub Desktop.
Save johnhamelink/890bf1fa168469c34d7a23a793233fb6 to your computer and use it in GitHub Desktop.
Love Letter game code
defmodule LoveLetter.Deck do
def shuffle(deck) do
new_deck = Enum.shuffle(deck)
case deck == new_deck do
true -> shuffle(deck)
_ -> new_deck
end
end
end
defmodule LoveLetter.Game do
alias LoveLetter.Player
def deal(%{deck: deck, players: []}), do:
%{deck: deck, players: []}
def deal(%{deck: deck, players: player}) when is_tuple(player) do
card = List.first(deck)
deck = List.delete(deck, card)
%{deck: deck, players: Player.add_card_to_hand(player, card)}
end
def deal(%{deck: deck, players: players = [player | tail]}) when is_list(players) do
head_state = deal(%{deck: deck, players: player})
tail_state = deal(%{deck: head_state[:deck], players: tail})
%{
deck: tail_state[:deck],
players: [head_state[:players] | tail_state[:players]]
}
end
def draw(%{player: player = {:player, hand}, deck: deck}) do
%{deck: deck, players: [{:player, new_hand}]} =
deal(%{deck: deck, players: [player]})
{:player, List.delete(new_hand, Enum.min(new_hand))}
end
end
defmodule LoveLetter.GameTest do
use ExUnit.Case
doctest LoveLetter.Game
@deck [1, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8]
test "dealing nothing results in nothing" do
assert LoveLetter.Game.deal(%{deck: [], players: []})
== %{deck: [], players: []}
end
test "dealing deck with one player, one player gets one card" do
assert LoveLetter.Game.deal(%{deck: @deck, players: [{:player, []}]}) ==
%{deck: List.delete_at(@deck, 0), players: [{:player, [1]}]}
end
test "multiple players deal multiple cards" do
assert LoveLetter.Game.deal(%{deck: [1,2,3,4,5], players: [{:player, []}, {:player, []}]}) ==
%{deck: [3,4,5], players: [{:player, [1]}, {:player, [2]}]}
end
test "shuffling decks" do
assert LoveLetter.Deck.shuffle([1,2,3,4]) != [1,2,3,4]
end
test "dealing out cards realistically" do
deck = LoveLetter.Deck.shuffle(@deck)
state = %{deck: deck, players: [{:player, []}, {:player, []}]}
%{deck: new_deck, players: players} = LoveLetter.Game.deal(state)
assert length(deck) > length(new_deck)
assert [1, 1] == Enum.map(players, fn({:player, hand}) -> length(hand) end)
end
test "Dealing & discarding second card" do
deck = LoveLetter.Deck.shuffle(@deck)
state = %{deck: deck, players: [{:player, []}, {:player, []}]}
%{deck: deck, players: players} = LoveLetter.Game.deal(state)
player = players |> Enum.shuffle |> List.first
new_player = LoveLetter.Game.draw(%{deck: deck, player: player})
end
end
defmodule LoveLetter.Player do
def add_card_to_hand({:player, hand}, card) when is_list(hand), do:
{:player, hand ++ [card]}
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment