Artificial Intelligence With Python 简明教程

AI with Python – Gaming

游戏通过策略进行。在开始游戏之前,每位玩家或团队都会制定策略,并且他们必须根据游戏中的当前情况更改或构建新策略。

Games are played with a strategy. Every player or team would make a strategy before starting the game and they have to change or build new strategy according to the current situation(s) in the game.

Search Algorithms

您还必须使用与上述相同的策略考虑计算机游戏。请注意,搜索算法是确定计算机游戏策略的算法。

You will have to consider computer games also with the same strategy as above. Note that Search Algorithms are the ones that figure out the strategy in computer games.

How it works

搜索算法的目标是找到最佳的移动集合,以便他们能够到达最终目的地并获胜。这些算法使用因游戏而异的获胜条件集合来找到最佳移动。

The goal of search algorithms is to find the optimal set of moves so that they can reach at the final destination and win. These algorithms use the winning set of conditions, different for every game, to find the best moves.

将计算机游戏可视化为一棵树。我们知道树具有节点。从根部开始,我们可以到达最终获胜节点,但采用最佳的移动。那是搜索算法的工作。此类树中的每个节点都代表一个未来状态。搜索算法通过此树搜索,并在游戏的每个步骤或节点做出决策。

Visualize a computer game as the tree. We know that tree has nodes. Starting from the root, we can come to the final winning node, but with optimal moves. That is the work of search algorithms. Every node in such tree represents a future state. The search algorithms search through this tree to make decisions at each step or node of the game.

使用搜索算法的主要缺点是它们本质上是详尽无遗的,这就是为什么它们探索整个搜索空间以找到导致浪费资源的解决方案的原因。如果这些算法需要搜索整个搜索空间以找到最终解决方案,那将更加麻烦。

The major disadvantage of using search algorithms is that they are exhaustive in nature, which is why they explore the entire search space to find the solution that leads to wastage of resources. It would be more cumbersome if these algorithms need to search the whole search space for finding the final solution.

为了消除此类问题,我们可以使用组合搜索,它利用启发式探索搜索空间,并通过消除可能的错误走法来缩小搜索空间。因此,此类算法可以节省资源。此处讨论了使用启发式探索空间并节省资源的一些算法。

To eliminate such kind of problem, we can use combinational search which uses the heuristic to explore the search space and reduces its size by eliminating the possible wrong moves. Hence, such algorithms can save the resources. Some of the algorithms that use heuristic to search the space and save the resources are discussed here −

Minimax Algorithm

这是组合搜索使用的策略,它利用启发式来加速搜索策略。极小化最大化策略的概念可以用双人游戏为例来理解,在双人游戏中,每个玩家尝试预测对手的下一步走法并尝试最小化该函数。此外,为了获胜,玩家始终尝试根据当前情况最大化其自己的函数。

It is the strategy used by combinational search that uses heuristic to speed up the search strategy. The concept of Minimax strategy can be understood with the example of two player games, in which each player tries to predict the next move of the opponent and tries to minimize that function. Also, in order to win, the player always try to maximize its own function based on the current situation.

启发式在极小化最大化之类的策略中扮演着重要角色。树的每个节点都会有一个与其关联的启发式函数。根据启发式,它将做出决定,向对他们最有利的节点移动。

Heuristic plays an important role in such kind of strategies like Minimax. Every node of the tree would have a heuristic function associated with it. Based on that heuristic, it will take the decision to make a move towards the node that would benefit them the most.

Alpha-Beta Pruning

极小化最大化算法的一个主要问题是它可以探索树中那些与问题无关的部分,从而导致资源浪费。因此,必须有一个策略来决定树的哪些部分是相关的,哪些部分是不相关的,并让不相关的部分未被探索。Alpha-Beta 剪枝就是这样一种策略。

A major issue with Minimax algorithm is that it can explore those parts of the tree that are irrelevant, leads to the wastage of resources. Hence there must be a strategy to decide which part of the tree is relevant and which is irrelevant and leave the irrelevant part unexplored. Alpha-Beta pruning is one such kind of strategy.

Alpha-Beta 剪枝算法的主要目标是避免搜索树中那些没有任何解决方案的部分。Alpha-Beta 剪枝的主要概念是使用两个边界,名为 Alpha ,最大下限,和 Beta ,最小上限。这两个参数是限制一组可能解决方案的值。它将当前节点的值与 alpha 值和 beta 值进行比较,以便它可以移动到具有解决方案的树部分并丢弃其余部分。

