使用Python创建属于你的国际象棋AI

Python3

最后更新 2020-10-23 16:23

阅读 120

最后更新 2020-10-23 16:23

阅读 120

Python3

##FlyAI文献翻译

**英文原文:**[:Let’s create a Chess AI](https://medium.com/dscvitpune/lets-create-a-chess-ai-8542a12afef)

> **标签** :Python

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836298314379.png)

Chess has been played by the world’s masterminds for ages and is the game where the brain needs a lot of processing. So, how can we teach a computer to play a mastermind game like chess? Let’s check it out.

To get started all you need is a python3 interpreter installed in your system and the basic level of python3. Cool right?

> 国际象棋已经被世界上的智囊们玩了很久,是一种需要大脑进行大量处理的游戏。那么,我们怎样才能教电脑玩象棋这样的游戏呢?我们来看看吧。

>要开始使用,您只需要在系统中安装python3解释器和python3的基本级别。很酷吧?

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836302228149.png)

**Today’s Outline**

1. Board Representation

3. Board Evaluation

5. Move Selection

7. Testing our AI

9. Making an Interface

>**今天的概要**

>1. Board 表现形式

2. Board 评估

3. 移动选择

4. 测试AI

5. 制作界面

**Board Representation**

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836298728531.png)

Before writing any algorithm for our engine it’s important for us to code the logic behind chess pieces i.e. assign every possible legal move to each and every chess piece.

For that, our work has been made a lot simpler by the [python-chess](https://github.com/niklasf/python-chess "python-chess") library which will provide us with all of the move generation and validation. So, let’s start by installing it.

>在为引擎编写任何算法之前,对我们来说,对棋子背后的逻辑进行编码非常重要,也就是说,将每一个可能的合法举动分配给每一个棋子。

>为此,python-chess 库使我们的工作变得简单得多,该库将为我们提供所有移动生成和验证。 因此,让我们从安装它开始。

```

!pip install python-chess

```

Now, as we have the library installed, we can start by importing and then initializing the board.

>现在,我们安装好了库,我们通过导入和初始化棋盘开始。

```

import chess

board = chess.Board()

board

```

This will be the output which you will be able to see in your notebook.

>下图所示将会输出在你的笔记本上

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836297472553.png)

Output-1

This board object will be the complete board representation which will provide us with some important functions such as board.is_checkmate() to check if there’s a checkmate, board.push() to append a move, board.pop() to undo the last move, etc. You can read the complete documentation [here](https://python-chess.readthedocs.io/en/latest/ "here").

> 输出-1

>该棋盘对象的表示形式是完整的棋盘,它将为我们提供一些重要的功能,例如board.is_checkmate()来检查是否有一个棋盘格,board.push()来附加一个动作,board.pop()来撤销最后一个移动等。您可以在here阅读完整的文档。

**Board Evaluation**

For evaluating the board initially, we must think about how a Grandmaster would think in his respective match.

>**Board评估**

>为了初步评估Board,我们必须考虑大师在各自比赛中的想法。

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836298516551.png)

ome of the points which should come in our mind are:

1. Avoid exchanging one minor piece for three pawns.

3. Always have the bishop in pairs.

5. Avoid exchanging two minor pieces for a rook and a pawn.

So, the equations from the above insights will be:

1. Bishop > 3 Pawns & Knight > 3 Pawns

3. Bishop > Knight

5. Bishop + Knight > Rook + Pawn

By simplifying the above equations, we get Bishop > Knight > 3 Pawns. Also, we must convert the third equation as Bishop + Knight = Rook + 1.5 Pawn as two minor pieces are worth a rook and two pawns.

>在我们脑海中浮现的一些要点:

>1. 避免将一个较小的棋子换成三个兵。

2. 使象成对出现。

3. 避免将两个棋子交换车和兵。

>从以上见解中得到以下公式:

>1. 象>3兵 &马>3兵

2. 象>马

3. 象+马>车+兵

>通过简化以上等式,我们得到象> 马> 3 兵。 此外,我们必须将第三个方程转换为 象 + 马 = 车 + 1.5 兵,因为两个较小的棋子值得一个车和两个兵。

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836300572071.png)

