非常有趣,无论是教科书还是老师讲课,国际象棋的学习顺序是先学残局,然后是中局,最后才学开局。开局的目的就是要获得一个好点的局面,但是非常多的人开局不好,究其原因,无非是略知皮毛,就开始到处逞强,而忽视了学习开局以及开局背后的理论。当然,开局的学习也是挺难的,刚开始几步还好,越往下走就越乱了,因为每往下走一步就又多了许多变化。

编辑:陈萍

开局分类
通常,国际象棋开局分为5大类,每大类下又分很多小类。
开放性开局,开始走1 e4 e5。其中重要或者常用的开局有意大利开局、伊文思弃兵、双马防御、匈牙利防御、三马开局、四马开局、西班牙开局、菲利多尔防御、彼得罗夫防御、苏格兰开局、王翼弃兵开局。
半开放性开局,开始1 e4,黑方应以除1...e5以外的招数。其中重要或者常用的开局有西西里防御、法兰西防御、卡罗-康防御、皮尔兹防御、阿廖欣防御、斯堪的纳维亚防御。
封闭性开局,开始走1. d4 d5。其中重要或者常用的有后翼弃兵开局、拒后翼弃兵开局、接受后翼弃兵开局、斯拉夫防御。
半封闭性开局,开始1.d4,黑方应以除1...d5以外的招数。其中重要或者常用的有尼姆佐-印度防御、新印度防御、古印度防御、别诺尼防御、格林菲尔德防御、荷兰防御。
不规则开局,第一步既不是1. e4, 也不是1. d4的开局。其中重要或者常用的有英国式开局、列蒂开局、伯德开局。
总之,国际象棋的开局选择是多样性的。整个篇幅会很长。
一、 开放性开局
意大利开局

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

国际象棋的五种开局分类

1.e4 e5 2.Nf3 Nc6 3.Bc4 Bc5 最古老的开局,大约已有500年历史,在19世纪极度风行。白方的基本战略思想很明确:以白格象直指防守薄弱的f7兵,并通过c3、d4占领中心,经常为了获得攻势,不惜弃兵、弃子来制造杀局。但经过几百年来的实战证明,此开局容易迅速简化,被黑方扳成平先;有时造成尖锐局面,也是胜负相当。因此意大利开局越来越少被采用。

今天,我们来教AI下国际象棋

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

伊文思弃兵

国际象棋的五种开局分类

1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 白棋的目的就是要走c3和d4来控制中心,4.b4就是为了吸引黑象到b4,这样挺c3兵的时候,黑象就在兵的进攻之下。

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

双马防御

国际象棋的五种开局分类

1.e4 e5 2.Nf3 Nc6 3.Bc4 Nf6 此开局略晚于意大利开局,因为黑方出c5象,很快将被白方冲起d4兵所驱赶,所以黑方采取更快一步的反击手段3.… Nf6,马上攻击e4兵与白方争先,这个变例容易导向尖锐局面。

Board 表示;Board 评估;移动选择;测试 AI;接口测试。

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

匈牙利防御

Board 表示

国际象棋的五种开局分类

1.e4 e5 2.Nf3 Nc6 3.Bc4 Be7 此开局出现较晚,约有150年历史,是由匈牙利棋手首先使用的,故名。其主要思想是避开意大利开局和双马防御等尖锐局面。从第三着3.… Be7开始防Ng5,构成一种稳固局面,但是子力拘谨、被动;若对付那些偏爱蛮干和冒险的棋手,往往很奏效。

今天,我们来教AI下国际象棋

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

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

!pip install python-chess

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

import chess board = chess.Board() board

在 notebook 中的输出如下所示:

今天,我们来教AI下国际象棋

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

三马开局

国际象棋的五种开局分类

1. e4 e5 2. Nf3 Nc6 3. Nc3 为了打破对称,避免出现4马开局的情况,黑方选择3.d6 或者3.Be7, 白棋可以回应4.d4,这样,避免了容易和棋的4马开局,但黑棋有点拥挤。所以,很少出现在高水平的比赛中。

四马开局

Board 评估

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

今天,我们来教AI下国际象棋

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

