Skip to content

Commit

Permalink
feat: play a few rounds with pass and keep
Browse files Browse the repository at this point in the history
  • Loading branch information
dennyabrain committed Jan 15, 2025
1 parent 5618ac7 commit 4e5eb4e
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 81 deletions.
12 changes: 5 additions & 7 deletions lib/viral_spiral/room.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ defmodule ViralSpiral.Room do
## Usage :
```elixir
room_reserved = Room.reserve()
room_gen = Room.room_gen!(room_reserved.name)
{:ok, room_gen} = Room.room_gen!(room_reserved.name)
send(room_gen, "ok")
:sys.get_state(room_gen)
```
Expand Down Expand Up @@ -45,10 +45,8 @@ defmodule ViralSpiral.Room do
This ensures there is only one room registered with a path.
"""
@spec reserve() :: RoomReserved.t()
def reserve() do
room_name = Room.name()

@spec reserve(String.t()) :: RoomReserved.t()
def reserve(room_name) do
pid =
case DynamicSupervisor.start_child(@supervisor, {@room_gen, room_name}) do
{:ok, pid} -> pid
Expand All @@ -64,8 +62,8 @@ defmodule ViralSpiral.Room do
"""
def room_gen!(room_name) do
case Registry.lookup(@registry, room_name) do
[{pid, _}] -> pid
_ -> raise NotFound
[{pid, _}] -> {:ok, pid}
_ -> {:error, :not_found}
end
end
end
Expand Down
24 changes: 20 additions & 4 deletions lib/viral_spiral/room/game_engine.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ defmodule ViralSpiral.Room.GameEngine do
All player actions are sent to this genserver, which returns or broadcasts the changes made to the game State.
"""
alias ViralSpiral.Canon.Card.Sparse
alias ViralSpiral.Room.Factory
alias ViralSpiral.Room.State
alias ViralSpiral.Entity.Room
use GenServer
Expand All @@ -16,8 +18,14 @@ defmodule ViralSpiral.Room.GameEngine do

@impl true
def init(name) do

Check warning on line 20 in lib/viral_spiral/room/game_engine.ex

View workflow job for this annotation

GitHub Actions / build-and-deploy

variable "name" is unused (if the variable is not meant to be used, prefix it with an underscore)
room = Room.reserve(name) |> Room.start(4)
state = State.new(room, ["adhiraj", "krys", "aman", "farah"])
state =
Factory.new_game()
|> Factory.join("adhiraj")
|> Factory.join("aman")
|> Factory.join("farah")
|> Factory.join("krys")
|> Factory.start()
|> Factory.draw_card()

{:ok, state}
end
Expand All @@ -31,11 +39,19 @@ defmodule ViralSpiral.Room.GameEngine do
end

@impl true
def handle_cast({:pass, from, to}, state) do
def handle_call({:pass, from, to, %Sparse{} = card}, _from, state) do
new_state = Factory.pass_card(state, card, from, to)
{:reply, new_state, new_state}
end

@impl true
def handle_cast({:keep, from}, state) do
def handle_call({:keep, from, %Sparse{} = card}, _from, state) do
new_state =
state
|> Factory.keep_card(card, from)
|> Factory.draw_card()

{:reply, new_state, new_state}
end

@impl true
Expand Down
25 changes: 19 additions & 6 deletions lib/viral_spiral_web/components/atoms.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,30 @@ defmodule ViralSpiralWeb.Atoms do
<div class="h-3"></div>
<span>pass to:</span>
<div :for={player <- @card.pass_to} }>
<div class="flex flex-row gap-x-2">
<div :for={player <- @card.pass_to} }>
<button
phx-click="pass_to"
value={1}
phx-value-to={player.id}
phx-value-from={@from}
phx-value-card-id={@card.id}
phx-value-card-veracity={"#{@card.veracity}"}
class=" py-1 px-2 bg-[#015058] hover:bg-[#21802B] text-white rounded"
>
<%= player.name %>
</button>
</div>
</div>
<div class="mt-4">
<button
phx-click="pass_to"
value={1}
phx-value-to={player.id}
phx-click="keep"
phx-value-from={@from}
phx-value-card-id={@card.id}
phx-value-card-veracity={"#{@card.veracity}"}
class="inline"
class="py-1 px-2 bg-[#015058] hover:bg-[#21802B] text-white rounded"
>
<%= player.name %>
Keep
</button>
</div>
</div>
Expand Down
67 changes: 43 additions & 24 deletions lib/viral_spiral_web/live/game_room.ex
Original file line number Diff line number Diff line change
@@ -1,46 +1,65 @@
defmodule ViralSpiralWeb.GameRoom do
import ViralSpiralWeb.Atoms
alias ViralSpiral.Canon.Card.Sparse
alias ViralSpiral.Canon.Card
alias ViralSpiral.Entity.Player
alias ViralSpiral.Canon.Deck
alias ViralSpiral.Room
alias ViralSpiral.Room.Factory
alias ViralSpiral.Room.Actions
alias ViralSpiral.Room.Reducer
alias ViralSpiral.Room.State
alias ViralSpiral.Entity.Room
use ViralSpiralWeb, :live_view

def mount(params, session, socket) do
room = Room.new() |> Room.start(4)
state = State.new(room, ["adhiraj", "krys", "aman", "farah"])
requirements = Factory.draw_type(state)
draw_type = Deck.draw_type(requirements)
state = Reducer.reduce(state, Actions.draw_card(draw_type))
{:ok, assign(socket, :state, nil)}
end

def handle_params(%{"room" => room_name}, uri, socket) do
pid =
case Room.room_gen!(room_name) do
{:ok, pid} ->
pid

{:error, :not_found} ->
room_reserved = Room.reserve(room_name)
{:ok, pid} = Room.room_gen!(room_reserved.name)
pid
end

gameroom_state = Factory.make_gameroom(state)
genserver_state = :sys.get_state(pid)
room_state = Factory.make_gameroom(genserver_state)
assign(socket, :state, room_state)

IO.inspect("hello")
socket =
socket
|> assign(:state, room_state)
|> assign(:room_gen, pid)

{:ok, assign(socket, :state, gameroom_state)}
{:noreply, socket}
end

def handle_event("start_game", _params, socket) do
{:noreply, socket}
end

def handle_event(
"pass_to",
params,
socket
) do
def handle_event("pass_to", params, socket) do
%{"from" => from, "to" => to, "card-id" => card_id, "card-veracity" => card_veracity} = params
state = socket.assigns.state
room_gen = socket.assigns.room_gen

msg = {:pass, from, to, Sparse.new({card_id, String.to_atom(card_veracity)})}
genserver_state = GenServer.call(room_gen, msg)

state =
state |> Factory.pass_card(Sparse.new({card_id, String.to_atom(card_veracity)}), from, to)
room_state = Factory.make_gameroom(genserver_state)
socket = assign(socket, :state, room_state)

{:noreply, assign(socket, :state, state)}
{:noreply, socket}
end

def handle_event("keep", params, socket) do
%{"from" => from, "card-id" => card_id, "card-veracity" => card_veracity} = params
room_gen = socket.assigns.room_gen

msg = {:keep, from, Sparse.new({card_id, String.to_atom(card_veracity)})}
genserver_state = GenServer.call(room_gen, msg)

room_state = Factory.make_gameroom(genserver_state)
socket = assign(socket, :state, room_state)
{:noreply, socket}
end

def player_options(state, player) do
Expand Down
86 changes: 46 additions & 40 deletions lib/viral_spiral_web/live/game_room.html.heex
Original file line number Diff line number Diff line change
@@ -1,52 +1,57 @@
<div class="p-4 border-red-200 border-2 rounded-2xl flex flex-row justify-between ">
<span><%= @state.room.name %></span>
<%!-- <span><%= @state.room.id %></span>
<span><%= @state.room.state %></span> --%>
<span><%= @state.room.chaos %></span>
<div :if={@state == nil}>
<p>Loading...</p>
</div>
<%!-- <vs-calendar id="cal" phx-hook="CalendarHook"></vs-calendar> --%>
<div class="mt-2 flex flex-row justify-between">
<div
:for={player <- @state.players}
class={[
"p-2 border-2 w-full rounded-xl m-2",
if(player.is_active,
do: "border-red-400",
else: "border-red-100"
)
]}
>
<span><%= player.name %></span>

<%!-- <span class="ml-6"><%= player.identity %></span> --%>
<div class="h-2"></div>
<div>
<h2 class="font-semibold">Clout</h2>
<span><%= player.clout %></span>
</div>
<div class="h-2"></div>
<div>
<h2 class="font-semibold">Affinities</h2>
<div :for={affinity <- player.affinities}>
<span><%= elem(affinity, 0) %></span>
<span><%= elem(affinity, 1) %></span>
</div>
<div :if={@state != nil}>
<div class="p-4 border-red-200 border-2 rounded-2xl flex flex-row justify-between ">
<span><%= @state.room.name %></span>
<%!-- <span><%= @state.room.id %></span>
<span><%= @state.room.state %></span> --%>
<span><%= @state.room.chaos %></span>
</div>
<%!-- <vs-calendar id="cal" phx-hook="CalendarHook"></vs-calendar> --%>
<div class="mt-2 flex flex-row justify-between">
<div
:for={player <- @state.players}
class={[
"p-2 border-2 w-full rounded-xl m-2",
if(player.is_active,
do: "border-red-400",
else: "border-red-100"
)
]}
>
<span><%= player.name %></span>

<%!-- <span class="ml-6"><%= player.identity %></span> --%>
<div class="h-2"></div>
<h2 class="font-semibold">Bias</h2>
<div :for={bias <- player.biases}>
<span><%= elem(bias, 0) %></span>
<span><%= elem(bias, 1) %></span>
<div>
<h2 class="font-semibold">Clout</h2>
<span><%= player.clout %></span>
</div>
<div class="h-2"></div>
<div>
<h2 class="font-semibold">Affinities</h2>
<div :for={affinity <- player.affinities}>
<span><%= elem(affinity, 0) %></span>
<span><%= elem(affinity, 1) %></span>
</div>

<div class="h-2"></div>
<h2 class="font-semibold">Bias</h2>
<div :for={bias <- player.biases}>
<span><%= elem(bias, 0) %></span>
<span><%= elem(bias, 1) %></span>
</div>

<div class="h-4"></div>
<div class="h-4"></div>

<div :for={card <- player.cards} :if={player.is_active}>
<.card card={card} from={player.id}></.card>
<div :for={card <- player.cards} :if={player.is_active}>
<.card card={card} from={player.id}></.card>
</div>
</div>
</div>

<%!-- <div class="h-4"></div>
<%!-- <div class="h-4"></div>
<%= if current_player?(@state, player) do %>
<.card>
<p><%= card(@state, player).headline %></p>
Expand All @@ -57,5 +62,6 @@
<span class="mr-4"><%= pass_to %></span>
<% end %>
<% end %> --%>
</div>
</div>
</div>

0 comments on commit 4e5eb4e

Please sign in to comment.