The main goal of Alpha-Beta pruning algorithm is to avoid the searching those parts of the tree that do not have any solution. The main concept of Alpha-Beta pruning is to use two bounds named Alpha, the maximum lower bound, and Beta, the minimum upper bound. These two parameters are the values that restrict the set of possible solutions. It compares the value of the current node with the value of alpha and beta parameters, so that it can move to the part of the tree that has the solution and discard the rest.

Negamax Algorithm

此算法与极小化最大化算法没有区别,但它具有更优雅的实现。使用极小化最大化算法的主要缺点是,我们需要定义两个不同的启发式函数。这些启发式之间的联系是,游戏中的一个状态对一个玩家越好,对另一个玩家就越糟。在 Negamax 算法中,两个启发式函数的相同工作是在单个启发式函数的帮助下完成的。

This algorithm is not different from Minimax algorithm, but it has a more elegant implementation. The main disadvantage of using Minimax algorithm is that we need to define two different heuristic functions. The connection between these heuristic is that, the better a state of a game is for one player, the worse it is for the other player. In Negamax algorithm, the same work of two heuristic functions is done with the help of a single heuristic function.

Building Bots to Play Games

对于在 AI 中构建机器人来玩双人游戏,我们需要安装 easyAI 库。它是一个人工智能框架,提供构建双人游戏的所有功能。你可以使用以下命令下载它:

For building bots to play two player games in AI, we need to install the easyAI library. It is an artificial intelligence framework that provides all the functionality to build two-player games. You can download it with the help of the following command −

pip install easyAI

A Bot to Play Last Coin Standing

在这个游戏中,一堆硬币。每个玩家都必须从这堆硬币中取出一定数量的硬币。游戏的目标是避免拿走堆中最后一个硬币。我们将使用 LastCoinStanding 类,该类继承自 easyAI 库中的 TwoPlayersGame 类。以下代码显示了此游戏的 Python 代码:

In this game, there would be a pile of coins. Each player has to take a number of coins from that pile. The goal of the game is to avoid taking the last coin in the pile. We will be using the class LastCoinStanding inherited from the TwoPlayersGame class of the easyAI library. The following code shows the Python code for this game −

导入所需的包,如所示:

Import the required packages as shown −

from easyAI import TwoPlayersGame, id_solve, Human_Player, AI_Player
from easyAI.AI import TT

现在,从 TwoPlayerGame 类继承该类来处理游戏的全部操作:

Now, inherit the class from the TwoPlayerGame class to handle all operations of the game −

class LastCoin_game(TwoPlayersGame):
   def __init__(self, players):

现在,定义玩家和将开始游戏的玩家。

Now, define the players and the player who is going to start the game.

self.players = players
self.nplayer = 1

现在,定义游戏中硬币的数量,这里我们使用 15 枚硬币进行游戏。

Now, define the number of coins in the game, here we are using 15 coins for the game.

self.num_coins = 15

定义玩家在一个移动中可以拿到的最大硬币数。

Define the maximum number of coins a player can take in a move.

self.max_coins = 4

现在需要定义一些确定的事情,如以下代码所示。定义可能的移动。

Now there are some certain things to define as shown in the following code. Define possible moves.

def possible_moves(self):
   return [str(a) for a in range(1, self.max_coins + 1)]

定义硬币的移除情况。

Define the removal of the coins

def make_move(self, move):
   self.num_coins -= int(move)

定义谁拿走了最后一个硬币。

Define who took the last coin.

def win_game(self):
   return self.num_coins <= 0

定义何时停止游戏,即何时有人获胜。

Define when to stop the game, that is when somebody wins.

def is_over(self):
   return self.win()

定义如何计算分数。

Define how to compute the score.

def score(self):
   return 100 if self.win_game() else 0

定义堆中剩余的硬币数。

Define number of coins remaining in the pile.

def show(self):
   print(self.num_coins, 'coins left in the pile')
if __name__ == "__main__":
   tt = TT()
   LastCoin_game.ttentry = lambda self: self.num_coins

使用以下代码块解决游戏 -

Solving the game with the following code block −

