Pythonを使用したAI–ゲーム
ゲームは戦略を持ってプレイされます。すべてのプレーヤーまたはチームは、ゲームを開始する前に戦略を立て、ゲームの現在の状況に応じて新しい戦略を変更または構築する必要があります。
検索アルゴリズム
上記と同じ戦略でコンピュータゲームも検討する必要があります。検索アルゴリズムは、コンピュータゲームの戦略を理解するものであることに注意してください。
使い方
検索アルゴリズムの目標は、最終目的地に到達して勝つことができるように、最適な一連の動きを見つけることです。これらのアルゴリズムは、ゲームごとに異なる勝利条件のセットを使用して、最良の動きを見つけます。
コンピュータゲームをツリーとして視覚化します。ツリーにはノードがあることがわかっています。ルートから始めて、最終的な勝者ノードに到達できますが、最適な動きがあります。それが検索アルゴリズムの仕事です。このようなツリーのすべてのノードは、将来の状態を表します。検索アルゴリズムは、このツリーを検索して、ゲームの各ステップまたはノードで決定を下します。
組み合わせ検索
検索アルゴリズムを使用することの主な欠点は、本質的に網羅的であるということです。そのため、検索スペース全体を探索して、リソースの浪費につながるソリューションを見つけます。これらのアルゴリズムが最終的な解決策を見つけるために検索空間全体を検索する必要がある場合は、より面倒になります。
このような問題を解消するために、ヒューリスティックを使用して検索スペースを探索し、起こりうる誤った動きを排除することでサイズを縮小する組み合わせ検索を使用できます。したがって、そのようなアルゴリズムはリソースを節約できます。ここでは、ヒューリスティックを使用してスペースを検索し、リソースを節約するアルゴリズムのいくつかについて説明します。
ミニマックスアルゴリズム
これは、ヒューリスティックを使用して検索戦略を高速化する、組み合わせ検索で使用される戦略です。ミニマックス戦略の概念は、各プレーヤーが対戦相手の次の動きを予測し、その機能を最小化しようとする2人のプレーヤーのゲームの例で理解できます。また、勝つために、プレイヤーは常に現在の状況に基づいて自分の機能を最大化しようとします。
ヒューリスティックは、ミニマックスのような種類の戦略で重要な役割を果たします。ツリーのすべてのノードには、ヒューリスティック関数が関連付けられています。そのヒューリスティックに基づいて、最も利益をもたらすノードに向かって移動するかどうかを決定します。
アルファベータ法
Minimaxアルゴリズムの主な問題は、ツリーの無関係な部分を探索できることであり、リソースの浪費につながります。したがって、ツリーのどの部分が関連していて、どの部分が無関係であるかを決定し、無関係な部分を未踏のままにしておく戦略が必要です。アルファベータ法はそのような戦略の1つです。
アルファベータプルーニングアルゴリズムの主な目標は、解決策がないツリーの部分を検索しないようにすることです。アルファベータ法の主な概念は、次の名前の2つの境界を使用することです。Alpha、最大下限、および Beta、最小上限。これらの2つのパラメーターは、可能な解決策のセットを制限する値です。現在のノードの値をアルファおよびベータパラメータの値と比較して、ソリューションのあるツリーの部分に移動し、残りを破棄できるようにします。
Negamaxアルゴリズム
このアルゴリズムはMinimaxアルゴリズムと同じですが、より洗練された実装になっています。Minimaxアルゴリズムを使用する主な欠点は、2つの異なるヒューリスティック関数を定義する必要があることです。これらのヒューリスティック間の関係は、ゲームの状態が1人のプレーヤーにとって良いほど、他のプレーヤーにとっては悪いということです。Negamaxアルゴリズムでは、2つのヒューリスティック関数の同じ作業が1つのヒューリスティック関数の助けを借りて行われます。
ゲームをプレイするためのボットの構築
AIで2人のプレーヤーのゲームをプレイするボットを構築するには、 easyAI図書館。これは、2人用ゲームを構築するためのすべての機能を提供する人工知能フレームワークです。次のコマンドを使用してダウンロードできます-
pip install easyAI
ラストコインスタンディングをプレイするボット
このゲームでは、コインの山があります。各プレイヤーは、その山からいくつかのコインを取得する必要があります。ゲームの目的は、山の最後のコインを取るのを避けることです。クラスを使用しますLastCoinStanding から継承 TwoPlayersGame のクラス easyAI図書館。次のコードは、このゲームのPythonコードを示しています-
図のように必要なパッケージをインポートします-
from easyAI import TwoPlayersGame, id_solve, Human_Player, AI_Player
from easyAI.AI import TT
今、からクラスを継承します TwoPlayerGame ゲームのすべての操作を処理するクラス-
class LastCoin_game(TwoPlayersGame):
def __init__(self, players):
ここで、プレーヤーとゲームを開始するプレーヤーを定義します。
self.players = players
self.nplayer = 1
ここで、ゲーム内のコインの数を定義します。ここでは、ゲームに15枚のコインを使用しています。
self.num_coins = 15
プレイヤーが移動で取ることができるコインの最大数を定義します。
self.max_coins = 4
次のコードに示すように、定義する特定の事項がいくつかあります。可能な動きを定義します。
def possible_moves(self):
return [str(a) for a in range(1, self.max_coins + 1)]
コインの除去を定義します
def make_move(self, move):
self.num_coins -= int(move)
最後のコインを誰が取ったかを定義します。
def win_game(self):
return self.num_coins <= 0
ゲームを停止するタイミング、つまり誰かが勝つタイミングを定義します。
def is_over(self):
return self.win()
スコアの計算方法を定義します。
def score(self):
return 100 if self.win_game() else 0
パイルに残っているコインの数を定義します。
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
次のコードブロックでゲームを解く-
r, d, m = id_solve(LastCoin_game,
range(2, 20), win_score=100, tt=tt)
print(r, d, m)
誰がゲームを開始するかを決める
game = LastCoin_game([AI_Player(tt), Human_Player()])
game.play()
次の出力とこのゲームの簡単なプレイを見つけることができます-
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
三目並べをプレイするボット
Tic-Tac-Toeは非常によく知られており、最も人気のあるゲームの1つです。を使用してこのゲームを作成しましょうeasyAIPythonのライブラリ。次のコードは、このゲームのPythonコードです-
図のようにパッケージをインポートします-
from easyAI import TwoPlayersGame, AI_Player, Negamax
from easyAI.Player import Human_Player
からクラスを継承します TwoPlayerGame ゲームのすべての操作を処理するクラス-
class TicTacToe_game(TwoPlayersGame):
def __init__(self, players):
ここで、プレーヤーとゲームを開始するプレーヤーを定義します-
self.players = players
self.nplayer = 1
ボードのタイプを定義する-
self.board = [0] * 9
今、次のように定義するいくつかの特定のものがあります-
可能な動きを定義する
def possible_moves(self):
return [x + 1 for x, y in enumerate(self.board) if y == 0]
プレイヤーの動きを定義する-
def make_move(self, move):
self.board[int(move) - 1] = self.nplayer
AIを強化するには、プレーヤーがいつ移動するかを定義します-
def umake_move(self, move):
self.board[int(move) - 1] = 0
対戦相手が3列に並んでいるという負け条件を定義します
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])
ゲームの終了のチェックを定義します
def is_over(self):
return (self.possible_moves() == []) or self.condition_for_lose()
ゲーム内のプレーヤーの現在の位置を表示します
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)]))
スコアを計算します。
def scoring(self):
return -100 if self.condition_for_lose() else 0
アルゴリズムを定義してゲームを開始するためのメインメソッドを定義します-
if __name__ == "__main__":
algo = Negamax(7)
TicTacToe_game([Human_Player(), AI_Player(algo)]).play()
次の出力とこのゲームの簡単なプレイを見ることができます-
. . .
. . .
. . .
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 .