灰色路线的“乘车票”棋盘游戏逻辑

时间:2013-01-23 15:35:55

标签: python algorithm graph

我喜欢玩Ticket to Ride,所以我决定在Python中实现部分游戏逻辑作为辅助编程项目。游戏板本质上是一个加权的多图,所以用NetworkX复制游戏的基本结构很简单。

我遇到问题的一个部分是分析玩家拥有的火车卡清单是否可以通过董事会的特定路径。我认为它更像是一个数学问题,而不是一个编程问题本身,我可能会把一个强力方法拼凑起来来解决问题,但我认为必须有一个更有效的方法

对于那些不了解游戏的人:在任何特定时间,每位玩家都有八种颜色中的一种火车牌,还有一个特殊的机车"作为外卡的类别。这些颜色对应于游戏板(shown here)上的火车线的颜色,除了灰色线,您可以使用任何颜色,只要该段中的所有汽车都是相同的颜色。 (有涉及隧道和渡轮的边缘案件,但我们暂时将这些留在一边。)

使用现在的代码,我可以找到两个给定城市之间的所有路径,并获取每个颜色需要多少列车卡才能采用该特定路径,除非路径涉及灰色段。我首先进行非灰色片段,因为它们更直接 - 要么你有足够的红色/绿色/蓝色卡片用于路径中的每个红色/绿色/蓝色片段,要么你没有。使用灰色,因为您可以选择要用于每个段的任何颜色,所以它会更复杂。

对于只有一个灰色部分的路径,它仍然很容易 - 要么你有足够的任何一种颜色的卡片来填充它。但是,对于多个灰色段,可以遇到为第一个段选择的颜色无法完成第二个或第三个段的情况。

举个例子,假设玩家的牌库存是4红色,2绿色,3蓝色,我们正试图弄清楚他是否可以从巴黎到达维也纳。看看董事会,很容易看出这张卡组合的唯一可能途径是走巴黎 - (3灰) - >苏黎世 - (2绿色) - >威尼斯 - (2灰色) - > Zagrad - (2灰色) - >维也纳。我解决这个问题的算法从绿色段开始,并在那里分配两张绿卡。然后需要决定如何使用剩余的4张红色和3张蓝卡来覆盖长度为3,2和2的灰色段。

当然,答案是使用巴黎和苏黎世之间的3张蓝卡,以及威尼斯至扎格拉德和扎格拉德至维也纳的2张红牌。但是,如何编写一个广义算法来解决这个问题,以解决涉及更多颜色和更多段的不太明显的情况?

我现在的代码如下:

def can_afford(path, cards):
    grays = list()
    for segment in path:
        if segment.color == 'Gray':
            grays.append(segment)
        else:
            if cards.get(segment.color, 0) >= segment.weight:
                cards[segment.color] -= segment.weight
            else:
                return False
    for gray in grays:
        # Halp!
        pass
    return True

("重量"是火车车厢段的长度。)

我觉得这里潜藏着一个非常微不足道的解决方案,我无法指责。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

这个问题与bin packingsubset sum和其他类似问题有一些相似之处。提到的和许多相关的问题是NP完全的,因此可能会发现这个问题没有(已知的)有效算法,但我现在无法证明这一点 - 它只是一种直觉。我会再考虑一下,然后更新这个答案。

答案 1 :(得分:0)

另一种解决方法是按如下方式构建搜索树:

  • 每个节点都标有城市名称,一组卡片和一些列车。这对应于特定路线的起始城市以及您可用的卡片和火车件。

  • 节点的每个子节点对应一个您可以从父节点到达的城市,以及完成从父节点到节点的路径后保留在您手中的卡片和火车片段。

    < / LI>

例如,树的根可以对应蒙特利尔,有4个蓝色,1个白色和1个外卡,以及45个火车片。根的孩子将是:

  • 多伦多,(1蓝,1白,1野),42#使用3张蓝卡
  • 多伦多,(2蓝色,1白色),42#使用2蓝色和外卡
  • 纽约,(1蓝,1白,1野),42#使用3张蓝卡
  • 纽约,(2蓝色,1白色),43#使用2蓝色和外卡
  • 波士顿,(3蓝色,1白色),43#使用1蓝色和外卡
  • 波士顿,(2蓝,1白,1野),43#使用2张蓝卡
  • 波士顿,(4蓝),43#使用1张白色和外卡

现在,您只需在此树中执行深度优先搜索,即可查看是否可以到达目的地城市。您添加到搜索树的边缘受到手中卡片的限制(即,您不能直接从蒙特利尔前往Sault St. Marie,因为您不会总共有6张黑/外卡在您的手中)和剩余的列车数量(如果您只剩下3张卡,则无法从卡尔加里前往西雅图)。