We will use [piece square tables](https://www.chessprogramming.org/Piece-Square_Tables "piece square tables") to evaluate our board pieces and the values will be set in an 8x8 matrix such as in chess such that it must have a higher value at favorable positions and a lower value at a non-favorable place.

For example, the probability of the white’s king crossing the centerline will be less than 20% and therefore we will place negative values in that matrix.

Let’s take another example, suppose the Queen, she would like her to be placed at the center position as she can dominate more number of positions from the center and therefore we will set higher values at the center and the same for the other pieces as chess is all about defending the king and dominating the center.

Enough of the theory lets initialize the piece square tables:

>我们将使用棋子方桌来评估我们的棋盘棋子,并将这些值设置在8x8矩阵中(例如象棋中),以使其在有利位置必须具有较高的值,而在不利位置则必须具有较低的值。

>例如,白人国王越过中心线的概率将小于20%,因此我们将负值放置在该矩阵中。

>让我们再举一个例子,假设王后,她希望将她放置在中心位置,因为她可以控制中心位置的更多位置,因此我们将在中心设置更高的值,而在其他棋子上将其设置为更高的值 就是要保卫国王并控制中心。

>足够的理论让我们初始化块棋盘:

```

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]

```

Now let’s get our evaluation function by following these four methods:

>现在,通过以下四种方法获取评估功能:

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836300271549.png)

Firstly, let’s check if the game is still going on.

Now the logic behind coding this stage is that If it returns true at checkmate then it will check whose turn to make a move, if the current turn is of WHITE it must return -9999 i.e previous turn must be of BLACK, and BLACK wins or else it must return +9999 and then White wins. For stalemate or any insufficient material, let’s return 0 as its draw.

So, let’s code:

>首先,让我们检查游戏是否仍在继续。

>现在,对该阶段进行编码的逻辑是,如果它在将要执行的回合中返回true,那么它将检查要进行移动的回合,如果当前回合为白色,则必须返回-9999,即前一回合必须为BLACK,BLACK获胜或 必须返回+9999,然后White获胜。 对于僵持或子力不足的情况,让我们返回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

```

Secondly, we must calculate the total number of pieces so that we can pass it into our material function.

>其次,我们必须计算棋子数目,以便将其传递给我们的子力函数。

```

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))

```

Third, let’s calculate the scores.

The material score is calculated by the summation of all respective piece’s weights multiplied by the difference between the number of that respective piece between white and black.

The individual pieces score is the sum of piece-square values of positions where the respective piece is present at that instance of the game.

>第三,计算得分。

>子力分值:将所有相应棋子的权重之和乘以该相应棋子在白色和黑色之间的数量之差。

>单个棋子得分是在该游戏实例中相应棋子所在位置的棋子平方值之和。

```

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)])

```

At last, let’s calculate the evaluation function which will return the summation of the material scores and the individual scores for white and when it comes for black, let’s negate it.

(As, favorable conditions for White = unfavorable conditions for Black)

>最后,让我们计算评估函数,它将返回白子的子力分值和单独分值的总和,对于黑色,让我们否定它。

>(例如,白色的有利条件=黑色的不利条件)

```

eval = material + pawnsq + knightsq + bishopsq + rooksq + queensq + kingsqif board.turn:

return eval

else:

return -eval

```

Let's summarize our evaluation function right now, with the help of the flowchart given below:

>现在,我们利用下面的流程图总结一下我们的评分功能:

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836298770644.png)

Flowchart for the evaluation function

>评分功能流程图

**Move Selection**

This will be the last step for our algorithm where we will use the[ Negamax](https://www.chessprogramming.org/Negamax " Negamax") Implementation of the [Minimax Algorithm](https://www.chessprogramming.org/Minimax "Minimax Algorithm") which is a mostly used algorithm for any two-player games such as checkers, snake, and ladders, etc. Then will later optimize it using[ Alpha-Beta pruning ](https://www.chessprogramming.org/Alpha-Beta " Alpha-Beta pruning ")which will in turn reduce our execution time.

>**移动选择**

>这是我们算法的最后一步,我们将使用Minimax算法的Negamax实现,Minimax算法是任何两人游戏(如跳棋、蛇和梯子等)最常用的算法。然后将使用Alpha-Beta修剪对其进行优化,从而减少我们的执行时间。

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836302622320.png)

For the smartness of our engine, we can use the initial moves from a book in which moves will be stored with a lot of opening moves by chess Grandmasters in a bin format. You can download some of them from here.

>为了引擎的智能化,我们可以使用一本书中的初始棋步,在书中,棋手们将以bin格式存储大量的开局棋。你可以产品能从here下载。

```

