好拉 昨天算是一個里程碑,
遊戲的核心也快完成了。
先把 handle_cast :play_card 裡面的東西全部搬出去到 play_card_with_checks 方法
然後再用 have_this_card? 來寫判斷
def handle_cast({:play_card, player, card}, game) do
if have_this_card?(game, player, card) do
{:noreply, play_card_with_checks(game, player, card)}
else
{:noreply, game}
end
end
def have_this_card?(game, player, card) do
game
|> Map.get(player)
|> Map.get(:hand)
|> Enum.member?(card) # 檢查 card 有沒有在 hand 裡面
end
def play_card_with_checks(%{turn: current_turn} = game, player, card) do
game
|> play_card_for(player, card)
|> end_turn()
|> add_wins()
|> end_round()
|> end_game()
|> start_turn_timer(current_turn)
end
defp start_turn_timer(game, current_turn \\ 0) do
if game.status == :start && current_turn != game.turn do
Process.send_after(self(), {:times_up, :host, game.round, game.turn}, 1500)
Process.send_after(self(), {:times_up, :guest, game.round, game.turn}, 1500)
end
game
end
最後這邊我還把 開啟倒數計時 也做成獨立的方法,他接收 game, 回傳 game,
讓我們可以把它直接串在 出牌的那一串 pipe
def init(game) do
{:ok, start_turn_timer(game)}
end
init 那邊也有用到,現在可以直接呼叫 start_turn_timer 就好了
另外 start_turn_timer 收的參數裡面 \\
是指預設的值,如果沒有給就是 0
0 是給 init 用的,確保他依定會發動
add_wins 這個判斷該 round 是誰贏,並且在他的 wins 裡面加一
這個方法我怎麼寫都不滿意,我現在又改成這樣。
defp add_wins(%{turn: turn, host: host, guest: guest} = game) when turn > 3 do
if host_win_this_round?(game) do
assign_to_player(game, :host, :wins, game.host.wins + 1)
else
assign_to_player(game, :guest, :wins, game.guest.wins + 1)
end
end
defp add_wins(game), do: game
defp host_win_this_round?(%{round: round, host: host, guest: guest}) do
range_start = (round - 1) * 3
range = range_start..(range_start + 2)
host_desk = Enum.slice(host.desk, range)
guest_desk = Enum.slice(guest.desk, range)
host_win = get_score(host_desk) > get_score(guest_desk)
if reverse?(host_desk ++ guest_desk) do
host_win
else
!host_win
end
end
滿困擾的,你覺得怎樣改好
然後我現在才發現,這樣子假如分數一樣會變成 guest 贏,
我寫的時候完全忘記之前訂說,如果分數一樣的話,有比較大的卡的人贏
不過我現在有點不想這樣做,明天來看看怎麼辦。
或者是就先這樣XD
回來修正錯誤
原本 ! 的地方放反了
if reverse?(host_desk ++ guest_desk) do
!host_win
else
host_win
end