比较结构列表中的项目并进行相应更新的最佳方法是什么?

时间:2018-10-17 12:11:55

标签: elixir

我正在做一个多人石头剪刀布游戏,以学习Elixir。我的游戏结构包含一个玩家列表和一个获胜者。我要在每个玩家选择更新分数后的选择中递归地迭代(将玩家1与其他玩家进行比较,然后将下一个玩家进行比较,以此类推,直到全部得分)。我正在尝试找出更新游戏的最佳方法,但是在性能方面,我尝试过的一切似乎都很平庸。最好的方法是什么?

链接到特定的游戏逻辑: https://github.com/onesneakymofo/rock_paper_scissors/blob/master/lib/rock_paper_scissors/judge.ex

结构:

%RockPaperScissors.Game{
  players: [
    %RockPaperScissors.Player{choice: "rock", name: "Mandude", score: 0},
    %RockPaperScissors.Player{choice: "paper", name: "Tophlove", score: 0},
    %RockPaperScissors.Player{choice: "scissors", name: "T. Milla", score: 0},
    %RockPaperScissors.Player{choice: "scissors, name: "K-pop", score: 0}
  ],
  winner: nil
}

预期输入:

players: [
    %RockPaperScissors.Player{choice: "rock", name: "Mandude", score: 0},
    %RockPaperScissors.Player{choice: "paper", name: "Tophlove", score: 0},
    %RockPaperScissors.Player{choice: "scissors", name: "T. Milla", score: 0},
    %RockPaperScissors.Player{choice: "scissors, name: "K-pop", score: 0}
  ]

预期输出:

players: [
    %RockPaperScissors.Player{choice: "rock", name: "Mandude", score: 2},
    %RockPaperScissors.Player{choice: "paper", name: "Tophlove", score: 1},
    %RockPaperScissors.Player{choice: "scissors", name: "T. Milla", score: 1},
    %RockPaperScissors.Player{choice: "scissors, name: "K-pop", score: 1}
  ]

1 个答案:

答案 0 :(得分:4)

首先准备数据,然后映射整个数据:

players = [
  %{choice: "rock", name: "Mandude", score: 0},
  %{choice: "paper", name: "Tophlove", score: 0},
  %{choice: "scissors", name: "T. Milla", score: 0},
  %{choice: "scissors", name: "K-pop", score: 0}
]

winners =
  %{"paper" => "rock",
    "rock" => "scissors",
    "scissors" => "paper"}

counts =
  players
  |> Enum.group_by(& &1.choice)
  |> Enum.map(fn {k, v} -> {k, Enum.count(v)} end)
  |> Enum.into(%{})

players =
  Enum.map(players, fn %{choice: choice, score: score} = p ->
    %{p | score: score + counts[winners[choice]]}
  end) 
#⇒ [
#    %{choice: "rock", name: "Mandude", score: 2},
#    %{choice: "paper", name: "Tophlove", score: 1},
#    %{choice: "scissors", name: "T. Milla", score: 1},
#    %{choice: "scissors", name: "K-pop", score: 1}
#  ]