r, d, m = id_solve(LastCoin_game,
   range(2, 20), win_score=100, tt=tt)
print(r, d, m)

决定谁将开始游戏

Deciding who will start the game

game = LastCoin_game([AI_Player(tt), Human_Player()])
game.play()

您可以找到以下输出,以及该游戏的简单玩法 -

You can find the following output and a simple play of this game −

d:2, a:0, m:1
d:3, a:0, m:1
d:4, a:0, m:1
d:5, a:0, m:1
d:6, a:100, m:4
1 6 4
15 coins left in the pile
Move #1: player 1 plays 4 :
11 coins left in the pile
Player 2 what do you play ? 2
Move #2: player 2 plays 2 :
9 coins left in the pile
Move #3: player 1 plays 3 :
6 coins left in the pile
Player 2 what do you play ? 1
Move #4: player 2 plays 1 :
5 coins left in the pile
Move #5: player 1 plays 4 :
1 coins left in the pile
Player 2 what do you play ? 1
Move #6: player 2 plays 1 :
0 coins left in the pile

A Bot to Play Tic Tac Toe

井字棋非常熟悉,是其中最受欢迎的游戏之一。让我们通过在 Python 中使用 easyAI 库来创建此游戏。以下代码是此游戏的 Python 代码 -

Tic-Tac-Toe is very familiar and one of the most popular games. Let us create this game by using the easyAI library in Python. The following code is the Python code of this game −

按所示导入包 -

Import the packages as shown −

from easyAI import TwoPlayersGame, AI_Player, Negamax
from easyAI.Player import Human_Player

TwoPlayerGame 类继承类,处理游戏的全部操作 -

Inherit the class from the TwoPlayerGame class to handle all operations of the game −

class TicTacToe_game(TwoPlayersGame):
   def __init__(self, players):

现在,定义玩家和将要开始游戏的玩家 -

Now, define the players and the player who is going to start the game −

self.players = players
self.nplayer = 1

定义棋盘的类型 -

Define the type of board −

self.board = [0] * 9

现在,有某些事情需要按如下方式定义 -

Now there are some certain things to define as follows −

定义可能的移动

Define possible moves

def possible_moves(self):
   return [x + 1 for x, y in enumerate(self.board) if y == 0]

定义玩家的移动 -

Define the move of a player −

def make_move(self, move):
   self.board[int(move) - 1] = self.nplayer

为提高人工智能,定义何时玩家移动 -

To boost AI, define when a player makes a move −

def umake_move(self, move):
   self.board[int(move) - 1] = 0

定义对手在线形成三连的失败条件

Define the lose condition that an opponent have three in a line

def condition_for_lose(self):
   possible_combinations = [[1,2,3], [4,5,6], [7,8,9],
      [1,4,7], [2,5,8], [3,6,9], [1,5,9], [3,5,7]]
   return any([all([(self.board[z-1] == self.nopponent)
      for z in combination]) for combination in possible_combinations])

定义对游戏结束进行检查

Define a check for the finish of game

def is_over(self):
   return (self.possible_moves() == []) or self.condition_for_lose()

显示玩家在游戏中当前的位置

Show the current position of the players in the game

def show(self):
   print('\n'+'\n'.join([' '.join([['.', 'O', 'X'][self.board[3*j + i]]
      for i in range(3)]) for j in range(3)]))

计算分数。

Compute the scores.

def scoring(self):
   return -100 if self.condition_for_lose() else 0

定义主方法,以定义算法并开始游戏 -

Define the main method to define the algorithm and start the game −

if __name__ == "__main__":
   algo = Negamax(7)
   TicTacToe_game([Human_Player(), AI_Player(algo)]).play()

您可以看到以下输出,以及该游戏的简单玩法 -

You can see the following output and a simple play of this game −

. . .
. . .
. . .
Player 1 what do you play ? 1
Move #1: player 1 plays 1 :
O . .
. . .
. . .
Move #2: player 2 plays 5 :
O . .
. X .
121
. . .
Player 1 what do you play ? 3
Move #3: player 1 plays 3 :
O . O
. X .
. . .
Move #4: player 2 plays 2 :
O X O
. X .
. . .
Player 1 what do you play ? 4
Move #5: player 1 plays 4 :
O X O
O X .
. . .
Move #6: player 2 plays 8 :
O X O
O X .
. X .