import chess.polygot

try:

move = chess.polyglot.MemoryMappedReader("C:/Users/your_path/books/human.bin").weighted_choice(board).move

return move

```

Now, let’s dig into our minimax algorithm. It’s a decision rule used in [artificial intelligence](https://www.chessprogramming.org/Artificial_Intelligence "artificial intelligence"), decision theory, game theory, statistics, and philosophy for minimizing the possible loss for a worst-case scenario. In simple words, at each step, it assumes that player A is trying to maximize its chances of winning, and in the next turn player B is trying to minimize the chances of winning.

Check out the tree from below for a better understanding of the algorithm:

>在,让我们深入研究minimax算法。 这是 artificial intelligence 中决策理论,博弈论,统计和哲学使用的决策规则,用于将最坏情况下的可能损失降至最低。 简而言之,它假设在每个步骤中,玩家A都在试图最大化其获胜的机会,而下一轮玩家B则试图将其获胜的机会降到最低。

>从下面的结构树更好的理解算法:

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836295420512.png)

A minimax tree example from Wikipedia

But we will be using the negamax variant of minimax for better results as we will need only one function that is to maximize the utility of both the players. The difference is that here, one player loss is equal to another player’s gain and vice versa. In terms of the game, the value of the given position to the first player is the negation of the value to the second player.

You can differentiate the tree given below.

>维基百科的一个minimax结构树例子

>但是我们将使用minimax的negamax变量来获得更好的结果,因为我们只需要一个功能,即最大化两个参与者的益处。不同之处在于,一个玩家的损失等于另一个玩家的收益,反之亦然。在游戏中,给第一个玩家的位置值是对第二个玩家的值的否定。

>你可以区分下面的结构树.

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836294158484.png)

A negamax tree example

Initially, we will set alpha as negative infinity and beta is positive infinity so that, both players start with the worst possible score. So, let's code.

>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

```

Okay, so let's understand what we did here with this flowchart:

>理解下面的流程图做了什么:

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836298224881.png)

Flowchart for the search function

Now, the next step is the alpha-beta pruning for the optimization of our execution speed.

Let’s not go deep in the algorithm but just understand that we are applying this logic just to eliminate most of the unnecessary iterations.

>搜索功能流程图

>现在,下一步是用于优化执行速度的alpha-beta修剪。

>我们不必深入研究算法,只要理解我们应用这个逻辑只是为了消除大多数不必要的迭代。

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836297565085.png)

An illustration of alpha-beta pruning from Wikipedia

Let’s Code:

>维基百科中的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

```

Now, let’s revise the alphabeta function with this flowchart given below:

>现在,让我们用下面给出的流程图修改alphabeta函数:

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836300666881.png)

Flowchart for the alphabeta function

Now comes the Quiescence search, the purpose of this search is to only evaluate “quiet” positions, i.e the positions where there are no winning tactical moves to be made.

This search is needed to avoid the[ horizon effect](https://www.chessprogramming.org/Horizon_Effect " horizon effect") which is caused by the depth limitation of the search algorithm.

> alphabeta 函数流程图

>现在是 Quiescence 搜索,这个搜索的目的只是评估“quiet”的位置,即没有获胜战术动作的位置。

>这种搜索是为了避免由于搜索算法的深度限制而引起的 horizon effect。

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836300904689.png)

A Gif for illustrating the horizon effect

Let’s understand the horizon effect with the above-given gif like there’s a stage when our brain stops to respond when we are overthinking something and this same happens here and that’s why we apply the quiescence search.

Okay, let’s code:

>显示horizon effect的Gif

>让我们来理解上面给的gif的 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

```