国际象棋的五种开局分类

1. e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4马开局在初学者中非常常见,这是因为遵循了“马前象后”的原则。4马开局通常会导致非常安静的局面对抗,高手之间的较量往往会以和棋收场。

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

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

西班牙开局

国际象棋的五种开局分类

1.e4 e5 2.Nf3 Nc6 3.Bb5 西班牙开局是现代最流行的开局之一,在白方1.e4开局体系的实战对局中,出现的数量,仅次于西西里防御,占第二位。在1.e4 e5类的开局中占首位。
此开局在15世纪,由西班牙棋手所创。3.Bb5一着,刚开始的简单目的,仅是换马威胁e5兵。实践证明,黑方并不怕这一点,故此在相当长的一段时间内并不流行,远不如意大利等其他开放类开局。直到19世纪末,引入了新的战略内容,又广为流行起来。发展到今天,其内容丰富,变化多端,包有多种体系。多数变例有长时间的斗争过程,也不乏短兵相接的尖锐变例。在国际国内比赛中,都得到大量应用。

菲利多尔防御

象 > 3 个兵 & 马 > 3 个兵;象 > 马;象 + 马 > 车 + 兵。

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

国际象棋的五种开局分类

1. e4 e5 2. Nf3 d6 黑棋的想法是用f5来挑战白棋的e4兵,这种走法比较坚实但略显被动。高水平的比赛里很少用。

彼得罗夫防御

今天,我们来教AI下国际象棋

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

国际象棋的五种开局分类

1.e4 e5 2.Nf3 Nf6,这个开局也很古老,到19世纪俄国棋手彼得洛夫对这个开局又作了深入研究,所以也叫做彼得洛夫防御。此开局同其他开局有显著区别的是,在第二招就要互吃e兵简化局面。白方毕竟先行一步,能够保持微小的优势。但也有的理论家认为,此开局是所有对付王兵开局中最好的一种。近年来此开局在实践中,使用的人逐渐多起来。

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

苏格兰开局

国际象棋的五种开局分类

1.e4 e5 2.Nf3 Nc6 3.d4 ,此开局首先由苏格兰棋手使用,那是在1824年,已有一百多年历史。3.d4 合乎抢占中心的原则,但是未免太直接了当,还没做好准备便开始交锋,容易被对方扳成平先。尽管如此,还有一些棋手出于策略原因,在重大比赛上使用它。如在1996年女子世界冠军赛上,匈牙利的苏珊·波尔加对我国谢军,三次走出苏格兰开局。

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

理论就讲这些,现在我们来初始化 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 9999 if board.is_stalemate(): return 0 if 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 + kingsq if board.turn: return eval else: return -eval今天,我们来教AI下国际象棋

评价函数流程图

国际象棋的五种开局分类

1.e4 e5 2.f4 王翼弃兵局已有400多年历史,在上世纪曾达鼎盛期。因其不符合现代理论,如今已在比赛场上隐退。按现代布局理论,王翼兵不可轻动,动则王翼削弱,企图以此换取占领中心和出子速度,是得不偿失的。黑方如应发得当,足可获得优势。对于年轻棋手,作为训练弃兵局的攻守技术,全面理解局面,仍然是必要的。

移动选择

二、 半开放性开局

西西里防御

国际象棋的五种开局分类

1.e4 c5 西西里防御虽然是一个古老开局,但很长时期没有被认识到它的极为深刻的内涵,直到20世纪中叶才开始流行起来。在近十年的任何重大比赛中,出现最多的开局就是西西里防御,大约占四分之一,其数量远远超过其他开局。
西西里防御具有半开放布局的代表性:既不是全开放局面,也不是封闭局面。白方往往占有空间优势,出子也略快些;黑棋子力配置具有很大反击潜力,并且占有半开c路,给反击后翼提供了重要条件。此开局的复杂性及分支体系之多,也非其他开局可比。白黑双方的胜率也基本相当;这是出现西西里防御大量对局的主要原因。
法兰西防御

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

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

国际象棋的五种开局分类

