diff --git a/lib/viral_spiral/game/player.ex b/lib/viral_spiral/game/player.ex index ebb3791..8195e9a 100644 --- a/lib/viral_spiral/game/player.ex +++ b/lib/viral_spiral/game/player.ex @@ -1,18 +1,30 @@ defmodule ViralSpiral.Game.Player do + alias ViralSpiral.Game.Player + alias ViralSpiral.Game.RoomConfig + defstruct id: "", name: "", - biases: [], - affinities: [], - score: 0, - hand: nil + identity: nil, + hand: [] def new() do - %__MODULE__{ + %Player{ id: UXID.generate!(prefix: "player", size: :small) } end - def set_name(%__MODULE__{} = player, name) do + def new(%RoomConfig{} = room_config) do + %Player{ + id: UXID.generate!(prefix: "player", size: :small), + identity: Enum.shuffle(room_config.communities) |> Enum.at(0) + } + end + + def set_name(%Player{} = player, name) do %{player | name: name} end + + def set_identity(%Player{} = player, identity) do + %{player | identity: identity} + end end diff --git a/lib/viral_spiral/game/room_config.ex b/lib/viral_spiral/game/room_config.ex new file mode 100644 index 0000000..b10ff7c --- /dev/null +++ b/lib/viral_spiral/game/room_config.ex @@ -0,0 +1,15 @@ +defmodule ViralSpiral.Game.RoomConfig do + defstruct affinities: [:cat, :sock], + communities: [:red, :yellow, :blue], + chaos_counter: 10, + volatility: :medium +end + +defmodule ViralSpiral.Game.RoomConfig.Guards do + @affinities [:cat, :sock, :highfive, :houseboat, :skub] + @communities [:red, :yellow, :blue] + + defguard is_affinity(value) when value in @affinities + + defguard is_community(value) when value in @communities +end diff --git a/lib/viral_spiral/game/score.ex b/lib/viral_spiral/game/score.ex new file mode 100644 index 0000000..e3a6f02 --- /dev/null +++ b/lib/viral_spiral/game/score.ex @@ -0,0 +1,51 @@ +defmodule ViralSpiral.Game.Score.Room do + alias ViralSpiral.Game.Score.Room + defstruct chaos_countdown: 10 + + def new() do + %Room{} + end + + def countdown(%Room{} = room) do + %{room | chaos_countdown: room.chaos_countdown - 1} + end +end + +defmodule ViralSpiral.Game.Score.Player do + alias ViralSpiral.Game.Score.Player + alias ViralSpiral.Game.RoomConfig + alias ViralSpiral.Game.Player, as: PlayerData + import ViralSpiral.Game.RoomConfig.Guards + + defstruct biases: %{}, affinities: %{}, clout: 0 + + def new(%PlayerData{} = player, %RoomConfig{} = room_config) do + bias_list = Enum.filter(room_config.communities, &(&1 != player.identity)) + bias_map = Enum.reduce(bias_list, %{}, fn x, acc -> Map.put(acc, x, 0) end) + + affinity_list = room_config.affinities + affinity_map = Enum.reduce(affinity_list, %{}, fn x, acc -> Map.put(acc, x, 0) end) + + %Player{ + biases: bias_map, + affinities: affinity_map + } + end + + def change(%Player{} = player, :bias, target_bias, count) + when is_community(target_bias) and is_integer(count) do + new_biases = Map.put(player.biases, target_bias, player.biases[target_bias] + count) + %{player | biases: new_biases} + end + + def change(%Player{} = player, :affinity, target, count) + when is_affinity(target) and is_integer(count) do + new_affinities = Map.put(player.affinities, target, player.affinities[target] + count) + %{player | affinities: new_affinities} + end + + def change(%Player{} = player, :clout, count) when is_integer(count) do + new_clout = player.clout + count + %{player | clout: new_clout} + end +end diff --git a/lib/viral_spiral/game/state.ex b/lib/viral_spiral/game/state.ex index 132455a..f6e016a 100644 --- a/lib/viral_spiral/game/state.ex +++ b/lib/viral_spiral/game/state.ex @@ -1,8 +1,10 @@ defmodule ViralSpiral.Game.State do - defstruct room: nil, + defstruct room_config: nil, + room: nil, player_list: nil, player_map: nil, - scores: nil, + room_score: nil, + player_scores: nil, round: nil, turn: nil diff --git a/test/support/fixtures.ex b/test/support/fixtures.ex index 815b52a..5d6ea9f 100644 --- a/test/support/fixtures.ex +++ b/test/support/fixtures.ex @@ -1,22 +1,38 @@ defmodule Fixtures do - alias ViralSpiral.Game.Player + alias ViralSpiral.Game.Score.Player + alias ViralSpiral.Game.Turn + alias ViralSpiral.Game.Round alias ViralSpiral.Game.Room + alias ViralSpiral.Game.RoomConfig + alias ViralSpiral.Game.Score.Player, as: PlayerScore + # alias ViralSpiral.Game.Score.Room, as: RoomScore + alias ViralSpiral.Game.Player alias ViralSpiral.Game.State def initialized_game() do + room_config = %RoomConfig{} + player_list = [ - Player.new() |> Player.set_name("adhiraj"), - Player.new() |> Player.set_name("aman"), - Player.new() |> Player.set_name("krys"), - Player.new() |> Player.set_name("farah") + Player.new(room_config) |> Player.set_name("adhiraj"), + Player.new(room_config) |> Player.set_name("aman"), + Player.new(room_config) |> Player.set_name("krys"), + Player.new(room_config) |> Player.set_name("farah") ] players = Enum.reduce(player_list, %{}, fn player, acc -> Map.put(acc, player.id, player) end) + round = Round.new(player_list) + turn = Turn.new(round) + %State{ + room_config: room_config, room: Room.new(), player_map: players, - player_list: player_list + player_list: player_list, + round: round, + turn: turn, + # room_score: RoomScore.new(), + player_scores: Enum.map(player_list, &PlayerScore.new(&1, room_config)) } end end diff --git a/test/viral_spiral/game/player_test.exs b/test/viral_spiral/game/player_test.exs new file mode 100644 index 0000000..454a651 --- /dev/null +++ b/test/viral_spiral/game/player_test.exs @@ -0,0 +1,15 @@ +defmodule ViralSpiral.Game.PlayerTest do + alias ViralSpiral.Game.Player + alias ViralSpiral.Game.RoomConfig + use ExUnit.Case + + test "create player from room config" do + room_config = %RoomConfig{} + + player = + Player.new(room_config) + |> Player.set_name("adhiraj") + + assert player.name == "adhiraj" + end +end diff --git a/test/viral_spiral/game/score_test.exs b/test/viral_spiral/game/score_test.exs new file mode 100644 index 0000000..8a2a00c --- /dev/null +++ b/test/viral_spiral/game/score_test.exs @@ -0,0 +1,50 @@ +defmodule ViralSpiral.Game.ScoreTest do + alias ViralSpiral.Game.Score.Player, as: PlayerScore + alias ViralSpiral.Game.RoomConfig + alias ViralSpiral.Game.Player + use ExUnit.Case + + setup_all do + room_config = %RoomConfig{} + player = Player.new(room_config) |> Player.set_identity("yellow") + player_score = PlayerScore.new(player, room_config) + + %{player: player, player_score: player_score} + end + + test "player should not have a bias against their own identity", state do + player_score = state.player_score + + assert Enum.find(player_score.biases, &(&1 == "yellow")) == nil + end + + test "change player bias", state do + player_score = state.player_score + + player_score = PlayerScore.change(player_score, :bias, :yellow, 3) + assert player_score.biases.yellow == 3 + + player_score = PlayerScore.change(player_score, :bias, :yellow, -2) + assert player_score.biases.yellow == 1 + end + + test "change player affinity", state do + player_score = state.player_score + + player_score = PlayerScore.change(player_score, :affinity, :cat, 5) + assert player_score.affinities.cat == 5 + + player_score = PlayerScore.change(player_score, :affinity, :cat, -2) + assert player_score.affinities.cat == 3 + end + + test "change player clout", state do + player_score = state.player_score + + player_score = PlayerScore.change(player_score, :clout, 3) + assert player_score.clout == 3 + + player_score = PlayerScore.change(player_score, :clout, -2) + assert player_score.clout == 1 + end +end diff --git a/test/viral_spiral/game_test.exs b/test/viral_spiral/game_test.exs deleted file mode 100644 index e82ffce..0000000 --- a/test/viral_spiral/game_test.exs +++ /dev/null @@ -1,25 +0,0 @@ -defmodule ViralSpira.GameTest do - use ExUnit.Case - alias ViralSpiral.Game.Player - alias ViralSpiral.Game.Room - - describe "game" do - test "room management" do - room = Room.new() - - assert room.id != nil - - _players = - [ - Player.new() |> Player.set_name("adhiraj"), - Player.new() |> Player.set_name("aman"), - Player.new() |> Player.set_name("krys"), - Player.new() |> Player.set_name("farah") - ] - - room = Room.set_state(room, :running) - - assert room.state == :running - end - end -end diff --git a/test/viral_spiral/gameplay_test.exs b/test/viral_spiral/gameplay_test.exs new file mode 100644 index 0000000..8b989cb --- /dev/null +++ b/test/viral_spiral/gameplay_test.exs @@ -0,0 +1,18 @@ +defmodule ViralSpiral.GameTest do + use ExUnit.Case + + describe "card actions" do + setup do + game_state = Fixtures.initialized_game() + %{state: game_state} + end + + test "passing an affinity card", %{state: game_state} do + players = game_state.player_map + round = game_state.round + turn = game_state.turn + room_score = game_state.room_score + player_scores = game_state.player_scores + end + end +end