电脑上的国际象棋(电脑对决,谁将成为国际象棋大师)

国际象棋是一种在棋盘上玩的双人战略棋盘游戏,棋盘格式为 64 格,排列在 8×8 网格中。有人无聊的时候会找电脑下国际象棋,但也有人无聊了会教电脑下棋。

电脑上的国际象棋

国际象棋可以说是最棒的棋盘游戏之一,它是战略战术和纯技术的完美融合。每位玩家开局时各有 16 枚棋子:一王、一后、两车、两马、两象和八兵,各具不同功能与走法。真人对弈可以凭借玩家的经验,步步为营。那么,对于一个机器——计算机,你该如何教会它下棋?近日,有人在 medium 上发表了一篇文章,详细解释了如何教计算机玩国际象棋。

本文将从 5 个方面进行介绍:

  • board 表示;
  • board 评估;
  • 移动选择;
  • 测试 ai;
  • 接口测试。

在开始之前,你只需要提前安装 python3。

board 表示

电脑上的国际象棋

首先,你需要对棋子背后的逻辑进行编码,即为每个棋子分配每一次可能的合法移动。

python-chess 库为我们提供了棋子的移动生成和验证,简化了工作,安装方式如下:

!pipinstall python-chess

python-chess 库安装好后,导入 chess 模块并进行初始化:

import chessboard = chess.board()board

在 notebook 中的输出如下所示:

电脑上的国际象棋

board 对象是一个完整的 board 表示,该对象为我们提供了一些重要的函数,例如,board.is_checkmate() 函数检查是否存在将杀(checkmate),board.push() 函数附加一个移动,board.pop() 函数撤销最后一次移动等。阅读完整的文档请参阅:https://python-chess.readthedocs.io/en/latest/

board 评估

为了对 board 进行初步评估,必须考虑一位大师在各自比赛中的想法。

电脑上的国际象棋

我们应该想到的一些要点是:

  • 避免用一个小棋子换三个兵;
  • 象总是成对出现;
  • 避免用两个小棋子换一辆车和一个兵。

将上述要点以方程形式进行表达:

  • 象 3 个兵 马 3 个兵;
  • 象 马;
  • 象 + 马 车 + 兵。

通过化简上述方程,可以得到:象 马 3 个兵。同样,第三个方程可以改写成:象 + 马 = 车 + 1.5 个兵,因为两个小棋子相当于一个车和两个兵。

电脑上的国际象棋

使用 piece square table 来评估棋子,在 8x8 的矩阵中设置值,例如在国际象棋中,在有利的位置设置较高的值,在不利的位置设置较低的值。

例如,白色国王越过中线的概率将小于 20%,因此我们将在该矩阵中将数值设置为负值。

再举一个例子,假设皇后希望自己被放在中间位置,因为这样可以控制更多的位置,因此我们将在中心设置更高的值,其他棋子也一样,因为国际象棋都是为了保卫国王和控制中心。

理论就讲这些,现在我们来初始化 piece square table:

