是否存在这样一种算法,如果赋予它无限的处理能力,计算机可以完美下象棋,从而永远不会丢失?
如果是这样,我在哪里可以找到伪代码?
是否存在这样一种算法,如果赋予它无限的处理能力,计算机可以完美下象棋,从而永远不会丢失?
如果是这样,我在哪里可以找到伪代码?
Answers:
是否存在算法?是。根据Zermelo的定理,有限确定性的完美信息两人游戏(如国际象棋)有三种可能性:第一个玩家有获胜策略,或者第二个玩家有获胜策略,或者任一玩家都可以平局。我们(尚)不知道这是国际象棋。(另一方面,跳棋已经解决:任何一方都可以强制平局。)
从概念上讲,该算法非常简单:构建完整的游戏树,分析叶子节点(游戏结束位置),然后进行获胜的初始移动,辞职或进行平局。
问题在于细节:大约有10 43个可能的位置,甚至还有更多的移动(大多数位置可以通过一种以上的方式到达)。您确实需要一台功能强大的计算机来利用此功能,因为可以利用此算法的计算机要么无法放入已知的Universe中,要么要等到Universe结束后的某个时间才能完成计算。
请参阅https://en.wikipedia.org/wiki/Endgame_tablebase。
借助无限的计算机功能,人们可以为起跑位置建立一张这样的桌子并解决象棋。
实际上,使用当前的超级计算机只能解决最多具有七个“人”(棋子,国王数)的位置,因此我们离解决国际象棋还很遥远。问题的复杂性随件数成倍增加。
如果您确实具有无限的处理能力,那么编写这样的算法实际上是微不足道的。由于国际象棋具有有限数量的可能状态,因此从理论上讲,您可以仅遍历所有这些状态,直到找到完美下棋的路径。这将是非常低效的,但是如果您具有无限的处理能力,那就没关系了。
直接解决这个问题:是的,有这样一种算法。它称为极小极大。(最终游戏表库是通过使用此算法生成的(向后!),但是您只需要普通的简单minimax算法即可)。该算法可以完美地玩任何两个玩家的零和游戏。在这里找到伪代码:
https://zh.wikipedia.org/wiki/Minimax
请注意,现代计算机国际象棋程序使用了此算法的变体。
不仅有一种算法可以完美地下棋,还可以编写一个简短的程序(在给定的无限资源的情况下)完美地玩任何具有确定性的,有知识的,有限时长的两人游戏。
游戏引擎甚至不需要知道它正在玩的游戏规则。它所需要的只是“游戏状态”的不透明表示,其功能是(a)给出任何游戏状态,提供合法的下一游戏状态列表,以及(b)给出游戏状态,确定是否对玩家1有利。 ,玩家2的胜利,平局,或者不是结束状态。
给定这些功能,一个简单的递归算法可以“解决”游戏。
国际象棋编程器(minimax)和累积(在python中提供了该程序的版本)在以前的答案中都提到了这一事实。
我在20多年前编写了这样的程序。我通过打零交叉游戏(如果您是美国人,则打井字游戏)进行了测试。果然它玩得很完美。
当然,对于任何严肃的游戏,这将在任何可以想象的计算机上迅速消失。由于它是递归的,因此可以有效地在堆栈上构建整个游戏树,因此在分析其他答案中提到的10 ^ 123下棋状态之前,您将获得“堆栈溢出”(非常有意思的双关语)。但有趣的是,原则上这个小程序可以完成这项工作。
对我来说,这也说明了AI的一些有趣之处:无论您认为“深蓝”或“零归零”,还是有人下象棋或“归零”表现出多少“智能”,这些游戏都具有微不足道的,可精确计算的最佳感觉解决方案。面临的挑战是如何在合理的时间内获得良好的解决方案,而不是最佳的解决方案。
为了简单起见,我将忽略平局或无限移动顺序的可能性。一旦理解了算法,将其扩展到那些情况就不会特别困难。
首先,一些定义:
对于做出此举的玩家而言,任何赢得比赛的举动都是获胜的举动。
对于做出此举的玩家而言,任何输掉比赛的举动都是失败的举动。
任何使另一方玩家至少获胜的举动也是失败的举动。(因为对手可以采取该行动并造成损失。)
任何让其他玩家只输掉棋子的举动也是获胜的棋子。(无论对手采取什么行动,您都将获胜。)
完美的策略意味着,只要有剩余的动作,就总是做出获胜的举动;而仅剩下剩余的动作时,就辞职。
现在,编写完美的策略很简单。只需分解所有可能的移动顺序并确定获胜/失败的举动。忽略僵局,最终将每一步识别为获胜或失败。
现在,该策略是微不足道的。查看您所有可能的举动。如果还有任何获胜的举动,则采取一个并获胜。如果只剩下失败的动作,请辞职,因为对手会迫使您失败。
调整策略以包括僵局的可能性并不难。
更新:如果尚不清楚如何将每一步识别为获胜或失败,请考虑:
n
在尽可能长的国际象棋游戏中调用步数。(尽管包括它们并不困难,我们现在暂时忽略无限制的序列。)n
,我们需要考虑之前移动。n-1
先行n
结束了最长的游戏,因此先行的每一步要么是获胜,要么是失败。n-2
仅跟随获胜动作或失败动作,因此其本身就是获胜动作或失败动作。1. d4
有...resigns
?
假设你有三个功能:win_state
,get_player
,和next_states
。输入的win_state
是游戏状态,如果白色处于将死状态,则输出为-1;如果是平局,则输出为0;如果黑色处于将死状态,则输出为1,None
否则。输入为get_player
游戏状态,如果是黑色则为-1,如果是白色则为1。输入的信息next_states
是合法举动可能导致的下一个游戏状态列表。然后,以下功能(在给定游戏状态和玩家时)应该告诉您要使该玩家获胜的游戏状态。
def best_state(game_state,player)
def best_result(game_state):
if win_state(game_state):
return(win_state)
else:
player = get_player(game_state)
return max([best_result(move)*player for move in next_states(game_state)])*player
cur_best_move = next_states(games_state)[0]
cur_best_outcome = -1
for state in next_states(game_state):
if best_result(state)*player > cur_best_outcome:
cur_best_outcome = best_result(state)*player
cur_best_move = state
return(best_move)
是。这简单。您甚至不需要无限的处理能力。您所需要的就是一张查找表,其中包含每个棋盘位置的最佳移动位置。这是伪代码:
def play-move(my-color, board-position):
return table-of-best-moves[my-color, board-position]
唯一的问题是,该查找表必须非常大(可能比银河系大),并且构造它的时间也很长,可能要比当前宇宙时代长,除非存在国际象棋中一些未发现的规律性使其比我们现在所看到的要简单得多。但是,如果您有此查询表,则每次只需选择一条CPU指令即可实现每次选择一个完美动作的子例程。
另外,考虑到我们目前对国际象棋的了解,因此无法确保完美的打法保证您不会输。例如,如果完美打法保证白方获胜,那么即使黑色打法完美,黑方也会输。