(連続企画)Pythonで将棋ソフト制作その5の補足
↓↓↓ 「十六式いろは初(うい)」 ↓↓↓
ダウンロード「16-168ui.exe」(34MB)
↑ 十六式いろは初(うい)のインストール方法
「16-168ui.exe」を実行して、ファイル群を展開してください。
展開されたフォルダの中にある「readme.txt」をお読みください。 ちなみに将棋所などで登録するエンジンのファイルは
「16-168ui_entry.bat」です。
youtube.com
将棋ソフト作成の連続企画の一つです。
上記の動画で作成したソースコードです。
main.py
import cshogi import random while True: input_cmd = input() # USIプロトコル対応の将棋GUI(将棋所)に # エンジン登録するときに通信する処理。 # # 普通にprintを使うと、改行はしてくれるので # 将棋エンジンを作る場合、問題なし。 # バッファリングさせない(フラッシュさせる)ために # printの引数に「flush=True」を使う。 if input_cmd == "usi": # ソフト名 print("id name 16-168ui", flush=True) # 開発者名 print("id author R.Sueyoshi", flush=True) print("usiok", flush=True) # 対局準備 if input_cmd == "isready": # 設定の読み込みが必要ならここで処理する。 print("readyok", flush=True) # 対局開始の合図 if input_cmd == "usinewgame": pass # 局面の受け取り # 平手はstartpos # 例) # position startpos moves 7g7f 3c3d 2g2f # 最初の8文字を使う。 if input_cmd[0:8] == "position": cmd_lst = list(input_cmd.split(" ")) # スペース区切りのリスト。 # 局面にセットする。 # cmd_lst[-1:][0]は最後の文字列(相手の手等) if cmd_lst[1] == "startpos": # 平手 board = cshogi.Board() # 送られてきた局面まで局面をセットしなおす。 if len(cmd_lst) > 2: for i in range(3, len(cmd_lst)): board.push_usi(cmd_lst[i]) # 指す # print(board) elif cmd_lst[1] == "sfen": # 指定局面 sfen_str = (cmd_lst[2] + " " + cmd_lst[3] + " " + cmd_lst[4] + " " + cmd_lst[5]) board = cshogi.Board(sfen_str) # 送られてきた局面まで局面をセットしなおす。 if len(cmd_lst) > 6: for i in range(7, len(cmd_lst)): board.push_usi(cmd_lst[i]) # 指す # print(board) else: # 想定外の時はエンジンを終了する。 break # 思考開始の合図 # 最初の3文字を使う。 if input_cmd[0:2] == "go": # 自分の次の手を考えさせる。 # board.legal_movesを使うと # 合法手がリストで戻り値として返ってくる。 move_lst = list(board.legal_moves) # 合法手をリスト化する # 王手をかけられたとき # if board.is_check() == True: # print("bestmove resign", flush=True) # 詰みのとき(負け) if len(move_lst) == 0: print("bestmove resign", flush=True) else: # 次の一手を将棋所等の将棋GUIに伝える。 # (廃止→)返事の最初に並んでいる手を指す。 # ランダムな手を指す。 move_num = random.randint(0, len(move_lst) - 1) print("bestmove", cshogi.move_to_usi( move_lst[move_num]), flush=True) # 将棋エンジン内の局面を変更する。 move = board.push(move_lst[move_num]) # 指す # print(board) # 1ゲームが終わった場合 if input_cmd[:8] == "gameover": # コマンド受付を終了する。 break # エンジン停止の合図 if input_cmd == "quit": # コマンド受付を終了する。 break # エンジンを終了させる。 quit()
pythonの将棋ソフト開発ライブラリ:cshogiとpython-shogi
pythonの将棋ソフト開発ライブラリの速度比較
プログラミング言語Pythonを使って、将棋ソフトを開発するときに
便利な上記の2つの将棋ライブラリ(cshogiとpython-shogi)について
処理速度の比較をしてみました( ´∀` )
(というか自分の覚書用w)
元々python-shogiが作られ、
その後、 C++により処理速度を向上させたcshogiが作られました。
環境
- Windows10
- WinPython
WPy64-31040→Pythonで将棋ソフト開発環境パックの公開 - 「十六式いろは」のあれこれ
Winpython32-3.9.4.0dot
Winpython64-3.8.12.2dotPyPy - GitHub - gunyarakun/python-shogi: A pure Python shogi library with move generation and validation and handling of common formats.
- GitHub - TadaoYamaoka/cshogi: 高速なPythonの将棋ライブラリ
方法
平手(ハンデなしの初期配置)で、
合法手(反則にならない次の手)を将棋ライブラリから
呼び出し、その中から一手を選び
(何も考えない手。最善の一手にあらず)
局面を進めます。
途中で次の一手が見つからなくなれば、
初期配置に戻します。
ということを、指定回数繰り返した時の
処理時間を比較してみようかと思いまして。
※選ばれる手が異なるでしょうから、公平に
一手指して戻して一手指すということを
繰り返してみたりもしましたが、
結果はほぼ変わりませんでした(;´Д`)w
ソースコード
- python-shogi用
import shogi import time board = shogi.Board() # 何回繰り返すか。10**2は、10の2乗という意味。 cnt = 10**2 # 計測開始 start_time = time.time() for i in range(cnt): board.legal_moves # 合法手を生成する move_lst = list(board.legal_moves) # 合法手をリスト化する if len(move_lst) == 0: # もし合法手がない場合は、平手に戻す。 board = shogi.Board() continue best_move = str(move_lst[0]) # 次の一手を選ぶ。 board.push_usi(best_move) # 指す print(cnt, time.time() - start_time)
- cshogi用
import cshogi import time board = cshogi.Board() # 何回繰り返すか。10**6は、10の6乗という意味。 cnt = 10**6 # 計測開始 start_time = time.time() for i in range(cnt): board.legal_moves # 合法手を生成する move_lst = list(board.legal_moves) # 合法手をリスト化する if len(move_lst) == 0: # もし合法手がない場合は、平手に戻す。 board = cshogi.Board() continue best_move = cshogi.move_to_usi(move_lst[0]) # 次の一手を選ぶ。 board.push_usi(best_move) # 指す print(cnt, time.time() - start_time)
Google Colaboratory で実行できます。
処理時間は以下の結果と異なりますが(;´Д`)w
colab.research.google.com
結果
というか、繰り返す回数の違いから結果は
わかるようなものですが、とりあえずw
環境 | 繰り返し回数 | 処理時間(秒) |
---|---|---|
python-shogi | 100 | 2.72 |
cshogi | 10の6乗(100万) | 3.16 |
python-shogi(pypy) | 100 | 2.41 |
8600倍!?えっ!?Σ(・□・;)
ちなみに、pypyというのは、ある工夫をしてpythonの
処理速度を爆速にしようぜ、的なものです( ´∀` )
ただ、cshogiとは一緒に使えません( ノД`)しくしく
←cshogiが使うnumpyという行列計算等を扱うライブラリと
非常に相性が悪いので。
結論とまとめ
将棋ソフトの棋力を求めるならcshogiを、
処理速度は気にしないが、勉強のために
ライブラリのソースコードも見たいならpython-shogiを、
という感じですネ( ´∀` )
おまけ
「board.legal_moves # 合法手を生成する」だけの繰り返しなら
pypy&python-shogiが爆速だった、なぜだ!?w
←cshogi呼び出すのに時間かかる等かもですネぇ。
(連続企画)Pythonで将棋ソフト制作その3の補足
上記の動画で作成したソースコードです。
main.py
while True: input_cmd = input() # USIプロトコル対応の将棋GUI(将棋所)に # エンジン登録するときに通信する処理。 # # 普通にprintを使うと、改行はしてくれるので # 将棋エンジンを作る場合、問題なし。 # バッファリングさせない(フラッシュさせる)ために # printの引数に「flush=True」を使う。 if input_cmd == "usi": # ソフト名 print("id name 16-168ui", flush=True) # 開発者名 print("id author R.Sueyoshi", flush=True) print("usiok", flush=True) # 対局準備 if input_cmd == "isready": # 設定の読み込みが必要ならここで処理する。 print("readyok", flush=True) # 対局開始の合図 if input_cmd == "usinewgame": pass # 局面の受け取り # 平手はstartpos # 例) # position startpos moves 7g7f 3c3d 2g2f # 最初の8文字を使う。 if input_cmd[0:8] == "position": position = input_cmd print("position: ", position, flush=True) # 思考開始の合図 # 最初の3文字を使う。 if input_cmd[0:2] == "go": # とりあえず先手の角道を開ける一手を指す。 print("bestmove 7g7f", flush=True) # エンジン停止の合図 if input_cmd == "quit": # コマンド受付を終了する。 break # エンジンを終了させる。 quit()