1.e4 e6 2.d4 d5 此开局由法国棋手在十六世纪创立,十九世纪开始盛行。它最早的意图是针对和抵制白方的白格象到c4,避免了像开放性布局那样,配合其他大子进攻f7兵的一系列战术。
从头两步棋来看,有点像卡罗·康防御,也是第一步做准备,第二步用d5去争夺中心;不同的是,当白兵压e5后,黑方的后翼很难出动,成为此开局的一个问题,但同时却获得通过c7-c5的有利反击,并可占领c路作为后翼进攻的途径。白方在王翼上有较大空间,子力也较通畅,有利于王翼的进攻。
此开局复杂、尖锐、多变,多数呈现半封闭状态,开局的变着也多种多样。
卡罗-康防御

国际象棋的五种开局分类

1.e4 c6 2.d4 d5 此开局在十九世纪由两位德国棋手卡罗和康共同创立。黑方第一步1.…c6 做准备,第二步2.… d5 去争中心,从这点说明比斯堪的纳维亚防御要稳固,同法兰西防御有些相像。其优点在于用c兵支持d5,后翼象很快出动,子力得以舒展。
在应1.e4不用1.… e5 的半开放性开局类中,卡罗·康防御比较简单、实用。主要策略师能避过一些尖锐变局,经过平缓的兑子过渡到残局。因此,采用此开局的棋手,多数残局功夫较好。
皮尔兹防御

国际象棋的五种开局分类

1.e4 d6 2.d4 Nf6 3.Nc3 g6 也叫乌菲姆采夫防御,王翼象防御。意图是先让白方占领中心,然后经过较充分的准备,给予中心反击,这一点有别于其他半开放性开局,明显地类似于古印度;但是与古印度不同的是中心长时间保持动态,不固定中心兵型,因而也就没有反击白方王翼。因为此开局,较长时间保持复杂性,和棋较少。近些年来,实战对局越来越多,有了很大发展。
阿廖欣防御

国际象棋的五种开局分类

1.e4 Nf6 此开局由前世界冠军阿廖欣所创。1921年用于实战,当人们第一次见到它时,惊讶不已!邀请e兵前进,再邀请c兵前进,情愿损失两三先,旨在“诱敌深入”,削弱其兵型,然后以邀兑方式再予以摧毁。这种构思同其他开局有显著区别,但经过多年实践,在多数变例中,白方能建立开局优势。如果白方犯有“急攻冒进”,则经常遭黑方有力的反击。
斯堪的纳维亚防御

为了更好地理解 minimax 算法,请看下图:

今天,我们来教AI下国际象棋

维基百科中 minimax 树举例

国际象棋的五种开局分类

1.e4 d5 这是一个古老的开局,黑方意在尽快兑兵,使大子灵活,积极制造反击。但因过早出动皇后,违反开局原则,会导致失先,因此很少有人使用。
我国少数棋手---其中主要是广东棋手吕晓莎却经常使用此开局,并得到很好效果,并丰富了此开局的内涵。人们往往只对皇后的被动易失先着眼,而忽略黑方弱子出动的效率,所以此开局还是有尝试价值的。
尼姆佐维奇防御

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

国际象棋的五种开局分类

1. e4 Nc6 黑棋让白兵在早期先控制中心,然后设法去阻止或者限制白棋的中心兵。如果白棋有不够准确的招法,黑棋就利用兵的恰到好处地进攻来收回中心的控制。
现代防御

国际象棋的五种开局分类

1. e4 g6 黑棋让白棋的兵先控制中心,黑棋的想法是不直接控制中心,而是进攻和破坏白棋的中心和中心兵

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

三、封闭式开局 后翼弃兵开局

今天,我们来教AI下国际象棋

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

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

国际象棋的五种开局分类

1.d4 d5 2.c4 在开局理论书籍中,习惯上白方不走1.e4而走任何一着,被称为封闭性开局。此类开局出现较晚,到本世纪伴随现代理论的建立,才得到很大发展;较之开放性开局和半开放开局,颇有后来居上之势。这类开局,一般都是在完成出子之后,双方的战斗才开始进行;着法含蓄,计划较强,有许多变例呈封闭局面,在高水平的比赛中出现较多。
后翼弃兵局,在此类开局中最早出现,经百年来的大量实践,常盛不衰,直到现在还是一些世界一流棋手的得力武器。
拒后翼弃兵开局