So let’s summarise the function in a bit:

>函数总结:

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836299625771.png)

Flowchart for the quiesce function

And now we are ready with our algorithm. Thanks for your patience guys.

>quiesce函数流程图

>现在已经准备好了算法,感谢你们的耐心。

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836300744493.png)

**Testing our AI**

Before starting to code the testing part we will need to import some of the libraries so let’s get to it:

>**测试AI**

>在开始编写测试部分代码之前,我们需要导入一些库,让我们开始:

```

import chess.svg

import chess.pgn

import chess.engine

from IPython.display import SVG

```

Now, today we will be doing three tests today which will be

1. AI Vs Human

3. Self Play (i.e AI vs AI)

5. AI Vs Stockfish (You can get info about stockfish12 here)

So, without wasting any further time let’s get started.

**AI Vs Human**

>今天我们要做三个测试

>1. 人工智能Vs人类

2. 自演(即人工智能vs人工智能)

3. AI Vs Stockfish(你可以在这里获得关于stockfish12的信息)

>所以,不用再浪费时间了,我们开始吧。

>**人工智能Vs人类 **

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836300146111.png)

```

# use this for computer move

mov = selectmove(3)

board.push(mov)

board# use this for human move, where e5 is the example move

board.push_san("e5")

board

```

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836297767574.png)

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836295828298.png)

Output-2

So, the AI chooses to go g1f3, which is a pretty smart move.

Self-Play

Let’s make our AI fight itself now:

>输出-2

>所以,人工智能选择了g1f3,这是一个相当聪明的举动。

>**自演**

>现在让我们的AI自己战斗:

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836301921297.png)

```

count = 0

movehistory = []

game = chess.pgn.Game()

board = chess.Board()while not board.is_game_over(claim_draw=True):

if board.turn:

count += 1

print(f'\n{count}]\n')

move = selectmove(3)

board.push(move)

print(board)

print()

else:

move = selectmove(3)

board.push(move)

print(board)game.add_line(movehistory)

game.headers["Event"] = "Self Tournament 2020"

game.headers["Site"] = "Pune"

game.headers["Date"] = str(datetime.datetime.now().date())

game.headers["Round"] = 1

game.headers["White"] = "Ai"

game.headers["Black"] = "Ai"

game.headers["Result"] = str(board.result(claim_draw=True))print(game)

SVG(chess.svg.board(board=board,size=400))

```

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836297324267.png)

Output-3

**AI Vs Stockfish**

Now, let’s make our AI fight Stockfish. You can download the Stockfish engine from here.

>输出-3

>**AI Vs Stockfish **

>现在,让我们使AI与Stockfish战斗。 您可以从此处下载Stockfish引擎。

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836302754335.png)

```

count = 0

movehistory = []

game = chess.pgn.Game()

board = chess.Board()

engine = chess.engine.SimpleEngine.popen_uci("your_path/stockfish.exe")while not board.is_game_over(claim_draw=True):

if board.turn:

count += 1

print(f'\n{count}]\n')

move = engine.play(board, chess.engine.Limit(time=0.1))

movehistory.append(move.move)

board.push(move.move)

print(board)

else:

move = selectmove(3)

movehistory.append(move)

board.push(move)

print(board)game.add_line(movehistory)

game.headers["Result"] = str(board.result(claim_draw=True))print(game)SVG(chess.svg.board(board=board, size=400))

```

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836297905219.png)

Output-4

So, yes our AI is not smart enough to beat the stockfish 12 but still, he managed to keep the fight for 20 moves.

There are a lot more open-source UCI compatible chess engines available for more of the testing purposes, you can find them here.

>输出-4

>因此,是的,我们的AI不够聪明,无法击败stockfish12,但他仍然设法争取20招。

>有更多开放源代码的UCI兼容国际象棋引擎可用于更多测试目的,您可以在这里找到它们。

**Making an Interface**

The above testing seems to be a lot of code. That’s why let’s code an interface, clean up our code, and then test our AI again.

>**制作界面**

