     assert message =~ regex
     [_, token] = Regex.run(regex, message)
     token
+  end
+
+  defp extract_player_seq(game, startmsg) do
+    [_, turn, seq] = Regex.run(~r/ROUND STARTED;(.*);(.*)\n/, startmsg)
+
+    players = seq
+      |> String.split(",")
+      |> Enum.with_index
+      |> Enum.map(fn {"player" <> n,i} ->
+                    {i+1, %{:name => "player"<>n,
+                            :socket => Enum.at(game[:sockets], String.to_integer(n)-1),
+                            :port => Enum.at(game[:ports], String.to_integer(n)-1)}
+                    }
+                  end)
+      |> Enum.into(%{})
+
+    %{game | :turn => String.to_integer(turn), :players => players}
   end
 
   defp setup_game() do

  end

  @timeout round(Application.get_env(:mia_server, :timeout) * 1.25)

  defp open_udp_socket(ip) do
    opts = [:binary, active: false, ip: ip]

  defp make_nonsense_msg(token), do: "BLABLA;#{token}"
  defp make_announcement_msg(token, d1, d2), do: "ANNOUNCE;#{d1},#{d2};#{token}"
  defp make_see_msg(token), do: "SEE;#{token}"

  defp want_to_see(game, playerno) do
    player = game[:players][playerno]
    player[:socket]
      |> receive_message()
      |> check_and_gettoken(:yourturn)
      |> make_see_msg()
      |> send_to_server(player[:socket], player[:port])
    check_broadcast_message(game[:sockets], "PLAYER WANTS TO SEE;#{player[:name]}\n")
    game
  end

  defp roll(game, playerno) do
    player = game[:players][playerno]
    player[:socket]
      |> receive_message()
      |> check_and_gettoken(:yourturn)
      |> make_roll_msg()
      |> send_to_server(player[:socket], player[:port])
    check_broadcast_message(game[:sockets], "PLAYER ROLLS;#{player[:name]}\n")
    game
  end

  defp announce(game, playerno, {d1, d2}) do
    player = game[:players][playerno]
    player[:socket]
      |> receive_message()
      |> check_and_gettoken(:rolled)
      |> make_announcement_msg(d1,d2)
      |> send_to_server(player[:socket], player[:port])
    check_broadcast_message(game[:sockets], "ANNOUNCED;#{player[:name]};#{d1},#{d2}\n")
    game
  end

  defp inject_dice(game, {d1, d2}) do
    MiaServer.Game.testing_inject_dice(d1,d2)
    game
  end

  defp check_yourturn(game, playerno) do
    game[:players][playerno][:socket]
      |> receive_message()
      |> check_and_gettoken(:yourturn)
    game
  end

  test "First player receives Your Turn" do
    game = setup_game()
    assert game[:turn] == 1
    game[:players][1][:socket] |> receive_message() |> check_and_gettoken(:yourturn)
  end

  test "First player rolls and receives dice" do
    game = setup_game()
    game |> roll(1)
    game[:players][1][:socket] |> receive_message() |> check_and_gettoken(:rolled)
  end

  test "First player does nothing" do
    game = setup_game()
    receive_message(game[:players][1][:socket])
    Process.sleep(@timeout)
    player_lost(game, 1, "DID NOT TAKE TURN")
  end

  test "Player sends invalid command" do
    game = setup_game()
    player = game[:players][1]
    player[:socket]
      |> receive_message()
      |> check_and_gettoken(:yourturn)
      |> make_nonsense_msg()
      |> send_to_server(player[:socket], player[:port])
    player_lost(game, 1, "INVALID TURN")
  end

  test "Player rolls but fails to announce" do
    game = setup_game()
    game |> roll(1)
    receive_message(game[:players][1][:socket])
    Process.sleep(@timeout)
    player_lost(game, 1, "DID NOT ANNOUNCE")
  end

  test "Game round with consecutive announcements" do
    setup_game()
      |> inject_dice({3,1})
      |> roll(1)
      |> announce(1, {3,1})
      |> inject_dice({3,2})
      |> roll(2)
      |> announce(2, {4,1})
      |> check_yourturn(1)
  end

  test "Player announces lower dice" do
    setup_game()
      |> inject_dice({6,1})
      |> roll(1)
      |> announce(1, {6,1})
      |> inject_dice({3,2})
      |> roll(2)
      |> announce(2, {5,1})
      |> player_lost(2, "ANNOUNCED LOSING DICE")
  end

  test "Player announces invalid MIA" do
    setup_game()
      |> inject_dice({6,1})
      |> roll(1)
      |> announce(1, {2,1})
      |> player_lost(1, "LIED ABOUT MIA")
  end

  test "Player announces valid MIA" do
    setup_game()
      |> inject_dice({2,1})
      |> roll(1)
      |> announce(1, {2,1})
      |> player_lost(2, "MIA")
  end

  test "Player wants to see, but no previous roll was made" do
    setup_game()
      |> want_to_see(1)
      |> player_lost(1, "SEE BEFORE FIRST ROLL")
  end

  test "Player wants to see, but roll was correctly annnounced" do
    setup_game()
      |> inject_dice({6,1})
      |> roll(1)
      |> announce(1, {5,1})
      |> want_to_see(2)
      |> player_lost(2, "SEE FAILED")
  end

  test "Player wants to see, and previous player bluffed" do
    setup_game()
      |> inject_dice({5,1})
      |> roll(1)
      |> announce(1, {6,1})
      |> want_to_see(2)
      |> player_lost(1, "CAUGHT BLUFFING")
  end

end