今天,我们来教AI下国际象棋

search 函数的流程图

国际象棋的五种开局分类

1.d4 d5 2. c4 e6(d5,d4...)如果接受了弃兵,实际上是放弃了中心,除非能找到好的途径。
接受后翼弃兵开局

国际象棋的五种开局分类

1. d4 d5 2. c4 dxc4 这种弃兵其实不是真正的弃兵,因为要么就很快就吃回来了,要么黑棋拿着也很难受。通常,黑棋让白棋把兵吃回,主要精力放在中心的争夺上。 斯拉夫防御

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

国际象棋的五种开局分类

1.d4 d5 2.c4 c6 斯拉夫防御,是后翼弃兵中分离出来的一种独特方案。因为正统防御走e6后,后翼象难以出动;用c6支持d5是为了尽快出子,d5兵还是要脱离岗位主动兑c兵,让出中心。尽管如此,其反击机会还是比较多的,使白方不像后翼弃兵那样心安理得地稳获先手中国象棋规则
卡塔龙开局

国际象棋的五种开局分类

1.d4 d5 2.c4 e6 3.Nf3 Nf6 4.g3 这个开局时后翼弃兵和列齐开局部分的结合体,但是它本身也自有其特色,形成的局面多数具有开放性,斗争在后翼展开,各种风格的棋手都可采用。
四、半封闭式开局
尼姆佐-印度防御

国际象棋的五种开局分类

1.d4 Nf6 2.c4 e6 3.Nc3 Bb4 尼姆佐-印度防御,是现代最流行的开局之一,也是黑方可靠的防御之一。其诱人之处在于战略战术的多样性。大体而论,黑方子力在中心活动,在王翼防守,在后翼反攻;而白方则积极组织发动在王翼的进攻。本开局能满足各种风格棋手采用,白黑双方胜率亦相差无几。
新印度防御

今天,我们来教AI下国际象棋

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

国际象棋的五种开局分类

1.d4 Nf6 2.c4 e6 3.Nf3 如果白方不想走尼姆佐维奇防御,便引向黑方新印度防御,也称后翼印度防御。此开局特点是:白方不急于占领或控制中心,而是先从容地出动子力,属平稳开局;至到中局才开始发展战斗。
古印度防御

代码如下:

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 函数:

国际象棋的五种开局分类

1.d4 Nf6 2.c4 g6 3.Nc3 Bg7 4.e4 d6 古印度防御,又称王翼印度防御。从本世纪五十年代开始流行,至今常盛不衰;是现代最流行的开局之一,在封闭性开局中占首位。黑方的策略在于先让白方占领中心,利用很早易过位和出子优势,予以反击;局面多呈封闭型,但复杂而尖锐,内容极其丰富多彩。多数变例,战斗的双方各攻一翼,对弈者须有攻守兼备的技术。在世界棋坛上,精通并主要运用此开局者,被称为“古印度大师”。
别诺尼防御

今天,我们来教AI下国际象棋

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

国际象棋的五种开局分类

1.d4 Nf6 2.c4 c5 3.d5 e6 4.Nc3 ed 5.cd d6 别诺尼防御,是从古印度防御分离出来的一种体系;但其战略目标有别。古印度防御黑方布兵d6和e5,是为了攻击王翼;而别诺尼防雨布兵d6、c5,是使g7象畅通并控制a1-h8主斜线,宜于攻击后翼。其缺点是d6兵容易遭到攻击。
格林菲尔德防御

国际象棋的五种开局分类

1.d4 Nf6 2.c4 g6 3.Nc3 d5 这个防御是由奥地利著名棋手格龙菲尔德首次走出,由此命名。主要

代码如下:

def quiesce(alpha, beta): stand_pat = evaluate_board() if (stand_pat >= beta): return beta if (alpha < stand_pat): alpha = stand_pat for 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 函数:

今天,我们来教AI下国际象棋

qui