pawntable = [ 0, 0, 0, 0, 0, 0, 0, 0, 5, 10, 10, -20, -20, 10, 10, 5, 5, -5, -10, 0, 0, -10, -5, 5, 0, 0, 0, 20, 20, 0, 0, 0, 5, 5, 10, 25, 25, 10, 5, 5, 10, 10, 20, 30, 30, 20, 10, 10, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0]knightstable = [ -50, -40, -30, -30, -30, -30, -40, -50, -40, -20, 0, 5, 5, 0, -20, -40, -30, 5, 10, 15, 15, 10, 5, -30, -30, 0, 15, 20, 20, 15, 0, -30, -30, 5, 15, 20, 20, 15, 5, -30, -30, 0, 10, 15, 15, 10, 0, -30, -40, -20, 0, 0, 0, 0, -20, -40, -50, -40, -30, -30, -30, -30, -40, -50] bishopstable = [ -20, -10, -10, -10, -10, -10, -10, -20, -10, 5, 0, 0, 0, 0, 5, -10, -10, 10, 10, 10, 10, 10, 10, -10, -10, 0, 10, 10, 10, 10, 0, -10, -10, 5, 5, 10, 10, 5, 5, -10, -10, 0, 5, 10, 10, 5, 0, -10, -10, 0, 0, 0, 0, 0, 0, -10, -20, -10, -10, -10, -10, -10, -10, -20] rookstable = [ 0, 0, 0, 5, 5, 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, -5, -5, 0, 0, 0, 0, 0, 0, -5, -5, 0, 0, 0, 0, 0, 0, -5, -5, 0, 0, 0, 0, 0, 0, -5, -5, 0, 0, 0, 0, 0, 0, -5, 5, 10, 10, 10, 10, 10, 10, 5, 0, 0, 0, 0, 0, 0, 0, 0] queenstable = [ -20, -10, -10, -5, -5, -10, -10, -20, -10, 0, 0, 0, 0, 0, 0, -10, -10, 5, 5, 5, 5, 5, 0, -10, 0, 0, 5, 5, 5, 5, 0, -5, -5, 0, 5, 5, 5, 5, 0, -5, -10, 0, 5, 5, 5, 5, 0, -10, -10, 0, 0, 0, 0, 0, 0, -10, -20, -10, -10, -5, -5, -10, -10, -20] kingstable = [ 20, 30, 10, 0, 0, 10, 30, 20, 20, 20, 0, 0, 0, 0, 20, 20, -10, -20, -20, -20, -20, -20, -20, -10, -20, -30, -30, -40, -40, -30, -30, -20, -30, -40, -40, -50, -50, -40, -40, -30, -30, -40, -40, -50, -50, -40, -40, -30, -30, -40, -40, -50, -50, -40, -40, -30, -30, -40, -40, -50, -50, -40, -40, -30]

通过以下四种方法得到评估函数:

第一步检查游戏是否还在继续。

这个阶段的背后编码逻辑是:如果它在 checkmate 时返回 true,程序将会检查轮到哪方移动。如果当前轮到白方移动,返回值为 - 9999,即上次一定是黑方移动,黑色获胜;否则返回值为 + 9999,表示白色获胜。对于僵局或比赛材料不足,返回值为 0 以表示平局。

代码实现方式:

if board.is_checkmate(): if board.turn: return -9999 else: return 9999if board.is_stalemate(): return 0if board.is_insufficient_material(): return 0

第二步,计算总的棋子数,并把棋子总数传递给 material 函数。

wp = len(board.pieces(chess.pawn, chess.white))bp = len(board.pieces(chess.pawn, chess.black))wn = len(board.pieces(chess.knight, chess.white))bn = len(board.pieces(chess.knight, chess.black))wb = len(board.pieces(chess.bishop, chess.white))bb = len(board.pieces(chess.bishop, chess.black))wr = len(board.pieces(chess.rook, chess.white))br = len(board.pieces(chess.rook, chess.black))wq = len(board.pieces(chess.queen, chess.white))bq = len(board.pieces(chess.queen, chess.black))


第三步,计算得分。material 函数得分的计算方法是:用各种棋子的权重乘以该棋子黑白两方个数之差,然后求这些结果之和。而每种棋子的得分计算方法是:该棋子在该游戏实例中所处位置的 piece-square 值的总和。

material = 100 * (wp - bp) + 320 * (wn - bn) + 330 * (wb - bb) + 500 * (wr - br) + 900 * (wq - bq)pawnsq = sum([pawntable[i] for i in board.pieces(chess.pawn, chess.white)])pawnsq = pawnsq + sum([-pawntable[chess.square_mirror(i)] for i in board.pieces(chess.pawn, chess.black)])knightsq = sum([knightstable[i] for i in board.pieces(chess.knight, chess.white)])knightsq = knightsq + sum([-knightstable[chess.square_mirror(i)] for i in board.pieces(chess.knight, chess.black)])bishopsq = sum([bishopstable[i] for i in board.pieces(chess.bishop, chess.white)])bishopsq = bishopsq + sum([-bishopstable[chess.square_mirror(i)] for i in board.pieces(chess.bishop, chess.black)])rooksq = sum([rookstable[i] for i in board.pieces(chess.rook, chess.white)])rooksq = rooksq + sum([-rookstable[chess.square_mirror(i)] for i in board.pieces(chess.rook, chess.black)])queensq = sum([queenstable[i] for i in board.pieces(chess.queen, chess.white)])queensq = queensq + sum([-queenstable[chess.square_mirror(i)] for i in board.pieces(chess.queen, chess.black)])kingsq = sum([kingstable[i] for i in board.pieces(chess.king, chess.white)])kingsq = kingsq + sum([-kingstable[chess.square_mirror(i)] for i in board.pieces(chess.king, chess.black)])