>上面的测试似乎是很多代码。 这就是为什么我们要编写一个界面代码,清理代码,然后再次测试我们的AI。

```

# Remaining imports

import traceback

from flask import Flask, Response, request

import webbrowser# Searching Ai's Move

def aimove():

move = selectmove(3)

board.push(move)# Searching Stockfish's Move

def stockfish():

engine = chess.engine.SimpleEngine.popen_uci(

"your_path/stockfish.exe")

move = engine.play(board, chess.engine.Limit(time=0.1))

board.push(move.move)app = Flask(__name__)# Front Page of the Flask Web Page

@app.route("/")

def main():

global count, board

ret = ''

ret += ''

ret += ''

ret += '

' % time.time()

ret += 'New Game'

ret += 'Undo Last Move'

ret += ''

ret += 'Make Ai Move'

ret += 'Make Stockfish Move'

return ret# Display Board

@app.route("/board.svg/")

def board():

return Response(chess.svg.board(board=board, size=700), mimetype='image/svg+xml')# Human Move

@app.route("/move/")

def move():

try:

move = request.args.get('move', default="")

board.push_san(move)

except Exception:

traceback.print_exc()

return main()# Make Ai’s Move

@app.route("/dev/", methods=['POST'])

def dev():

try:

aimove()

except Exception:

traceback.print_exc()

return main()# Make UCI Compatible engine's move

@app.route("/engine/", methods=['POST'])

def engine():

try:

stockfish()

except Exception:

traceback.print_exc()

return main()# New Game

@app.route("/game/", methods=['POST'])

def game():

board.reset()

return main()# Undo

@app.route("/undo/", methods=['POST'])

def undo():

try:

board.pop()

except Exception:

traceback.print_exc()

return main()

```

Now, let's execute it all in the next block.

>现在,让我们在下一个board中全部执行。

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836296293830.png)

Final Output

Thanks for reading out patiently guys. We have successfully completed our Chess AI in about 12 minutes. Now, we can have fun.

> 最后输出

>感谢大家耐心的阅读。 我们已经在大约12分钟内成功完成了Chess AI。 现在,我们可以玩得开心。

