再加入 回转功能卡 进入胜利判断之前
我想整理一下判断胜利相关的方法
目前是否执行 结束回合是由 maybe_end_round 方法的 guard 判断当下 turn 是否大於 3 来决定的
我想与其把判断胜利放在 maybe_end_round 里面,不如我放在 maybe_end_round 前面,也由 turn 是否大於 3 来决定
看看有没有比较好用。
把原本从 compare_score/3 开头的方法改成下面
defp maybe_add_wins(%{turn: turn} = game) when turn > 3 do
scores = calculate_score(game)
if scores.host > scores.guest 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 maybe_add_wins(game), do: game
defp calculate_score(%{host: %{desk: host_desk}, guest: %{desk: guest_desk}, round: round}) do
[host_score, guest_score] =
[host_desk, guest_desk]
|> Enum.map(&Enum.slice(&1, (round - 1)..(round * 3 - 1)))
|> Enum.map(&Enum.sum(&1))
%{host: host_score, guest: guest_score}
end
现在 handle_cast :play_card 方法多了拉到这个层级的 maybe_add_wins 方法
def handle_cast({:play_card, player, card}, game) do
game =
game
|> play_card_for(player, card)
|> maybe_end_turn()
|> maybe_add_wins()
|> maybe_end_round()
{:noreply, game}
end
每个都 maybe 好像有点瞎,都拿掉好了
def handle_cast({:play_card, player, card}, game) do
game =
game
|> play_card_for(player, card)
|> end_turn()
|> add_wins()
|> end_round()
{:noreply, game}
end
我现在才发现我在 struct 把回转卡叫 :turn ,跟回合的 turn 好像有点撞到,
改成 :reverse 又很长,不过为了避免各种误会还是改一下好了
initial_hand = [1, 1, 2, 2, 3, 3, 4, 5, 6, :reverse, :reverse]
因为我们在计算分数是用加的
所以要再计算前把 reverse 拿掉
应该是放在这个计算方法
defp calculate_score(%{host: %{desk: host_desk}, guest: %{desk: guest_desk}, round: round}) do
[host_score, guest_score] =
[host_desk, guest_desk]
|> Enum.map(&Enum.slice(&1, (round - 1)..(round * 3 - 1)))
|> Enum.map(&挡掉(:reverse))
|> Enum.map(&Enum.sum(&1))
%{host: host_score, guest: guest_score}
end
我们可以用 Enum.reject(enumerable, fun)
方法
Enum.reject([1, 2, :reverse], fn card -> card == :reverse end)
就变成
defp calculate_score(%{host: %{desk: host_desk}, guest: %{desk: guest_desk}, round: round}) do
[host_score, guest_score] =
[host_desk, guest_desk]
|> Enum.map(&Enum.slice(&1, (round - 1)..(round * 3 - 1)))
|> Enum.map(&Enum.reject(&1, fn card -> card == :reverse end))
|> Enum.map(&Enum.sum(&1))
%{host: host_score, guest: guest_score}
end
再来是 :reverse 的效果是可以叠加的
我出一张 :reverse 你出一张 :reverse 的效果会抵销 依此类推
我猜可能要先数 :reverse 有几张,偶数就用没事,
奇数就在比较分数的时候用一下 not 方法
not(true) #=> false
not(host_score > guest_score)
於是判断是不是 host 赢的地方被我加了一个 apply_reverse/2 来决定要不要套用 not
defp add_wins(%{turn: turn} = game) when turn > 3 do
scores = calculate_score(game)
if apply_reverse((scores.host > scores.guest), scores.reverse) 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 apply_reverse(compare, true), do: not(compare)
defp apply_reverse(compare, false), do: compare
至於这局要不要 套用我目前把做法放进 calculate_score 他有我们这次所需要的数值们,
很显然的,这又让calculate_socre这个方法做太多事了,没关系我们先把作法变出来
defp calculate_score(%{host: %{desk: host_desk}, guest: %{desk: guest_desk}, round: round}) do
[host_cards, guest_cards] =
Enum.map([host_desk, guest_desk], &Enum.slice(&1, (round - 1)..(round * 3 - 1)))
[host_score, guest_score] =
[host_cards, guest_cards]
|> Enum.map(&Enum.reject(&1, fn card -> card == :reverse end))
|> Enum.map(&Enum.sum(&1))
reverse =
[host_desk, guest_desk]
|> Enum.map(&Enum.filter(&1, fn card -> card == :reverse end))
|> List.flatten()
|> length()
|> rem(2) == 1
%{host: host_score, guest: guest_score, reverse: reverse}
end
在利用 slice 取得当前这局双方的卡後,除了使用 reject 去掉 :reverse 继续算分数外
还有用他们套进 filter 取出所有的 :reverse,用 flatten 把它们混再一起後
算长度除 2 在比比看 是不是 1,就可以得到这局要不要 reverse
最後在 iex 试玩一下
现在试玩的步骤变得超长到我想要写个脚本...
iex(1)> import Game
Game
iex(2)> {:ok, pid} = start
{:ok, #PID<0.113.0>}
iex(3)> play_card pid, :host, 1
:ok
iex(4)> play_card pid, :guest, 2
:ok
iex(5)> play_card pid, :host, :reverse
:ok
iex(6)> play_card pid, :guest, :reverse
:ok
iex(7)> play_card pid, :host, :reverse
:ok
iex(8)> play_card pid, :guest, 3
:ok
iex(9)> status pid
%Game{
guest: %{
desk: [2, :reverse, 3],
hand: [1, 1, 2, 3, 4, 5, 6, :reverse],
wins: 0
},
host: %{
desk: [1, :reverse, :reverse],
hand: [1, 2, 2, 3, 3, 4, 5, 6],
wins: 1
},
round: 2,
turn: 1
}
>>: Day 0x18 UVa10415 Eb Alto Saxophone Player
今天是30天程序语言研究的第十八天,由於深度学习老师多让我们上了python的进阶课程里面包括之前没...
提到健康监控系统,就不可不提鼎鼎大名的《PSYCHO-PASS心灵判官》中的希必拉系统Sibyl S...
谁是最棒的狗勾 tags: IT铁人 效能的定义 生活中很常对各种东西做出比较,哪本书比较好看、哪个...
了解完套件更新的地方後,再回来玩其他的网路架构。依照day04的架构,严格说来树梅派wifi连上的其...
在 [Day 20],[Day 21],[Day 22] 介绍了「Edge Impulse + BL...