Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
165 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
defmodule ToyRobot.Application do | ||
use Application | ||
|
||
def start(_type, _args) do | ||
children = [ | ||
ToyRobot.Game.PlayerSupervisor | ||
] | ||
|
||
# See https://hexdocs.pm/elixir/Supervisor.html | ||
# for other strategies and supported options | ||
opts = [strategy: :one_for_one, name: ToyRobot.Supervisor] | ||
Supervisor.start_link(children, opts) | ||
end | ||
end |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
defmodule ToyRobot.Game.Player do | ||
use GenServer | ||
|
||
alias ToyRobot.{Robot, Simulation, Table} | ||
|
||
def start(robot) do | ||
GenServer.start(__MODULE__, robot) | ||
end | ||
|
||
def start_link([position: position, name: name]) do | ||
GenServer.start_link(__MODULE__, position, name: process_name(name)) | ||
end | ||
|
||
def init(position) do | ||
simulation = %Simulation{ | ||
table: %Table{ | ||
north_boundary: 4, | ||
east_boundary: 4, | ||
}, | ||
robot: struct(Robot, position) | ||
} | ||
|
||
{:ok, simulation} | ||
end | ||
|
||
def process_name(name) do | ||
{:via, Registry, {ToyRobot.Game.PlayerRegistry, name}} | ||
end | ||
|
||
def report(player) do | ||
GenServer.call(player, :report) | ||
end | ||
|
||
def move(player) do | ||
GenServer.call(player, :move) | ||
end | ||
|
||
def handle_call(:report, _from, simulation) do | ||
{:reply, simulation |> Simulation.report, simulation} | ||
end | ||
|
||
def handle_call(:move, _from, simulation) do | ||
{:ok, new_simulation} = simulation |> Simulation.move() | ||
{:reply, new_simulation, new_simulation} | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
defmodule ToyRobot.Game.PlayerSupervisor do | ||
use DynamicSupervisor | ||
|
||
alias ToyRobot.Game.Player | ||
|
||
def start_link(args) do | ||
DynamicSupervisor.start_link(__MODULE__, args, name: __MODULE__) | ||
end | ||
|
||
def init(_args) do | ||
Registry.start_link(keys: :unique, name: ToyRobot.Game.PlayerRegistry) | ||
DynamicSupervisor.init(strategy: :one_for_one) | ||
end | ||
|
||
def start_child(position, name) do | ||
DynamicSupervisor.start_child( | ||
__MODULE__, | ||
{Player, [position: position, name: name]} | ||
) | ||
end | ||
|
||
def move(name) do | ||
name |> Player.process_name() |> Player.move() | ||
end | ||
|
||
def report(name) do | ||
name |> Player.process_name() |> Player.report() | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
defmodule ToyRobot.Game.PlayerSupervisorTest do | ||
use ExUnit.Case, async: true | ||
|
||
alias ToyRobot.Game.PlayerSupervisor | ||
|
||
test "starts a game child process" do | ||
starting_position = %{north: 0, east: 0, facing: :north} | ||
{:ok, player} = PlayerSupervisor.start_child(starting_position, "Izzy") | ||
|
||
[{registered_player, _}] = Registry.lookup(ToyRobot.Game.PlayerRegistry, "Izzy") | ||
assert registered_player == player | ||
end | ||
|
||
test "starts a registry" do | ||
registry = Process.whereis(ToyRobot.Game.PlayerRegistry) | ||
assert registry | ||
end | ||
|
||
test "moves a robot forward" do | ||
starting_position = %{north: 0, east: 0, facing: :north} | ||
{:ok, _player} = PlayerSupervisor.start_child(starting_position, "Charlie") | ||
%{robot: %{north: north}} = PlayerSupervisor.move("Charlie") | ||
|
||
assert north == 1 | ||
end | ||
|
||
test "reports a robot's location" do | ||
starting_position = %{north: 0, east: 0, facing: :north} | ||
{:ok, _player} = PlayerSupervisor.start_child(starting_position, "Davros") | ||
%{north: north} = PlayerSupervisor.report("Davros") | ||
|
||
assert north == 0 | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
defmodule ToyRobot.Game.PlayerTest do | ||
use ExUnit.Case, async: true | ||
|
||
alias ToyRobot.Game.Player | ||
alias ToyRobot.Robot | ||
|
||
describe "report" do | ||
setup do | ||
starting_position = %{north: 0, east: 0, facing: :north} | ||
{:ok, player} = Player.start(starting_position) | ||
%{player: player} | ||
end | ||
|
||
test "shows the current position of the robot", %{player: player} do | ||
assert Player.report(player) == %Robot{ | ||
north: 0, | ||
east: 0, | ||
facing: :north | ||
} | ||
end | ||
end | ||
|
||
describe "move" do | ||
setup do | ||
starting_position = %{north: 0, east: 0, facing: :north} | ||
{:ok, player} = Player.start(starting_position) | ||
%{player: player} | ||
end | ||
|
||
test "moves the robot forward one space", %{player: player} do | ||
%{robot: robot} = Player.move(player) | ||
|
||
assert robot == %Robot{ | ||
north: 1, | ||
east: 0, | ||
facing: :north | ||
} | ||
end | ||
end | ||
end |