测试肯定胜利的算法

问题描述 投票:0回答:2

我正在尝试用Python编写一个算法来测试游戏中的肯定胜利。

该函数如下所示:

check(num, options)

num - 最初的圆圈数

options - 每个玩家必须依次删除的选项列表。

每个玩家依次移除一定数量的圈子(根据他拥有的选项)。

赢得圈子的最后一名球员获胜。

现在我想检查第一个玩家是否总是在这里赢得num = 5和options = [3,1]:

https://imgur.com/a/i4qt5

我开始尝试解决这个问题以及我来自哪里:

def check(num, options):

    options.sort()
    options.reverse()

    if num == 1:
        return True
    if num == 0:
        return False

    for i in range(len(options)-1):
        if options[i] == num:
            return True
        if options[i] > num:
            continue
        return check(num - options[i], options) and check(num - options[i+1], options)

    return check(num - 1,options)
python algorithm tree
2个回答
1
投票

我很开心写这篇文章。

如果您有任何特殊情况无法解决此问题,请告诉我。

你的主要错误是你没有考虑到其他玩家会玩的事实。我正在使用的技巧是xor逻辑门。 <currentBool> ^ True只是扭转了<currentBool>状态。所以,如果我们想要返回True,我们将要玩,我们只返回我们的状态(因为它是True),否则,相反。

然而,如果是敌人轮到玩,并且他获胜,它将返回False,但万一他输了,它将返回True,因此为你赢。

def check(num, options, currentTurn=True):
    #   If for some reasons, you want to sort in reverse
    #   You should do it like this.
    options.sort(reverse=True)

    #   However if it is 0, the current player obviously lose.
    if num == 0:
        return currentTurn ^ True

    for i in range(len(options) - 1):
        #   If the option gives currentPlayer the win...
        if options[i] == num:
            return currentTurn

        #   If the option is superior, can't use it.
        if options[i] > num:
            continue

        #   If we can subtract, then, we do ! And recursively
        #   go on to the next stage.
        return check(num - options[i], options, currentTurn ^ True)

    #   If the current player can't play, or hasn't won yet, he lost.
    return currentTurn ^ True

-1
投票

你几乎是对的。对于非平凡的情况,您需要检查是否可以移动至少一个丢失状态(如果我正确读取您的代码,则为False)。

所以你可以像编码一样

if num == 0: return False
return any([not check(num - x, options) for x in options if x <= num])

对于较大的num值,这将会很慢,因为您重复检查。您可以通过记忆结果加快速度。

© www.soinside.com 2019 - 2024. All rights reserved.