diff --git a/labs/02/card_server.ex b/labs/02/card_server.ex new file mode 100644 index 0000000..6bfcbf4 --- /dev/null +++ b/labs/02/card_server.ex @@ -0,0 +1,71 @@ +defmodule CardServer do + # --- Server Implementation --- + def start() do + spawn(fn -> loop(new()) end) + end + + defp new() do + values = Enum.map(2..10, &Integer.to_string/1) ++ ["J", "Q", "K", "A"] + suits = ["\u2663", "\u2666", "\u2665", "\u2660"] + + for v <- values, f <- suits, do: v <> f + end + + defp deal(from, deck, n) do + case n do + _ when n < 0 -> + send(from, {:error, "Cannot deal negative number of cards"}) + deck + + _ when n > length(deck) -> + send(from, {:error, "Insufficient cards in deck to deal"}) + deck + + _ -> + {d, r} = Enum.split(deck, n) + send(from, {:ok, d}) + r + end + end + + defp loop(deck) do + receive do + :new -> + loop(new()) + + :shuffle -> + loop(Enum.shuffle(deck)) + + {from, :count} -> + send(from, length(deck)) + loop(deck) + + {from, :deal, n} -> + remaining = deal(from, deck, n) + loop(remaining) + end + end + + # --- Client API --- + def new(pid) do + send(pid, :new) + end + + def shuffle(pid) do + send(pid, :shuffle) + end + + def count(pid) do + send(pid, {self(), :count}) + receive do + x -> x + end + end + + def deal(pid, n \\ 1) do + send(pid, {self(), :deal, n}) + receive do + x -> x + end + end +end