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