第四步,计算评价函数,此时将会返回白棋的 material 得分和各棋子单独得分之和。

eval = material + pawnsq + knightsq + bishopsq + rooksq + queensq + kingsqif board.turn: return evalelse: return -eval
电脑上的国际象棋

评价函数流程图

移动选择

算法的最后一步是用 minimax 算法中的 negamax 实现进行移动选择,minimax 算法是双人游戏(如跳棋等)中的常用算法。之后使用 alpha-beta 剪枝进行优化,这样可以减少执行的时间。

现在让我们深入研究一下 minimax 算法。该算法被广泛应用在棋类游戏中,用来找出失败的最大可能性中的最小值。该算法广泛应用于人工智能、决策论、博弈论、统计和哲学,力图在最坏的情况下将损失降到最低。简单来说,在游戏的每一步,假设玩家 a 试图最大化获胜几率,而在下一步中,玩家 b 试图最小化玩家 a 获胜的几率。

为了更好地理解 minimax 算法,

电脑上的国际象棋

维基百科中 minimax 树举例

为了得到更好的结果,使用 minimax 变体 negamax,因为我们只需要一个最大化两位玩家效用的函数。不同点在于,一个玩家的损失等于另一个玩家的收获,反之亦然。

就游戏而言,给第一个玩家的位置值和给第二个玩家的位置值符号是相反的。

电脑上的国际象棋

negamax 示例

首先,我们将 alpha 设为负无穷大,beta 设为正无穷大,这样两位玩家都能以尽可能差的分数开始比赛,代码如下:

except: bestmove = chess.move.null() bestvalue = -99999 alpha = -100000 beta = 100000 for move in board.legal_moves: board.push(move) boardvalue = -alphabeta(-beta, -alpha, depth - 1) if boardvalue bestvalue: bestvalue = boardvalue bestmove = move if (boardvalue alpha): alpha = boardvalue board.pop() return bestmove

下面让我们以流程图的方式来解释:

电脑上的国际象棋

search 函数的流程图

下一步是进行 alpha-beta 的剪枝来优化执行速度。

电脑上的国际象棋

来自维基百科的 alpha-beta 剪枝说明

代码如下:

def alphabeta(alpha, beta, depthleft): bestscore = -9999 if (depthleft == 0): return quiesce(alpha, beta) for move in board.legal_moves: board.push(move) score = -alphabeta(-beta, -alpha, depthleft - 1) board.pop() if (score = beta): return score if (score bestscore): bestscore = score if (score alpha): alpha = score return bestscore

现在,让我们用下面给出的流程图来调整 alphabeta 函数:

电脑上的国际象棋

现在是静态搜索,这种搜索旨在仅评估静态位置,即不存在致胜战术移动的位置。该搜索需要避免由搜索算法的深度限制所引起的水平线效应(horizon effect)。

代码如下:

def quiesce(alpha, beta): stand_pat = evaluate_board() if (stand_pat = beta): return beta if (alpha stand_pat): alpha = stand_patfor move in board.legal_moves: if board.is_capture(move): board.push(move) score = -quiesce(-beta, -alpha) board.pop()if (score = beta): return beta if (score alpha): alpha = score return alpha

简单总结一下 quiesce 函数:

电脑上的国际象棋

quiesce 函数流程图。

测试 ai

开始测试前,需要导入一些库:

测试有 3 项:

  • ai 对弈人类;
  • ai 对弈 ai;
  • ai 对弈 stockfish。