![](https://static.leiphone.com/uploads/new/sns/article/202010/1602836302356575.png)

**Conclusion**

I hope you guys understood most of the things we coded. If not, don’t hesitate to ask your questions in the comment box. As this was a basic implementation of creating a chess engine, I would like to hear what you guys think can make this Chess AI more smarter? Comment down below.

Also, for more information, you can visit [here](https://www.chessprogramming.org/Main_Page "here").

And all of the code can be found[ here](https://github.com/AnshGaikwad/Chess-World " here").

>**结论**

>希望你们能理解我们编写的大部分内容。 如果没有,请随时在评论框中提出您的问题。 因为这是创建国际象棋引擎的基本实现,所以我想听听你们认为可以使这种国际象棋AI更智能吗? 在下方留言。

>另外,有关更多信息,您可以在这里访问。

>所有代码都可以在这里找到。

讨论

500字

表情

每日优质讨论奖励 20FAI发送

每日优质讨论奖励 20FAI

删除确认

是否删除该条评论?

取消

删除

python国际象棋ai程序_使用Python创建属于你的国际象棋AI相关推荐

  1. python国际象棋ai程序_用Python编写一个国际象棋AI程序

    最近我用Python做了一个国际象棋程序并把代码发布在Github上了.这个代码不到1000行,大概20%用来实现AI.在这篇文章中我会介绍这个AI如何工作,每一个部分做什么,它为什么能那样工作起来. ...

  2. python国际象棋ai程序_用 Python 编写一个国际象棋 AI 程序

    最近我用Python做了一个国际象棋程序并把代码发布在Github上了.这个代码不到1000行,大概20%用来实现AI.在这篇文章中我会介绍这个AI如何工作,每一个部分做什么,它为什么能那样工作起来. ...

  3. python写机器人程序_用Python写的一个多线程机器人聊天程序

    本人是从事php开发的, 近来想通过php实现即时通讯(兼容windows).后来发现实现起来特别麻烦, 就想到python.听说这家伙在什么地方都能发挥作用.所以想用python来做通讯模块...所 ...

  4. python二分法查找程序_查找Python程序的输出| 套装2(基础)

    python二分法查找程序 Program 1: 程序1: a = 10 b = 3 res = a/b print "a/b: ", res res = float(a/b) p ...

  5. 用python写投票程序_大话python最终篇,web.py 开发的投票程序demo

    概述 开发语言         python Web开发框架  web.py 前端开发框架   vuejs+elementui 数据库              mysql 设计思路 首先是数据库设计 ...

  6. python收集数据程序_用Python挖掘Twitter数据:数据采集

    原标题:用Python挖掘Twitter数据:数据采集 作者:Marco Bonzanini 翻译:数盟 这是7部系列中的第1部分,注重挖掘Twitter数据以用于各种案例.这是第一篇文章,专注于数据 ...

  7. python写新年快乐程序_新年快乐! python实现绚烂的烟花绽放效果

    新年快乐! python实现绚烂的烟花绽放效果 来源:中文源码网    浏览: 次    日期:2019年11月5日 [下载文档:  新年快乐! python实现绚烂的烟花绽放效果.txt ] (友情 ...

  8. python 小游戏程序_用 Python 写个消消乐小游戏

    文 |野客 来源:Python 技术「ID: pythonall」 提到开心消消乐这款小游戏,相信大家都不陌生,其曾在 2015 年获得过玩家最喜爱的移动单机游戏奖,受欢迎程度可见一斑,本文我们使用 ...

  9. python人工智能小程序_杭州python小程序

    杭州python小程序 来源:教育联展网    编辑:佚名    发布时间:2018-10-19 Java.PHP.Python哪个就业前景比较好 具体对比分析如下: Java语言特点:所有Andro ...

最新文章

  1. conda 装tensorboardx_【工欲善其事】TensorboardX的使用
  2. Postfix邮件地址改写(header)
  3. Java为什么会存成undefined,为什么我在Java中获得NoClassDefFoundError?
  4. OpenLayers学习笔记5——使用jQuery UI实现查询并标注(UI篇)
  5. Go在谷歌:以软件工程为目的的语言设计
  6. 中邮智递通过数加和datav将系统和服务迁移到大数据平台
  7. url带多个参数_动态URL和静态URL做seo优化不必二选一
  8. 学习笔记DL003:神经网络第二、三次浪潮,数据量、模型规模,精度、复杂度,对现实世界冲击...
  9. 以前的模板太糟糕了?
  10. 办公自动化系统项目报告
  11. Jira配置LDAP实现统一认证
  12. 算法4-中兴捧月杯热身赛1素数判断-热身赛2亲和串-热身赛3旅游路线-
  13. 51单片机之继电器实验
  14. php文字如何排版,文字排版,二十个文字排版技巧教程
  15. 文献阅读—GAIN:Missing Data Imputation using Generative Adversarial Nets
  16. 我们为什么选择NEXTCHIP?为什么要选择ISP?为什么要选择AHD?为什么选择北京冠宇铭通?
  17. java: You aren't using a compiler supported by lombok, so lombok will not work and has been disab...
  18. 弥散圆以及最大弥散圆
  19. gitee提交代码碰见的报错:error:failed to push some refs to ‘https: //gitee.com/....‘
  20. 针对 WS-Discovery 协议的威胁观察

热门文章

  1. 两种方法实现图片懒加载
  2. 实现indexof()
  3. 学校如何搭建文件服务器,学校服务器搭建
  4. 头条限流是什么原因_抖音为什么会被限流?被限流了如何补救?
  5. python generator长度_Python 高级特性之:生成器(generator)和迭代器(Iterator)
  6. 羊车门问题python程序_用Python实现羊车门问题
  7. 柯尼卡美能达打印机c226使用说明_高效便捷柯尼卡美能达C226复印机优惠中-柯尼卡美能达 C226_西安复印机行情...
  8. cubrid php,PHP - Manual: CUBRID (官方文档)
  9. 宝塔linux apache怎么部署证书,Linux+Apache部署SSL证书方法步骤
  10. postgresql 删除触发器_postgresql 触发器