easyAI入門
目次
- 1. 概要
- 2. リンク
- 3. easyAIのインストール
- 4. コネクトX(Xは数字)を作って動かしてみる
- 4.1. 以下の操作を行っている動画
- 4.2. コネクト4を作って動かしてみる の手順
- 4.2.1. イメージ起動
- 4.2.2. シェル起動
- 4.2.3. シェルで以下のコマンドを実行
- 4.2.4. easyAIのインストール
- 4.2.5. コネクトX用のディレクトリ掘り、ファイルを作成
- 4.2.6. Connectx.pyファイルを以下の内容で作成
- 4.2.7. ConnectxEasyAI.py ファイルを以下の内容で作成
- 4.2.8. ConnectxEasyAI1.py ファイルを以下の内容で作成
- 4.2.9. ConnectxEasyAI2.py ファイルを以下の内容で作成
- 4.2.10. ConnectxEasyAI3.py ファイルを以下の内容で作成
- 4.2.11. 対AI戦を行ってみる
- 4.2.12. 人対人戦を行ってみる
- 4.2.13. 人対人戦を行ってみる
- 4.3. この章のまとめ
- 5. 今後
- 6. この文書のチェンジログ
1 概要
- Negamax(αβ法の一種 αβ法はMINMAX法(全手検索)と同じ結果を少ない探索で可能なアルゴリズム)のフレームワーク
- Pythonベース
- MITライセンス
2 リンク
- easyAI 公式サイト https://zulko.github.io/easyAI/
- easyAI Github https://github.com/Zulko/easyAI
3 easyAIのインストール
- tensorflow/tensorflowのイメージを拡張その2(GNU GLobal入り)https://www.youtube.com/watch?v=FFWRbgJjekoを利用します。
3.1 以下の操作を行っている動画
3.2 easyAIのインストール 手順
3.2.1 イメージ起動
- tensorflow/tensorflowのイメージを拡張その2(GNU GLobal入り)https://www.youtube.com/watch?v=FFWRbgJjekoを利用します。
- 以下を実行して表示される一番下のhttp://127.0.0.1 …. をコピペしてブラウザで開く
docker run -it --rm -v $(realpath ~/notebooks):/tf/notebooks -p 8888:8888 mytensorflow
3.2.2 シェル起動
- New から terminalを選択して、ターミナル起動
3.2.3 シェルで以下のコマンドを実行
sudo su - user
cd /tf/notebooks/
3.2.4 easyAIのインストール
sudo pip3 install easyAI
3.2.5 easyAIのgithubのダウンロード
mkdir easyAI
cd easyAI
git clone https://github.com/Zulko/easyAI.git
3.2.6 easyAIのサンプルプログラムを動かしてみる
python3 easyAI/games/GameOfBones.py
3.3 この章のまとめ
- easyAIをダウンロードし動かしてみた
4 コネクトX(Xは数字)を作って動かしてみる
- tensorflow/tensorflowのイメージを拡張その2(GNU GLobal入り)https://www.youtube.com/watch?v=FFWRbgJjekoを利用します。
4.1 以下の操作を行っている動画
4.2 コネクト4を作って動かしてみる の手順
4.2.1 イメージ起動
- tensorflow/tensorflowのイメージを拡張その2(GNU GLobal入り)https://www.youtube.com/watch?v=FFWRbgJjekoを利用します。
- 以下を実行して表示される一番下のhttp://127.0.0.1 …. をコピペしてブラウザで開く
docker run -it --rm -v $(realpath ~/notebooks):/tf/notebooks -p 8888:8888 mytensorflow
4.2.2 シェル起動
- New から terminalを選択して、ターミナル起動
4.2.3 シェルで以下のコマンドを実行
sudo su - user
cd /tf/notebooks/
4.2.4 easyAIのインストール
- 起動しなおす毎に消えてるので、再度インストール
sudo pip3 install easyAI
4.2.5 コネクトX用のディレクトリ掘り、ファイルを作成
mkdir -p easyAI/Connectx
cd easyAI/Connectx
4.2.6 Connectx.pyファイルを以下の内容で作成
- ホスト側だとホームディレクトリのnotebooks/easyAI/Connectxディレクトリに以下の内容で作成
- Connect X の処理を行うクラス
- BWIDTHで盤の幅
- BHEIGHTで盤の高さ
- NEEDLENで勝利条件の長さ(4なら4個以上同じ陣営のコマを縦横あるいは斜めに連続で並べたら勝ち)
BWIDTH=7 # board width
BHEIGHT=6 # board height
NEEDLEN=4 # How many must be arranged to win
class Connectx(object):
def __init__(self):
self.color=[[2] * BWIDTH for i in range(BHEIGHT)]
self.v=[" O "," X "," . "]
self.turn=0
self.history=[]
self.isEnd=False
self.winner=2
def clear(self, stone=True):
self.color=[[2] * BWIDTH for i in range(BHEIGHT)]
self.turn=0
self.history.clear()
self.isEnd=False
self.winner=2
def showboard(self):
print(" ",end="")
for x in range(BWIDTH):
print("{0:2d}".format(x),end=" ")
print()
for y in range(BHEIGHT):
print("{0:2d}".format(y)+" | ",end="")
for x in range(BWIDTH):
c=self.color[y][x]
print(self.v[c] ,end="")
print(" | "+"{0:2d}".format(y))
print(" ",end="")
for x in range(BWIDTH):
print("{0:2d}".format(x),end=" ")
print()
print("isEnd : "+str(self.isEnd))
if self.isEnd:
print("game is over winner is "+str(self.winner))
print(self.history)
print()
def legal(self, v):
ans=False
if self.color[0][v]==2:
ans=True
return ans
def isValidXY(self ,xy):
v,y=xy
return (v>=0 and v<BWIDTH and y>=0 and y<BHEIGHT)
def getColor(self,xy):
ans=3
if self.isValidXY(xy):
v,y=xy
ans=self.color[y][v]
return ans
def check(self):
ans=False
for x in range(BWIDTH):
if ans:
break
for y in reversed(range(BHEIGHT)):
if ans:
break
c=self.color[y][x]
if c<2:
#print(">>>***************",end="")
#print((x,y))
if self.bcheck((x,y)):
ans=True
break
return ans
def bcheck(self,xy):
x,y=xy
ans=False
c=self.color[y][x]
if c<2:
for dx in [1,0,-1]:
for dy in [1,0,-1]:
#print("*****(dx,dy)",end=" ")
#print((dx,dy))
if (not (dx==0 and dy==0)) and (not ans):
c1=1
for i in range(1,NEEDLEN):
nx=x+dx*i
ny=y+dy*i
#print("(nx,ny)",end=" ")
#print((nx,ny))
if self.isValidXY((nx,ny)):
nc=self.getColor((nx,ny))
if nc==c:
#print((nx,ny),end=" ")
c1+=1
#print(c1)
if c1>=NEEDLEN:
#print("*** TRUE")
ans=True
break
else:
break
return ans
def getEnableVs(self):
ans=[]
for i in range(BWIDTH):
if self.color[0][i]==2:
ans.append(i)
return ans
def checkEnd(self):
evs=self.getEnableVs()
ans=len(evs)>0 or self.isEnd
if ans:
self.isEnd=True
return ans
def play(self,v):
ans=False
if self.legal(v):
ans=True
for y in reversed(range(BHEIGHT)):
if self.color[y][v]==2:
self.color[y][v]=self.turn
self.history.append([v,y])
#print(self.check())
if not self.isEnd:
if self.check():
self.isEnd=True
self.winner=self.turn
# print("game is over winner is "+str(self.winner))
# print(self.history)
self.turn=int(self.turn==0)
break
return ans
def unmake_move(self, move): # optional method (speeds up the AI)
if len(self.history)>0:
x,y=self.history[-1]
self.color[y][x]=2
#for i in range(BHEIGHT):
# if self.color[y][i]<2:
# self.color[y][i]=2
# break
self.history=self.history[:-1]
self.turn=int(self.turn==0)
self.isEnd=False
self.winner=2
4.2.7 ConnectxEasyAI.py ファイルを以下の内容で作成
- easyAI用
- ホスト側だとホームディレクトリのnotebooks/easyAI/Connectxディレクトリに以下の内容で作成
from easyAI import TwoPlayersGame
from easyAI.Player import Human_Player
from Connectx import *
class ConnectxEasyAI( TwoPlayersGame ):
def __init__(self, players):
self.board=Connectx()
self.players = players
self.nplayer = 1
def possible_moves(self):
return self.board.getEnableVs()
def make_move(self, move):
self.board.play(move)
def unmake_move(self, move): # optional method (speeds up the AI)
self.board.unmake_move(move)
def lose(self):
ans=self.board.check()
enemy=int(self.board.turn==0)
return self.board.winner==enemy
def is_over(self):
self.board.check()
return self.board.isEnd;
def show(self):
self.board.showboard()
def scoring(self):
return -100 if self.lose() else 0
if __name__ == "__main__":
from easyAI import AI_Player, Negamax
ai_algo = Negamax(6)
ConnectxEasyAI( [Human_Player(),AI_Player(ai_algo)]).play()
4.2.8 ConnectxEasyAI1.py ファイルを以下の内容で作成
- 先手人間、後手AI(読み深さ6)戦用
- ホスト側だとホームディレクトリのnotebooks/easyAI/Connectxディレクトリに以下の内容で作成
from easyAI import TwoPlayersGame
from easyAI.Player import Human_Player
from Connectx import *
from ConnectxEasyAI import ConnectxEasyAI
if __name__ == "__main__":
from easyAI import AI_Player, Negamax
ai_algo = Negamax(6)
ConnectxEasyAI( [Human_Player(),AI_Player(ai_algo)]).play()
4.2.9 ConnectxEasyAI2.py ファイルを以下の内容で作成
- 総当りで調べる用(私のマシンで半日動かしたが、8->12手までしか探索できず。時間をかければ先手必勝の結果が得られると思われる)
- ホスト側だとホームディレクトリのnotebooks/easyAI/Connectxディレクトリに以下の内容で作成
from easyAI import TwoPlayersGame
from easyAI.Player import Human_Player
from Connectx import *
from ConnectxEasyAI import ConnectxEasyAI
if __name__ == "__main__":
from easyAI import id_solve, Human_Player, AI_Player
from easyAI.AI import TT
#r, d, m = id_solve(ConnectxEasyAI, range(NEEDLEN*2, BWIDTH*BHEIGHT+1), win_score = 100)
#r, d, m = id_solve(ConnectxEasyAI, range(13, BWIDTH*BHEIGHT+1,2), win_score = 100)
r, d, m = id_solve(ConnectxEasyAI, range(13, BWIDTH*BHEIGHT+1), win_score = 100)
print(r, d, m) # see the docs.
4.2.10 ConnectxEasyAI3.py ファイルを以下の内容で作成
- 対人対人戦用
- ホスト側だとホームディレクトリのnotebooks/easyAI/Connectxディレクトリに以下の内容で作成
from easyAI import TwoPlayersGame
from easyAI.Player import Human_Player
from Connectx import *
from ConnectxEasyAI import ConnectxEasyAI
if __name__ == "__main__":
from easyAI import AI_Player, Negamax
ai_algo = Negamax(6)
#ConnectxEasyAI( [Human_Player(),AI_Player(ai_algo)]).play()
ConnectxEasyAI( [Human_Player(),Human_Player()]).play()
4.2.11 対AI戦を行ってみる
- 以下のコマンドを(docker内)ターミナルで実行
python3 ConnectxEasyAI1.py
4.2.12 人対人戦を行ってみる
- 以下のコマンドを(docker内)ターミナルで実行
python3 ConnectxEasyAI3.py
4.2.13 人対人戦を行ってみる
- 探索を行ってみる(時間かかりすぎるので、最後まで未調査、調査した方いたら結果を教えてもらえると嬉しい)
- 半日やって8から12まで終わり、13手の処理中でした
python3 ConnectxEasyAI2.py
4.3 この章のまとめ
- easyAIをダウンロードし動かしてみた
5 今後
- 今後も文書追加していきます。
6 この文書のチェンジログ
- 2020/04/02 初版
Created: 2020-04-04 土 20:52