1. ai 对弈人类:

电脑上的国际象棋

ai 选择从 g1 到 f3,这是一个很明智的选择。

2. ai 对弈 ai:

电脑上的国际象棋

3. ai 对弈 stockfish:

电脑上的国际象棋

可以得出:ai 还不够智能,不足以打败 stockfish 12,但仍然坚持走了 20 步。

接口测试

上述测试方式看起来代码很多,你也可以写一个接口测试 ai。

然后执行:

电脑上的国际象棋

最终输出

【温馨提示】如果文章内容有帮助到您,别忘动动小手指分享给好友哦!

相关文章

  • 天天象棋摆棋谱怎么和电脑下(天天象棋摆棋谱,如何挑战电脑对手).

    天天象棋摆棋谱怎么和电脑下(天天象棋摆棋谱,如何挑战电脑对手)

    当计算机诞生时, 人们便想将计算机技术与博弈游戏相结合,这就是机器博弈,机器博弈 是人工智能领域里一个重要研究领域, 在国际上已经开展了半个多世纪。1996年2月10日,ibm的超级电脑装载国际象棋程序“深蓝”首次挑战国际象棋世界冠军加里·卡斯帕罗夫,但以2-4落败。2月17日比赛结束后研究小组对深蓝做了进一步的改良。

    2023-09-11 阅读 (229)
  • 象棋是电脑厉害还是人厉害(电脑棋艺精湛,人类棋手能否捍卫荣誉).

    象棋是电脑厉害还是人厉害(电脑棋艺精湛,人类棋手能否捍卫荣誉)

    一代象棋棋神许银川,人生非常完美,进可夺取六次全国个人赛桂冠,仅次于棋坛泰斗、司令胡荣华。退可开办许银川学堂,教棋育人,传播棋道。许银川的开中残局俱佳,可以说无懈可击。即使现在,与年轻一辈的王天一、郑惟桐、蒋川等对抗,依然不落下风,可谓神一般的存在。要说许银川有什么遗憾的,那就是颠峰时期没有拿下超级象棋软件浪潮天梭。

    2023-09-11 阅读 (198)
  • 天天象棋特级电脑水平(天天象棋特级电脑水平,探寻无人能敌的棋艺之谜).

    天天象棋特级电脑水平(天天象棋特级电脑水平,探寻无人能敌的棋艺之谜)

    天天象棋是目前非常流行的一款象棋软件,深受广大棋友的欢迎,天天象棋评测系统也成为目前衡量棋手水平的重要依据。一些棋友根据天天象棋的评测分数及等级,对应划分出村级、市级、省级、大师及特大等级,例如:业6-业8是村县级、业9-神1是市省级,神2-神3是大师、特大级等。对于这些标准划分,虽然有依有据,但因为有局时(天天象棋评测局时比较固定,15分钟基础局时,每走一步加10秒,是一种偏向于快棋的模式)、象棋软件介入等因素,其实并不见得科学,并不能真实客观地反映出棋手的真实实力。

    2023-09-20 阅读 (129)
  • 电脑象棋软件怎么用(如何让电脑成为你的最佳棋伴).

    电脑象棋软件怎么用(如何让电脑成为你的最佳棋伴)

    天天象棋是一款多人在线的手机象棋游戏。那么电脑如何安装天天象棋呢?有两种方法可以让你在电脑上玩天天象棋。天天象棋方法一:如果电脑上有安装电脑管家1、打开电脑管家电脑管家2、打开软件管理,搜索:天天象棋搜索天天象棋3,点击安装。因为天天象棋是手机软件游戏,所以自动安装时会安装腾讯手游助手,所有功能与手机版天天象棋无二,但对于对电脑不太熟悉的朋友,可能有些麻烦。

    2023-09-09 阅读 (124)
  • 为什么下象棋下不过电脑入门(为何你在象棋比赛中败给了电脑新手).

    为什么下象棋下不过电脑入门(为何你在象棋比赛中败给了电脑新手)

    谢谢棋友提出的问题!大家好,我是销魂飞刀,很高兴有机会来回答这个问题!中国象棋高手下得过电脑吗?人类早就下不过电脑了,这个是现实。因为电脑一、几乎不犯错误……二、几乎不知疲倦……三、引擎越来越强(简单说,就是程序员编写的核心代码,越来越优化)四、内含海量开局库……(人能记多少?电脑是无限)五、开始有了“智能学习”。

    2023-09-20 阅读 (66)
  • 象棋电脑不可战胜(人工智能如何颠覆传统象棋游戏).

    象棋电脑不可战胜(人工智能如何颠覆传统象棋游戏)

    谢谢棋友提出的问题!大家好,我是销魂飞刀,很高兴有机会来回答这个问题!中国象棋高手下得过电脑吗?人类早就下不过电脑了,这个是现实。因为电脑一、几乎不犯错误……二、几乎不知疲倦……三、引擎越来越强(简单说,就是程序员编写的核心代码,越来越优化)四、内含海量开局库……(人能记多少?电脑是无限)五、开始有了“智能学习”。

    2023-09-23 阅读 (60)
  • 象棋大师与电脑谁厉害(电脑智能挑战象棋大师,谁将成为棋盘上的霸主).

    象棋大师与电脑谁厉害(电脑智能挑战象棋大师,谁将成为棋盘上的霸主)

    北京时间7月13日,2019年东莞市第四届“元朗荣华杯”象棋公开赛在广东省东莞市天悦酒店结束第二比赛日的争夺。最终夺冠大热门、超级悍将孟辰连败汪洋、赵金成、李少庚等各路强敌,豪取两日八战全胜积16分高居第一,剑指称霸,汪洋、赵金成13分,柳大华、陶汉明、曹岩磊、金松、庄玉庭、黎德志、任福俊、张学潮、林辉宇、程宇东、黄光颖、李少庚12分。

    2023-09-23 阅读 (14)
  • 中国象棋为什么下不过电脑(为何人类高手在人工智能面前败下阵来).

    中国象棋为什么下不过电脑(为何人类高手在人工智能面前败下阵来)

    谢谢棋友提出的问题!大家好,我是销魂飞刀,很高兴有机会来回答这个问题!中国象棋高手下得过电脑吗?人类早就下不过电脑了,这个是现实。因为电脑一、几乎不犯错误……二、几乎不知疲倦……三、引擎越来越强(简单说,就是程序员编写的核心代码,越来越优化)四、内含海量开局库……(人能记多少?电脑是无限)五、开始有了“智能学习”。

    2023-09-23 阅读 (13)
  • 王天一和电脑战绩(王天一与电脑的对弈,谁将更胜一筹).

    王天一和电脑战绩(王天一与电脑的对弈,谁将更胜一筹)

    北京时间10月28日,2022年第十七届世界象棋锦标赛在马来西亚古晋帝宫大酒店盛大战罢。最终一场冠亚军决赛焦点大战,棋坛第一高手、连续九年等级分全国第一、“外星人”王天一凭借强大的杀术,残棋力量,弃兵破局,139手马炮单缺相巧绝了对手中国香港队新锐冯家俊的马炮单象,王天一夺冠,2013、2017年后,时隔五年豪取世界第三霸,傲视全球,实现丰功伟业。

    2023-09-10 阅读 (9)
  • 天天象棋如何在电脑上微信登陆(微信登录电脑版天天象棋的步骤是什么).

    天天象棋如何在电脑上微信登陆(微信登录电脑版天天象棋的步骤是什么)

    天天象棋是一款多人在线的手机象棋游戏。那么电脑如何安装天天象棋呢?有两种方法可以让你在电脑上玩天天象棋。天天象棋方法一:如果电脑上有安装电脑管家1、打开电脑管家电脑管家2、打开软件管理,搜索:天天象棋搜索天天象棋3,点击安装。因为天天象棋是手机软件游戏,所以自动安装时会安装腾讯手游助手,所有功能与手机版天天象棋无二,但对于对电脑不太熟悉的朋友,可能有些麻烦。

    2023-09-22 阅读 (7)