我正在尝试用Python编写一个算法来测试游戏中的肯定胜利。
该函数如下所示:
check(num, options)
num - 最初的圆圈数
options - 每个玩家必须依次删除的选项列表。
每个玩家依次移除一定数量的圈子(根据他拥有的选项)。
赢得圈子的最后一名球员获胜。
现在我想检查第一个玩家是否总是在这里赢得num = 5和options = [3,1]:
我开始尝试解决这个问题以及我来自哪里:
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)
我很开心写这篇文章。
如果您有任何特殊情况无法解决此问题,请告诉我。
你的主要错误是你没有考虑到其他玩家会玩的事实。我正在使用的技巧是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
你几乎是对的。对于非平凡的情况,您需要检查是否可以移动至少一个丢失状态(如果我正确读取您的代码,则为False)。
所以你可以像编码一样
if num == 0: return False
return any([not check(num - x, options) for x in options if x <= num])
对于较大的num值,这将会很慢,因为您重复检查。您可以通过记忆结果加快速度。