如何迭代集合

时间:2017-10-13 19:51:20

标签: ruby algorithm directed-acyclic-graphs

我有一个以游戏玩家的名字为主键的哈希值,以及一个包含每个玩家击败的其他玩家名称的设置对象作为值。这些集合被初始化为空,然后两个玩家随机挑选并互相争斗,获胜者将另一个玩家密钥添加到其集合中,代表胜利。一旦胜利确立,玩家就不能再次互相争斗。最后,一个击败另一个的玩家也应该在他的场景中击败对方,其他人击败他们,等等。

在特定的比赛情况下,有5名球员,克劳迪娅,罗莎,鲍勃,卡洛斯和蒂姆。让我们假设罗莎击败鲍勃,然后鲍勃击败卡洛斯和克劳迪娅击败蒂姆,此时给定的数据将如下所示:

@match_data = {"claudia"=>#<Set: {"tim">,
               "rosa"=>#<Set: {"bob", "carlos"}>,
               "bob"=>#<Set: {"carlos"},
               "carlos"=>#<Set: {},
               "tim"=>#<Set: {}}

所以在这一点上克劳迪娅取得了对阵蒂姆的胜利,所以他们不会再打一场战斗,罗莎队取得了对阵鲍勃和卡洛斯的胜利,因此她再也不需要与他们作战了,鲍勃反对卡洛斯,他们赢了#39或者战斗。想象一下,在此之后,Bob击败了Claudia,此时所需的数据应该是:

@match_data = {"claudia"=>#<Set: {"tim"}>,
               "rosa"=>#<Set: {"bob", "carlos", "claudia", "tim"}>,
               "bob"=>#<Set: {"carlos", "claudia", "tim"},
               "carlos"=>#<Set: {},
               "tim"=>#<Set: {}}
当鲍勃击败克劳迪娅时,他不仅获得了对她的胜利,而且还获得了以前被击败过的蒂姆,更重要的是,罗莎获得了克劳迪娅和蒂姆的胜利,因为她已经取得了对鲍勃的胜利。因此,在这种情况下,罗莎赢得比赛,鲍勃是第二名,而其他人仍在比赛。这可能会变得更加复杂,因为玩家的数量不受限制。

我想克服的问题是创建一个能够更新游戏状态的功能。每次匹配结束时,此代码将查看match_data并查找匹配结果已获取的胜利。这段代码是我的一次尝试:

def update_set(key)
  store = Set.new
  @match_data[key].each { |value| store.merge @match_data[value] }
  if store.size > 0
    store.each { |value| update_set(value) }
  end
  @match_data[key].merge store
end

@match_data.sort.map do |key, set|
  update_set(key)
end

我的其他尝试得到一个错误,说我太深了,或者我在循环期间无法迭代哈希。或者,我可以尝试使用其他数据结构,但我不知道哪一个。

编辑:为了清楚起见,我编辑了原始问题,因为在运行我的代码时不清楚我想要的输出是什么。然而,给出@ddubs的答案对我的代码完全有效。

另外,我想在我的例子中指出一个错误,在我的程序中,数据永远不会真正完全转换为第一个代码片段,因为所需的函数将始终在每个战斗之间运行,刷新状态然后是字典。我想我不想写太多无用的信息,让我的问题变得更加复杂,但我最终还是要压制重要的信息。

如果需要,我可以发布整个程序逻辑,但我不认为这是必要的。

EDIT2:添加了整个游戏逻辑,因为我发现它仍然不够清晰,@ ddubs给出的解决方案仍然有效,但也许有人可以提供更好的东西,现在所有的信息都给出了

1 个答案:

答案 0 :(得分:1)

Set似乎使这个奇怪,或者它只是@match_data对象的布局。无论如何,必须对每个玩家及其相应的集合应用此功能。它还需要您将匹配数据传递给它:

def compile_sets(set, data, results = Set.new)
  set.each do |s|
    results << s
    results << compile_sets(data[s], data, results)
  end
  results.flatten
end

示例用法:

results = @match_data.map { |player,set| { player => compile_sets(set, @match_data) } }

p results

返回:

[
  {"carlos"=>#<Set: {}>},
  {"bob"=>#<Set: {"carlos", "claudia"}>},
  {"lisa"=>#<Set: {"bob", "carlos", "claudia"}>},
  {"tim"=>#<Set: {"lisa", "bob", "carlos", "claudia"}>},
  {"mary"=>#<Set: {"lisa", "bob", "carlos", "claudia"}>},
  {"rosa"=>#<Set: {"tim", "lisa", "bob", "carlos", "claudia"}>}, 
  {"claudia"=>#<Set: {}>}
]