在測試出牌的時候我才想到,
同一回合如果只有我出牌,對方應該是要看不到我出什麼牌才對
我覺得這項功能從原本的 Card.Game 那層來做會比較好,
但是有點懶得回去條了,我直接在 liveview 這層做,算是還可以拉,
也是在伺服器端。
雖然感覺不是最好的做法,我做了一個判斷需不需要顯示對手新的牌的方法
如果對手的桌面長度比玩家的長,就把對手的最後一張牌換成 :fold
defp maybe_fold_last(game, current_player, opponent) do
if length(desk(game, opponent)) > length(desk(game, current_player)) do
opponent_status =
game
|> Map.get(opponent)
|> Map.replace(:desk, Enum.drop(desk(game, opponent), -1) ++ [:fold])
Map.replace(game, opponent, opponent_status)
else
game
end
end
defp desk(game, player) do
game
|> Map.get(player)
|> Map.get(:desk)
end
用在 mount 的 game 狀態上面
mount 方法
def mount(
# 省略...
{:ok,
assign(socket, %{
pid: pid,
id: id,
game: maybe_fold_last(game, current_player, opponent),
current_player: current_player,
opponent: opponent
})}
end
除了 mount 方法要加,接收廣播的 handle_info
才是主要改變狀態的地方
def handle_info(game, socket) do
%{assigns: %{current_player: current_player, opponent: opponent}} = socket
{:noreply,
assign(socket, %{game: maybe_fold_last(game, current_player, opponent)})}
end
最後調整一下 card component
如果是覆蓋狀態的話就用第一個
def card(%{name: :fold} = assigns) do
~H"""
<div class="border border-gray-200 rounded-lg p-0.5 w-14 h-22 m-1 shadow">
<div class="border-2 p-0.5 border-blue-500 rounded-md flex justify-center items-center w-full h-full">
<div class="bg-blue-300 rounded w-full h-full">
</div>
</div>
</div>
"""
end
def card(assigns) do
~H"""
<div class="border border-gray-200 rounded-lg p-0.5 w-14 h-22 m-1 shadow">
<div class="border-2 border-blue-500 rounded-md flex justify-center items-center w-full h-full">
<div class="text-xl font-bold text-blue-500">
<%= card_name(@name) %>
</div>
</div>
</div>
"""
end
完成之後對手如果先出牌,我們就會暫時看不到了