YaneuraOuさんの将棋ライブラリで楽しむ(2020/7バージョン)
目次
- 1. 概要
- 2. リンク
- 3. Ubuntuでコンパイル
- 4. 下準備
- 5. 下準備2
- 6. Positionクラス(盤面クラス)の初期化と表示
- 7. ある盤面で可能な手をすべて表示
- 8. 現状の盤面の評価値表示
- 9. 高速1手詰め探索ルーチン利用
- 10. 詰みチェック
- 11. 指定の一手を行う
- 12. 指定の一手を行った後、その手の取り消し
- 13. Python+cppyyを利用して、PythonからYaneuraouのライブラリの直接利用
- 14. 最新ソースをダウンロード(2020/11/19)して、トーナメント用、詰将棋用のエンジンコンパイル、それらのライブラリコンパイル用のスクリプトについて の章を作成
- 15. Ayaneの利用(PythonからYaneuraOuを利用する別の方法)
- 16. Ayaneの利用2(PythonからYaneuraOuを利用する別の方法)
- 17. python-shogiの基本的な使い方
- 18. USIを直接使って、内容を確認してみよう1(詰将棋エンジンで、指定の盤面を解いてみる)
- 19. USIを直接使って対戦(GUIを使わず直接エンジンと対話)
- 20. 検討の時にどのようなUSIコマンドを使うべきか、将棋エンジンの設定について調べてみた
- 21. 今後
- 22. この文書のチェンジログ
1 概要
- ここ数年YaneuraOuさんの将棋ライブラリを利用した将棋ソフトがコンピューター将棋大会で優勝
- C++とアセンブラベース
- Stockfishというチェスソフトをかなり取り込んだ作りになってるらしい
- GitHubにてソース公開されている
- バージョンによって使い方が相当変化している
- 昔のバージョンに戻せば、過去の動画の使い方も出来る(今は同じ方法で同じように使えない)
- スレッド等他のライブラリとの依存関係があり、使う難易度が高い
- YaneuraOuさんの将棋ソフトのUbuntuへのインストール(2020/7 バージョン) という別文書とリンク部分とインストール部分はほぼ同じ
2 リンク
- GitHub https://github.com/yaneurao/YaneuraOu
- 公式サイト?ブログ? http://yaneuraou.yaneu.com/
- リリース(評価関数も含まれているもの) https://github.com/yaneurao/YaneuraOu/releases
- V4.91(2020/07/07時点で最新) https://github.com/yaneurao/YaneuraOu/releases/download/V4.91/YaneuraOu2019V491all.zip
- 定跡 https://github.com/yaneurao/YaneuraOu/blob/master/docs/news.md
- テラショック定跡 user_book1.db https://github.com/yaneurao/YaneuraOu/releases/download/BOOK-700T-Shock/700T-shock-book.zip
- やねうら王 定跡ファイル詰め合わせ https://github.com/yaneurao/YaneuraOu/releases/tag/v4.73_book
- NNUE-K-P-256-32-32用評価関数バイナリその2 小さい評価関数 https://github.com/yaneurao/YaneuraOu/releases/tag/20190212_k-p-256-32-32 https://github.com/yaneurao/YaneuraOu/releases/download/20190212_k-p-256-32-32/20190212_k-p-256-32-32.zip
- 評価関数
- YaneuraOuさん WCS29優勝の評価関数公開されていない?不明?有料化?
- Kristallweizen WCSC29準優勝https://github.com/Tama4649/Kristallweizen
- https://www.qhapaq.org/shogi/kifdb/
- (最新版)評価関数 orqha1018 レーティング約4390の評価関数 https://www.qhapaq.org/static/media/bin/orqha1018.7z
- 評価関数 orqha レーティング約4330の評価関数 https://www.qhapaq.org/static/media/bin/orqha.7z
- (最新版)評価関数 shinderella レーティング約4260の振り飛車を指す評価関数 https://www.qhapaq.org/static/media/bin/shinderella-0815.7z
- レーティング約4260の振り飛車を指す評価関数です https://www.qhapaq.org/static/media/bin/shinderella-0825.7z
- Aprey https://hiraokatakuya.github.io/apery/
- Aprey GitHub https://github.com/HiraokaTakuya/apery
- AperyのWCSC26のファイル(評価関数含む これがそのままYaneuraOuで使えると記述あり)https://github.com/HiraokaTakuya/apery/releases/tag/WCSC26
- AperyのWCSC28のファイル(評価関数含む こちらは使えるか不明) https://github.com/HiraokaTakuya/apery/releases/tag/WCSC28
- Elmo((2019は4位, 2020/5 3位だけど、2020/5バージョンは右のURLでまだ入手不可能みたい 2017優勝) https://mk-takizawa.github.io/elmo/howtouse_elmo.html
- elmo_wcsc29_eval.zip(2019は4位) https://drive.google.com/open?id=1Q66LqVx4bCCOkHbMyWbIrCnQbmk2gNEF
- YaneuraOuさん https://github.com/yaneurao/YaneuraOu/releases
- ゼロベース評価関数
- NNUE-K-P-256-32-32用評価関数バイナリその2 https://github.com/yaneurao/YaneuraOu/releases/tag/20190212_k-p-256-32-32
- 過去のプロジェクト https://github.com/yaneurao/YaneuraOu/blob/master/docs/README2017.md
- リゼロ評価関数 epoch 8 (elmo(WCSC27)にまだR50ぐらい負けているようです。) https://drive.google.com/file/d/0Bzbi5rbfN85NMHd0OEUxcUVJQW8/view
- ゼロベース評価関数
- 評価関数+改造
- 水匠2(2020/5優勝 「すいしょう」と読むらしい) https://twitter.com/tayayan_ts
- 探索部カスタマイズある?
- ここからだとログイン無しでダウンロード出来るみたい https://migigyoku.com/?p=3132
- https://twitter.com/_illqha
- https://twitter.com/tayayan_ts
- 水匠2(2020/5優勝 「すいしょう」と読むらしい) https://twitter.com/tayayan_ts
- GUI
- パッケージ化されているもの
- xboard, uci2wb
- tagua shogivar (まだ試してない)
- MyShogi https://github.com/yaneurao/MyShogi
- 将棋所 http://shogidokoro.starfree.jp/download.html
- パッケージ化されているもの
- Python
3 Ubuntuでコンパイル
3.1 以下の操作を行っている動画
3.2 easyAIのインストール 手順
3.3 手順
3.3.1 依存パッケージのインストール
- 色々あると思う、私は色々入れていたので、私の環境の場合以下を入れる必要があった
sudo apt install libomp-dev libopenblas-dev
3.3.2 ソースゲット
git clone https://github.com/yaneurao/YaneuraOu.git
3.3.3 ソースバックアップ
tar cvzf YaneuraOu.org.tgz YaneuraOu
3.3.4 コンパイル(トーナメントタイプの場合)
- CPUがSSE42タイプの場合(私のマシンのCPUはタイプが古くAVX2タイプをサポートしていないため)
- AVX2タイプのCPU命令可能な場合はSSE42の部分をAVX2にすればOK
- SSE42もダメな場合はNO_SSEや、OTHER、ZEN2というCPUタイプも選択可能
- UbuntuなどLinuxの場合は/proc/cpuinfoで利用可能かどうか確認可能 ( grep -i sse4 /proc/cpuinfo, grep -i avx2 /proc/cpuinfo 等)
cd YaneuraOu/source make clean tournament TARGET_CPU=SSE42
- これでコンパイルが実行され、YaneuraOu-by-gcc っていう実行可能なファイルが生成される(必要なライブラリやツールがインストールされていた場合、不足している場合はエラーメッセージから必要なパッケージをインストールしていく)
- 取得してソースバックアップし、コンパイル後にコンパイル後のファイルも保存するスクリプトが以下
#!/bin/bash #TARGET_CPU=AVX512 #TARGET_CPU=AVX2 TARGET_CPU=SSE42 #TARGET_CPU=SSE41 #TARGET_CPU=SSE2 #TARGET_CPU=NO_SSE #TARGET_CPU=OTHER #TARGET_CPU=ZEN2 D=`date +%Y%m%d` DT=`date +%Y%m%d_%H%M` mkdir ${DT} cd ${DT} git clone https://github.com/yaneurao/YaneuraOu.git tar cvzf YaneuraOu_${DT}.tgz YaneuraOu/ (cd YaneuraOu/source && make clean tournament TARGET_CPU=${TARGET_CPU}) 2>&1 | tee ./log001.txt tar cvzf YaneuraOu_${DT}_build.tgz YaneuraOu/ ( mkdir LEARN cd LEARN tar xvzf ../YaneuraOu_${DT}.tgz (cd YaneuraOu/source && make clean evallearn TARGET_CPU=${TARGET_CPU}) 2>&1 | tee ./log002.txt )
3.3.5 コンパイル(学習タイプの場合、評価関数ファイルを生成できるタイプ)
- CPUがSSE42タイプの場合(私のマシンのCPUはタイプが古くAVX2タイプをサポートしていないため)
- AVX2タイプのCPU命令可能な場合はSSE42の部分をAVX2にすればOK
- SSE42もダメな場合はNO_SSEや、OTHER、ZEN2というCPUタイプも選択可能
- UbuntuなどLinuxの場合は/proc/cpuinfoで利用可能かどうか確認可能 ( grep -i sse4 /proc/cpuinfo, grep -i avx2 /proc/cpuinfo 等)
make clean evallearn TARGET_CPU=SSE42
- 同じく YaneuraOu-by-gcc というファイルが生成される
- コンパイルする前にLEARNディレクトリにソースを解凍してそこで行った
mkdir LEARN cd LEARN tar xvzf ../YaneuraOu.org.tgz cd YaneuraOu/source
3.4 ゼロの評価関数ファイルの生成
3.4.1 以下の操作を行っている動画
3.4.2 手順
- 学習タイプの YaneuraOu-by-gcc の起動
./YaneuraOu-by-gcc
- YaneuraOu/docs/解説.txt にある文書の手順で行う
EvalDir xyz // 存在しないフォルダを評価関数の読み込みフォルダに指定する SkipLoadingEval true // こうしておけば評価関数ファイルの読み込みに失敗してもエラーにならない isready // このタイミングで評価関数が読み込まれるが存在しないフォルダから読み込むのでゼロクリアされた評価関数を読み込んだことになる。 EvalSaveDir eval_zero // 保存フォルダ名を"eval_zero"に設定(何でも良い) test evalsave // メモリ上の評価関数を保存するコマンド
- これにより eval_zero/nn.bin に評価関数ファイル nn.binが生成される
- nn.binを競技用YaneuraOu-by-gccのあるディレクトリのevalの中に入れる
cp -i eval_zero/nn.bin ../../../YaneuraOu/source/eval/
3.5 動作確認
- 以下のコマンドで起動
./YaneuraOu-by-gcc
- usiコマンドをいれて動作確認(usi,d等)
usi isready d
- quitで停止
quit
4 下準備
4.1 以下の操作を行っている動画
4.2 Makefileの修正
- YaneuraOu/sourceディレクトリで以下の作業を行う
4.2.1 Makefile の バックアップ
cp Makefile Makefile.org
4.2.2 myMain.cpp の 作成
cp main.cpp myMain.cpp
4.3 Makefileの修正
4.3.1 Makefile 修正内容
- CPUタイプの修正、(各自該当のCPUに変更、私のPCのCPUはSSE42タイプ)
- デバッグ機能をオン, デバッグ情報追加
- libYaneuraOu-by-gcc.so という動的ライブラリファイル作成、動的ライブラリにするため、コンパイル時に -fPICオプション追加
- 独自のmain関数用のmyMain.cppを追加し、これをメイン関数とした myMainを作成、myMainを更新成功したら、myMainを実行
4.3.2 Makefileを修正し、以下のコマンドで、patchファイルを作成した
diff -c Makefile.org Makefile > Makefile.diff
- CPU SSE42タイプの場合のMakefileが以下
# ビルドターゲット # normal : 通常使用用 # evallearn : 教師局面からの学習用 # tournament : 大会で使う用 # gensfen : 教師生成用(現状、非公開) # やねうら王の使いたいエディションを指定する # YANEURAOU_ENGINE_NNUE : NNUE型評価関数(halfKP256),標準NNUE型 # YANEURAOU_ENGINE_NNUE_KP256 : NNUE型評価関数(KP256) # YANEURAOU_ENGINE_KPPT : KPPT型評価関数 # YANEURAOU_ENGINE_KPP_KKPT : KPP_KKPT型評価関数 # YANEURAOU_ENGINE_MATERIAL : 駒得のみの評価関数 # MATE_ENGINE : tanuki- 詰将棋エンジン # USER_ENGINE : USER定義エンジン YANEURAOU_EDITION = YANEURAOU_ENGINE_NNUE #YANEURAOU_EDITION = YANEURAOU_ENGINE_NNUE_KP256 #YANEURAOU_EDITION = YANEURAOU_ENGINE_KPPT #YANEURAOU_EDITION = YANEURAOU_ENGINE_KPP_KKPT #YANEURAOU_EDITION = YANEURAOU_ENGINE_MATERIAL #YANEURAOU_EDITION = MATE_ENGINE #YANEURAOU_EDITION = USER_ENGINE # ターゲットCPU # 利用できるCPU拡張命令を指定する。 # ARM系ならOTHERを指定する。 # 32bit環境用はNO_SSE # AMDのZen2はZEN2を選択すると良いかも?(clang9以降で対応) #TARGET_CPU = AVX512 #TARGET_CPU = AVX2 TARGET_CPU = SSE42 #TARGET_CPU = SSE41 #TARGET_CPU = SSE2 #TARGET_CPU = NO_SSE #TARGET_CPU = OTHER #TARGET_CPU = ZEN2 # デバッガーを使用するか #DEBUG = OFF DEBUG = ON # clangでコンパイルしたほうがgccより数%速いっぽい。 #COMPILER = g++ COMPILER = clang++ # 標準的なコンパイルオプション CFLAGS = -std=c++17 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fpermissive WCFLAGS = LDFLAGS = LIBS = INCLUDE = # -I../include # デバッガーを使わないなら、NDEBUGをdefineする。 ifeq ($(DEBUG),OFF) CFLAGS += -DNDEBUG endif # clang用にCFLAGSなどを変更 ifeq ($(findstring clang++,$(COMPILER)),clang++) # stdlib CFLAGS += -stdlib=libstdc++ # C++17のfilesystem # LDFLAGS += -lstdc++fs # 関数の引数が関数本体で使われていないときに警告出るのうざすぎるので抑制。 CFLAGS += -Wno-unused-parameter # static リンクを行う際に __cxa_guard_acquire __cxa_guard_release の生成を抑止 # undefined reference to `__imp___cxa_guard_acquire' # undefined reference to `__imp___cxa_guard_release' # static 変数を初期化したかを pthread_mutex_t でロックを取って確認し、 # 最初の実行なら初期化するスレッドセーフなコードを生成するためのもの。 # → 本当に消してしまっても大丈夫か? WCFLAGS += -fno-threadsafe-statics else ifeq ($(findstring g++,$(COMPILER)),g++) # mingw g++ で AVX512 向けビルドを行おうとするとエラーになる問題の回避 # https://stackoverflow.com/questions/43152633/invalid-register-for-seh-savexmm-in-cygwin # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65782 WCFLAGS += -fno-asynchronous-unwind-tables # C++17のfilesystem # LDFLAGS += -lstdc++fs endif endif ifeq ($(OS),Windows_NT) CFLAGS += $(WCFLAGS) LDFLAGS += -static -Wl,--stack,25000000 TARGET = YaneuraOu-by-gcc.exe else CFLAGS += -D_LINUX TARGET = YaneuraOu-by-gcc endif # リンク時最適化。 # CFLAGSとLDFLAGSの両方で-fltoを指定する必要がある。 # cf. https://gcc.gnu.org/onlinedocs/gcc-6.3.0/gcc/Optimize-Options.html#Optimize-Options LTOFLAGS = -flto # wstringを使うためにこのシンボル定義が必要。 CFLAGS += -DUNICODE # stripの指示。(実行ファイルのサイズを小さく) LDFLAGS += -Wl,-s # mingw64では-D_WIN64,-D_WIN32は環境に応じて自動で設定されるので指定すべきではない。 # CFLAGS += -D_WIN64 # これを指定していると、各CPU向けの実行ファイルが生成されないので指定すべきではない。 # CFLAGS += -march=native # デバッグ情報を付加 CFLAGS += -g3 -ggdb CFLAGS += -fPIC # OpenMPを使うときにCFLAGSとして指定するオプション # ※ 学習部ではOpenMpを用いるので、学習用のビルドではこのオプションを指定する。 # clangでOPENMPを有効にしてビルドする方法については、解説.txtを参照のこと。 # エンジンの表示名("usi"コマンドに対して出力される) #ENGINE_NAME = # 開発中のbranchならdevと指定する #ENGINE_BRANCH = dev ifeq ($(findstring g++,$(COMPILER)),g++) OPENMP = -fopenmp OPENMP_LDFLAGS = endif ifeq ($(findstring clang++,$(COMPILER)),clang++) ifeq ($(MSYSTEM),MINGW64) # MSYS2 MINGW64 env # libgompを指定した場合、ビルドは通るがOpenMPは無効化される? OPENMP = -fopenmp=libgomp OPENMP_LDFLAGS = else ifeq ($(findstring w64-mingw32,$(COMPILER)),w64-mingw32) # Ubuntu mingw-w64 clang++ env (experimental) OPENMP = -fopenmp=libgomp OPENMP_LDFLAGS = else # Other (normal clang++/libomp env) OPENMP = -fopenmp OPENMP_LDFLAGS = -lomp endif endif endif # NNUE評価関数 学習バイナリ用 OpenBLAS ifeq ($(findstring YANEURAOU_ENGINE_NNUE,$(YANEURAOU_EDITION)),YANEURAOU_ENGINE_NNUE) BLAS = -DUSE_BLAS BLAS_LDFLAGS = -lopenblas ifeq ($(MSYSTEM),MINGW64) BLAS += -I$(shell cygpath -aw /mingw64/include/OpenBLAS) endif endif CFLAGS += -DNO_EXCEPTIONS LDFLAGS += -lpthread LDFLAGS += -v OBJDIR = ../obj ifeq "$(strip $(OBJDIR))" "" OBJDIR = .. endif #SOURCES = $(wildcard *.cpp) SOURCES = \ main.cpp \ types.cpp \ bitboard.cpp \ misc.cpp \ movegen.cpp \ position.cpp \ usi.cpp \ usi_option.cpp \ thread.cpp \ tt.cpp \ movepick.cpp \ timeman.cpp \ benchmark.cpp \ extra/book/apery_book.cpp \ extra/book/book.cpp \ extra/book/makebook2019.cpp \ extra/bitop.cpp \ extra/long_effect.cpp \ extra/mate/mate1ply_with_effect.cpp \ extra/mate/mate1ply_without_effect.cpp \ extra/mate/mate_n_ply.cpp \ extra/test_cmd.cpp \ extra/sfen_packer.cpp \ extra/kif_converter/kif_convert_tools.cpp \ eval/evaluate_bona_piece.cpp \ eval/evaluate.cpp \ eval/evaluate_io.cpp \ eval/evaluate_mir_inv_tools.cpp \ learn/learner.cpp \ learn/learning_tools.cpp \ learn/multi_think.cpp ifeq ($(YANEURAOU_EDITION),YANEURAOU_ENGINE_KPPT) SOURCES += \ eval/kppt/evaluate_kppt.cpp \ eval/kppt/evaluate_kppt_learner.cpp \ engine/yaneuraou-engine/yaneuraou-search.cpp endif ifeq ($(YANEURAOU_EDITION),YANEURAOU_ENGINE_KPP_KKPT) SOURCES += \ eval/kppt/evaluate_kppt.cpp \ eval/kpp_kkpt/evaluate_kpp_kkpt.cpp \ eval/kpp_kkpt/evaluate_kpp_kkpt_learner.cpp \ engine/yaneuraou-engine/yaneuraou-search.cpp endif ifeq ($(YANEURAOU_EDITION),YANEURAOU_ENGINE_MATERIAL) SOURCES += \ engine/yaneuraou-engine/yaneuraou-search.cpp endif ifeq ($(findstring YANEURAOU_ENGINE_NNUE,$(YANEURAOU_EDITION)),YANEURAOU_ENGINE_NNUE) ifeq ($(YANEURAOU_EDITION),YANEURAOU_ENGINE_NNUE) else CFLAGS += -DYANEURAOU_ENGINE_NNUE endif ifeq ($(YANEURAOU_EDITION),YANEURAOU_ENGINE_NNUE_KP256) CFLAGS += -DEVAL_NNUE_KP256 else ifeq ($(NNUE_EVAL_ARCH),KP256) CFLAGS += -DEVAL_NNUE_KP256 endif endif SOURCES += \ eval/nnue/evaluate_nnue.cpp \ eval/nnue/evaluate_nnue_learner.cpp \ eval/nnue/nnue_test_command.cpp \ eval/nnue/features/k.cpp \ eval/nnue/features/p.cpp \ eval/nnue/features/half_kp.cpp \ eval/nnue/features/half_relative_kp.cpp \ engine/yaneuraou-engine/yaneuraou-search.cpp endif ifeq ($(YANEURAOU_EDITION),MATE_ENGINE) SOURCES += engine/mate-engine/mate-search.cpp endif ifeq ($(YANEURAOU_EDITION),USER_ENGINE) SOURCES += engine/user-engine/user-search.cpp endif ifneq ($(ENGINE_NAME),) CFLAGS += -DENGINE_NAME_FROM_MAKEFILE=$(ENGINE_NAME) endif # 開発用branch ifeq ($(findstring dev,$(ENGINE_BRANCH)),dev) # SuperSort使ってみよう。 SOURCES += extra/super_sort.cpp endif # CPU判別 # AMDなど特定のCPU ifeq ($(TARGET_CPU),ZEN2) CFLAGS += -DUSE_AVX2 -mbmi -mbmi2 -mavx2 -march=znver2 # それ以外は、AVX512,AVX2,SSE4.2,SSE4.1,SSE2のように利用できるCPU拡張命令で振り分ける。 else ifeq ($(TARGET_CPU),AVX512) # skylake : -DUSE_AVX512 -DUSE_AVX512VLBWDQ -march=skylake-avx512 # cascadelake : -DUSE_AVX512 -DUSE_AVX512VLBWDQ -DUSE_AVX512VNNI -march=cascadelake # icelake : -DUSE_AVX512 -DUSE_AVX512VLBWDQ -DUSE_AVX512VNNI -DUSE_AVX512VBMI -DUSE_AVX512IFMA -USE_GFNI -march=icelake-client CFLAGS += -DUSE_AVX512 -DUSE_AVX512VLBWDQ -march=skylake-avx512 else ifeq ($(TARGET_CPU),AVX2) CFLAGS += -DUSE_AVX2 -mbmi -mbmi2 -mavx2 -march=corei7-avx else ifeq ($(TARGET_CPU),SSE42) CFLAGS += -DUSE_SSE42 -msse4.2 -march=corei7 else ifeq ($(TARGET_CPU),SSE41) CFLAGS += -DUSE_SSE41 -msse4.1 -march=core2 else ifeq ($(TARGET_CPU),SSE2) CFLAGS += -DUSE_SSE2 -msse2 -march=core2 else ifeq ($(TARGET_CPU),NO_SSE) # 32bit用。-m32は、MSYS2 MinGW-64だと無視されるので、 # MinGW-64の32bit環境用でコンパイルする必要がある。 CFLAGS += -DNO_SSE -m32 -march=pentium3 else ifeq ($(TARGET_CPU),OTHER) CFLAGS += -DNO_SSE endif CFLAGS += -DUSE_MAKEFILE -D$(YANEURAOU_EDITION) OBJECTS = $(addprefix $(OBJDIR)/, $(SOURCES:.cpp=.o)) DEPENDS = $(OBJECTS:.o=.d) $(TARGET): $(OBJECTS) $(LIBS) $(COMPILER) -o $@ $^ $(LDFLAGS) $(CFLAGS) myMain.o : myMain.cpp $(COMPILER) $(CFLAGS) $(INCLUDE) -o $@ -c $< myMain : myMain.o $(OBJECTS) $(LIBS) lib$(TARGET).so $(COMPILER) -o $@ myMain.o lib$(TARGET).so $(LDFLAGS) $(CFLAGS) && LD_LIBRARY_PATH=. ./$@ lib$(TARGET).so: $(OBJECTS) $(LIBS) $(COMPILER) -shared -o $@ $^ $(LDFLAGS) $(CFLAGS) $(OBJDIR)/%.o: %.cpp @[ -d $(dir $@) ] || mkdir -p $(dir $@) $(COMPILER) $(CFLAGS) $(INCLUDE) -o $@ -c $< all: clean $(TARGET) # https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html # ビルドターゲット # 通常使用。 normal: $(MAKE) CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS) $(LTOFLAGS)' $(TARGET) # 学習用。openmp , openblasなどを有効にする。 evallearn: $(MAKE) CFLAGS='$(CFLAGS) $(OPENMP) $(BLAS)' LDFLAGS='$(LDFLAGS) $(OPENMP_LDFLAGS) $(BLAS_LDFLAGS) $(LTOFLAGS)' $(TARGET) # トーナメント用 tournament: $(MAKE) CFLAGS='$(CFLAGS) -DFOR_TOURNAMENT' LDFLAGS='$(LDFLAGS) $(LTOFLAGS)' $(TARGET) # トーナメント用lib tournamentlib: $(MAKE) CFLAGS='$(CFLAGS) -DFOR_TOURNAMENT' LDFLAGS='$(LDFLAGS) $(LTOFLAGS)' lib$(TARGET).so # 教師棋譜生成用 gensfen: $(MAKE) CFLAGS='$(CFLAGS) $(OPENMP) $(BLAS) -DGENSFEN2019' LDFLAGS='$(LDFLAGS) $(OPENMP_LDFLAGS) $(BLAS_LDFLAGS) $(LTOFLAGS)' $(TARGET) # とりあえずPGOはAVX2とSSE4.2専用 prof: $(MAKE) CFLAGS='$(CFLAGS) -pg' tournament profgen: $(MAKE) CFLAGS='$(CFLAGS) -fprofile-generate -lgcov' LDFLAGS='$(LDFLAGS) -fprofile-generate -lgcov' profuse: $(MAKE) CFLAGS='$(CFLAGS) -fprofile-use -lgcov' LDFLAGS='$(LDFLAGS) -fprofile-use -lgcov $(LTOFLAGS)' pgo: $(MAKE) profgen @./$(TARGET) EvalDir ../build/eval , bench , quit @touch $(SOURCES) $(MAKE) profuse clean: rm -f $(OBJECTS) $(DEPENDS) $(TARGET) ${OBJECTS:.o=.gcda} -include $(DEPENDS)
4.4 libYaneuraOu-by-gcc.soの作成
- -fPIC オプションをつけてコンパイルしなおさないといけないから、以下で一旦コンパイルしたものを消して再度コンパイルしなおす
make clean tournamentlib
- ソースを消してやるのが上のコマンドだけど、変更してないのをコンパイルしなおさないのは以下
make tournamentlib
4.5 myMain を作成(myMain.cppをmain関数とした実行ファイルの作成)
- myMainのコンパイルに成功したら、実行される
make myMain
- 単体で実行するには以下(libYaneuraOu-by-gcc.soをカレントディレクトリに探しにいくように、LD_LIBRARY_PATHの設定が必要になる)
LD_LIBRARY_PATH=. ./myMain
4.6 この章のまとめ
- 動的ライブラリの作成
- 昔の動画では、コンパイルコマンドを自作してたけど、今回はMakefileの改造で対応
5 下準備2
5.1 以下の操作を行っている動画
5.2 myMain.cpp の修正
- USIのループに行かないようにする
- 評価関数の読み込み処理部分をusi.cppからもってくる(これを行わないと、セグメンテーションエラーになるようになったようだ、数年前はこれなしでいけてた)
//#include <iostream> //#include "bitboard.h" //#include "position.h" #include "search.h" #include "thread.h" #include "tt.h" #include "usi.h" #include "misc.h" // ---------------------------------------- // main() // ---------------------------------------- int main(int argc, char* argv[]) { // --- 全体的な初期化 Misc::init(argv); USI::init(Options); Bitboards::init(); Position::init(); Search::init(); Threads.set(Options["Threads"]); //Search::clear(); Eval::init(); // USIコマンドの応答部 //USI::loop(argc, argv); // ************* 評価関数の読み込み Eval::load_eval(); // チェックサムの計算と保存(その後のメモリ破損のチェックのため) u64 eval_sum; eval_sum = Eval::calc_check_sum(); // ソフト名の表示 Eval::print_softname(eval_sum); USI::load_eval_finished = true; // ************* 評価関数の読み込み // 生成して、待機させていたスレッドの停止 Threads.set(0); return 0; }
5.3 コンパイル実行
make myMain
5.4 この章のまとめ
- 数年前にアップしてた動画の方法で、現在はダメ
- 最新のソースで上手く行く方法の一つを紹介
6 Positionクラス(盤面クラス)の初期化と表示
6.1 以下の操作を行っている動画
6.2 myMain.cpp の修正
- Posionオブジェクトと、必要なオブジェクト生成
- 平手の盤面設定コード追加
- 以下の2つの方法ある。どちらでもOK(posはPosionクラスのオブジェクトがはいっている変数)
pos.set_hirate(&states->back(),Threads.main());
pos.set(SFEN_HIRATE,&states->back(),Threads.main());
- 平手にしたPosionオブジェクトの表示
//#include <iostream> //#include "bitboard.h" //#include "position.h" #include "search.h" #include "thread.h" #include "tt.h" #include "usi.h" #include "misc.h" #include "types.h" #include "usi.h" #include "position.h" #include "search.h" #include "thread.h" #include "tt.h" #include <sstream> #include <queue> using namespace std; // ---------------------------------------- // main() // ---------------------------------------- int main(int argc, char* argv[]) { // --- 全体的な初期化 Misc::init(argv); USI::init(Options); Bitboards::init(); Position::init(); Search::init(); Threads.set(Options["Threads"]); //Search::clear(); Eval::init(); // USIコマンドの応答部 //USI::loop(argc, argv); // ************* 評価関数の読み込み Eval::load_eval(); // チェックサムの計算と保存(その後のメモリ破損のチェックのため) u64 eval_sum; eval_sum = Eval::calc_check_sum(); // ソフト名の表示 Eval::print_softname(eval_sum); USI::load_eval_finished = true; // ************* 評価関数の読み込み Position pos; StateListPtr states = StateListPtr(new StateList(1)); // pos.set_hirate(&states->back(),Threads.main()); pos.set(SFEN_HIRATE,&states->back(),Threads.main()); cout << pos << endl; // 生成して、待機させていたスレッドの停止 Threads.set(0); return 0; }
6.3 コンパイル実行
make myMain
6.4 この章のまとめ
- Postionオブジェクトの生成、盤面設定、表示
- 評価関数を読み込んでからじゃないと、セグメンテーションエラーとなる
7 ある盤面で可能な手をすべて表示
7.1 以下の操作を行っている動画
7.2 myMain.cpp の修正
//#include <iostream> //#include "bitboard.h" //#include "position.h" #include "search.h" #include "thread.h" #include "tt.h" #include "usi.h" #include "misc.h" #include "types.h" #include "usi.h" #include "position.h" #include "search.h" #include "thread.h" #include "tt.h" #include <sstream> #include <queue> using namespace std; // ---------------------------------------- // main() // ---------------------------------------- int main(int argc, char* argv[]) { // --- 全体的な初期化 Misc::init(argv); USI::init(Options); Bitboards::init(); Position::init(); Search::init(); Threads.set(Options["Threads"]); //Search::clear(); Eval::init(); // USIコマンドの応答部 //USI::loop(argc, argv); // ************* 評価関数の読み込み Eval::load_eval(); // チェックサムの計算と保存(その後のメモリ破損のチェックのため) u64 eval_sum; eval_sum = Eval::calc_check_sum(); // ソフト名の表示 Eval::print_softname(eval_sum); USI::load_eval_finished = true; // ************* 評価関数の読み込み Position pos; StateListPtr states = StateListPtr(new StateList(1)); // pos.set_hirate(&states->back(),Threads.main()); pos.set(SFEN_HIRATE,&states->back(),Threads.main()); cout << pos << endl; //可能な手を全て表示 MoveList< LEGAL_ALL > ml(pos); cout << "ml.size()=" << ml.size() << endl; for(auto m : ml) { //cout << m.move << endl; cout << m << endl; } // 生成して、待機させていたスレッドの停止 Threads.set(0); return 0; }
7.3 コンパイル実行
make myMain
7.4 この章のまとめ
- ある盤面で可能な手をすべて表示
8 現状の盤面の評価値表示
8.1 以下の操作を行っている動画
8.2 myMain.cpp の修正
//#include <iostream> //#include "bitboard.h" //#include "position.h" #include "search.h" #include "thread.h" #include "tt.h" #include "usi.h" #include "misc.h" #include "types.h" #include "usi.h" #include "position.h" #include "search.h" #include "thread.h" #include "tt.h" #include <sstream> #include <queue> using namespace std; // ---------------------------------------- // main() // ---------------------------------------- int main(int argc, char* argv[]) { // --- 全体的な初期化 Misc::init(argv); USI::init(Options); Bitboards::init(); Position::init(); Search::init(); Threads.set(Options["Threads"]); //Search::clear(); Eval::init(); // USIコマンドの応答部 //USI::loop(argc, argv); // ************* 評価関数の読み込み Eval::load_eval(); // チェックサムの計算と保存(その後のメモリ破損のチェックのため) u64 eval_sum; eval_sum = Eval::calc_check_sum(); // ソフト名の表示 Eval::print_softname(eval_sum); USI::load_eval_finished = true; // ************* 評価関数の読み込み Position pos; StateListPtr states = StateListPtr(new StateList(1)); // pos.set_hirate(&states->back(),Threads.main()); pos.set(SFEN_HIRATE,&states->back(),Threads.main()); cout << pos << endl; //可能な手を全て表示 MoveList< LEGAL_ALL > ml(pos); cout << "ml.size()=" << ml.size() << endl; for(auto m : ml) { //cout << m.move << endl; cout << m << endl; } //現状の盤面の評価値を表示 cout << "eval=" << Eval::compute_eval(pos) << endl; Eval::print_eval_stat(pos); // 生成して、待機させていたスレッドの停止 Threads.set(0); return 0; }
8.3 コンパイル実行
make myMain
8.4 この章のまとめ
- 現状の盤面の評価値表示
9 高速1手詰め探索ルーチン利用
9.1 以下の操作を行っている動画
9.2 myMain.cpp の修正
//#include <iostream> //#include "bitboard.h" //#include "position.h" #include "search.h" #include "thread.h" #include "tt.h" #include "usi.h" #include "misc.h" #include "types.h" #include "usi.h" #include "position.h" #include "search.h" #include "thread.h" #include "tt.h" #include <sstream> #include <queue> using namespace std; // ---------------------------------------- // main() // ---------------------------------------- int main(int argc, char* argv[]) { // --- 全体的な初期化 Misc::init(argv); USI::init(Options); Bitboards::init(); Position::init(); Search::init(); Threads.set(Options["Threads"]); //Search::clear(); Eval::init(); // USIコマンドの応答部 //USI::loop(argc, argv); // ************* 評価関数の読み込み Eval::load_eval(); // チェックサムの計算と保存(その後のメモリ破損のチェックのため) u64 eval_sum; eval_sum = Eval::calc_check_sum(); // ソフト名の表示 Eval::print_softname(eval_sum); USI::load_eval_finished = true; // ************* 評価関数の読み込み Position pos; StateListPtr states = StateListPtr(new StateList(1)); // pos.set_hirate(&states->back(),Threads.main()); pos.set(SFEN_HIRATE,&states->back(),Threads.main()); cout << pos << endl; cout << "pos.mate1ply()=" << pos.mate1ply() << endl; //可能な手を全て表示 MoveList< LEGAL_ALL > ml(pos); cout << "ml.size()=" << ml.size() << endl; for(auto m : ml) { //cout << m.move << endl; cout << m << endl; } //現状の盤面の評価値を表示 cout << "eval=" << Eval::compute_eval(pos) << endl; Eval::print_eval_stat(pos); //世界一早い1手づめチェックルーチン // lnsgkgsnl/1r5b1/pppp+P1ppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGS1L[N] w 0 1 pos.set("lnsgkgsnl/1r5b1/pppp+P1ppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGS1L b N 1",&states->back(),Threads.main()); cout << pos << endl; cout << "pos.mate1ply()=" << pos.mate1ply() << endl; // 生成して、待機させていたスレッドの停止 Threads.set(0); return 0; }
9.3 コンパイル実行
make myMain
9.4 この章のまとめ
- 高速1手詰め探索ルーチン利用
10 詰みチェック
10.1 以下の操作を行っている動画
10.2 myMain.cpp の修正
- Positionオブジェクトのis_mated() メソッドで行える
//#include <iostream> //#include "bitboard.h" //#include "position.h" #include "search.h" #include "thread.h" #include "tt.h" #include "usi.h" #include "misc.h" #include "types.h" #include "usi.h" #include "position.h" #include "search.h" #include "thread.h" #include "tt.h" #include <sstream> #include <queue> using namespace std; // ---------------------------------------- // main() // ---------------------------------------- int main(int argc, char* argv[]) { // --- 全体的な初期化 Misc::init(argv); USI::init(Options); Bitboards::init(); Position::init(); Search::init(); Threads.set(Options["Threads"]); //Search::clear(); Eval::init(); // USIコマンドの応答部 //USI::loop(argc, argv); // ************* 評価関数の読み込み Eval::load_eval(); // チェックサムの計算と保存(その後のメモリ破損のチェックのため) u64 eval_sum; eval_sum = Eval::calc_check_sum(); // ソフト名の表示 Eval::print_softname(eval_sum); USI::load_eval_finished = true; // ************* 評価関数の読み込み Position pos; StateListPtr states = StateListPtr(new StateList(1)); // pos.set_hirate(&states->back(),Threads.main()); pos.set(SFEN_HIRATE,&states->back(),Threads.main()); cout << pos << endl; // 高速一手詰みチェックルーチン cout << "pos.mate1ply()=" << pos.mate1ply() << endl; // 詰みか表示 cout << "pos.is_mated()=" << pos.is_mated() << endl; //可能な手を全て表示 MoveList< LEGAL_ALL > ml(pos); cout << "ml.size()=" << ml.size() << endl; for(auto m : ml) { //cout << m.move << endl; cout << m << endl; } //現状の盤面の評価値を表示 cout << "eval=" << Eval::compute_eval(pos) << endl; Eval::print_eval_stat(pos); //世界一早い1手づめチェックルーチン // lnsgkgsnl/1r5b1/pppp+P1ppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGS1L[N] w 0 1 pos.set("lnsgkgsnl/1r5b1/pppp+P1ppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGS1L b N 1",&states->back(),Threads.main()); cout << pos << endl; // 高速一手詰みチェックルーチン cout << "pos.mate1ply()=" << pos.mate1ply() << endl; // 詰みか表示 cout << "pos.is_mated()=" << pos.is_mated() << endl; // 生成して、待機させていたスレッドの停止 Threads.set(0); return 0; }
10.3 コンパイル実行
make myMain
10.4 この章のまとめ
- 詰みチェック
11 指定の一手を行う
11.1 以下の操作を行っている動画
11.2 myMain.cpp の修正
- Positionオブジェクトのdo_move() メソッドで行える
//#include <iostream> //#include "bitboard.h" //#include "position.h" #include "search.h" #include "thread.h" #include "tt.h" #include "usi.h" #include "misc.h" #include "types.h" #include "usi.h" #include "position.h" #include "search.h" #include "thread.h" #include "tt.h" #include <sstream> #include <queue> using namespace std; // ---------------------------------------- // main() // ---------------------------------------- int main(int argc, char* argv[]) { // --- 全体的な初期化 Misc::init(argv); USI::init(Options); Bitboards::init(); Position::init(); Search::init(); Threads.set(Options["Threads"]); //Search::clear(); Eval::init(); // USIコマンドの応答部 //USI::loop(argc, argv); // ************* 評価関数の読み込み Eval::load_eval(); // チェックサムの計算と保存(その後のメモリ破損のチェックのため) u64 eval_sum; eval_sum = Eval::calc_check_sum(); // ソフト名の表示 Eval::print_softname(eval_sum); USI::load_eval_finished = true; // ************* 評価関数の読み込み Position pos; StateListPtr states = StateListPtr(new StateList(1)); // pos.set_hirate(&states->back(),Threads.main()); pos.set(SFEN_HIRATE,&states->back(),Threads.main()); cout << pos << endl; // 高速一手詰みチェックルーチン cout << "pos.mate1ply()=" << pos.mate1ply() << endl; // 詰みか表示 cout << "pos.is_mated()=" << pos.is_mated() << endl; //可能な手を全て表示 MoveList< LEGAL_ALL > ml(pos); cout << "ml.size()=" << ml.size() << endl; for(auto m : ml) { //cout << m.move << endl; cout << m << endl; } //現状の盤面の評価値を表示 cout << "eval=" << Eval::compute_eval(pos) << endl; Eval::print_eval_stat(pos); //世界一早い1手づめチェックルーチン // lnsgkgsnl/1r5b1/pppp+P1ppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGS1L[N] w 0 1 pos.set("lnsgkgsnl/1r5b1/pppp+P1ppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGS1L b N 1",&states->back(),Threads.main()); cout << pos << endl; //可能な手を全て表示 (LEGAL_ALL ではなく、 LEGALタイプ) MoveList< LEGAL > ml2(pos); cout << "ml.size()=" << ml2.size() << endl; for(auto m : ml2) { //cout << m.move << endl; cout << m << endl; } // 高速一手詰みチェックルーチン cout << "pos.mate1ply()=" << pos.mate1ply() << endl; // 詰みか表示 cout << "pos.is_mated()=" << pos.is_mated() << endl; Move m=pos.mate1ply(); // 上位bitに駒種を入れておかないとpseudo_legal()で引っかかる。 //これやっとなかないと、MoveList<LEGAL>(pos).contains(m) で正しいのがかえってこない m = pos.move16_to_move(m); cout << "m=" << m << endl; cout << "MoveList<LEGAL>(pos).contains(m)=" << MoveList<LEGAL>(pos).contains(m) << endl; if (MoveList<LEGAL>(pos).contains(m)) { // 1手進めるごとにStateInfoが積まれていく。これは千日手の検出のために必要。 states->emplace_back(); if (m == MOVE_NULL) // do_move に MOVE_NULL を与えると死ぬので { cout << "MOVE_NULL " << m << endl; pos.do_null_move(states->back()); } else { cout << "not MOVE_NULL " << m << endl; pos.do_move(m, states->back()); } cout << pos << endl; cout << "pos.is_mated()=" << pos.is_mated() << endl; } Move mymove = USI::to_move("7f7g"); cout << mymove << endl; // 生成して、待機させていたスレッドの停止 Threads.set(0); return 0; } /* // 指し手のリストをパースする(あるなら) while (is >> token && (m = USI::to_move(pos, token)) != MOVE_NONE) { // 1手進めるごとにStateInfoが積まれていく。これは千日手の検出のために必要。 states->emplace_back(); if (m == MOVE_NULL) // do_move に MOVE_NULL を与えると死ぬので pos.do_null_move(states->back()); else pos.do_move(m, states->back()); } Move USI::to_move(const Position& pos, const std::string& str) { // 全合法手のなかからusi文字列に変換したときにstrと一致する指し手を探してそれを返す //for (const ExtMove& ms : MoveList<LEGAL_ALL>(pos)) // if (str == move_to_usi(ms.move)) // return ms.move; // ↑のコードは大変美しいコードではあるが、棋譜を大量に読み込むときに時間がかかるうるのでもっと高速な実装をする。 if (str == "resign") return MOVE_RESIGN; if (str == "win") return MOVE_WIN; // パス(null move)入力への対応 {UCI: "0000", GPSfish: "pass"} if (str == "0000" || str == "null" || str == "pass") return MOVE_NULL; // usi文字列を高速にmoveに変換するやつがいるがな.. Move move = USI::to_move(str); // 上位bitに駒種を入れておかないとpseudo_legal()で引っかかる。 move = pos.move16_to_move(move); #if defined(MUST_CAPTURE_SHOGI_ENGINE) // 取る一手将棋は合法手かどうかをGUI側でチェックしてくれないから、 // 合法手かどうかのチェックを入れる。 if (!MoveList<LEGAL>(pos).contains(move)) sync_cout << "info string Error!! Illegal Move = " << move << sync_endl; #endif if (pos.pseudo_legal(move) && pos.legal(move)) return move; // いかなる状況であろうとこのような指し手はエラー表示をして弾いていいと思うが…。 // cout << "\nIlligal Move : " << str << "\n"; return MOVE_NONE; } */
11.3 コンパイル実行
make myMain
11.4 この章のまとめ
- 指定の一手を行う
12 指定の一手を行った後、その手の取り消し
12.1 以下の操作を行っている動画
12.2 myMain.cpp の修正
- Positionオブジェクトのundo_move() メソッドで行える
//#include <iostream> //#include "bitboard.h" //#include "position.h" #include "search.h" #include "thread.h" #include "tt.h" #include "usi.h" #include "misc.h" #include "types.h" #include "usi.h" #include "position.h" #include "search.h" #include "thread.h" #include "tt.h" #include <sstream> #include <queue> using namespace std; // ---------------------------------------- // main() // ---------------------------------------- int main(int argc, char* argv[]) { // --- 全体的な初期化 Misc::init(argv); USI::init(Options); Bitboards::init(); Position::init(); Search::init(); Threads.set(Options["Threads"]); //Search::clear(); Eval::init(); // USIコマンドの応答部 //USI::loop(argc, argv); // ************* 評価関数の読み込み Eval::load_eval(); // チェックサムの計算と保存(その後のメモリ破損のチェックのため) u64 eval_sum; eval_sum = Eval::calc_check_sum(); // ソフト名の表示 Eval::print_softname(eval_sum); USI::load_eval_finished = true; // ************* 評価関数の読み込み Position pos; StateListPtr states = StateListPtr(new StateList(1)); // pos.set_hirate(&states->back(),Threads.main()); pos.set(SFEN_HIRATE,&states->back(),Threads.main()); cout << pos << endl; // 高速一手詰みチェックルーチン cout << "pos.mate1ply()=" << pos.mate1ply() << endl; // 詰みか表示 cout << "pos.is_mated()=" << pos.is_mated() << endl; //可能な手を全て表示 MoveList< LEGAL_ALL > ml(pos); cout << "ml.size()=" << ml.size() << endl; for(auto m : ml) { //cout << m.move << endl; cout << m << endl; } //現状の盤面の評価値を表示 cout << "eval=" << Eval::compute_eval(pos) << endl; Eval::print_eval_stat(pos); //世界一早い1手づめチェックルーチン // lnsgkgsnl/1r5b1/pppp+P1ppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGS1L[N] w 0 1 pos.set("lnsgkgsnl/1r5b1/pppp+P1ppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGS1L b N 1",&states->back(),Threads.main()); cout << pos << endl; //可能な手を全て表示 (LEGAL_ALL ではなく、 LEGALタイプ) MoveList< LEGAL > ml2(pos); cout << "ml.size()=" << ml2.size() << endl; for(auto m : ml2) { //cout << m.move << endl; cout << m << endl; } // 高速一手詰みチェックルーチン cout << "pos.mate1ply()=" << pos.mate1ply() << endl; // 詰みか表示 cout << "pos.is_mated()=" << pos.is_mated() << endl; Move m=pos.mate1ply(); // 上位bitに駒種を入れておかないとpseudo_legal()で引っかかる。 //これやっとなかないと、MoveList<LEGAL>(pos).contains(m) で正しいのがかえってこない m = pos.move16_to_move(m); cout << "m=" << m << endl; cout << "MoveList<LEGAL>(pos).contains(m)=" << MoveList<LEGAL>(pos).contains(m) << endl; if (MoveList<LEGAL>(pos).contains(m)) { // 1手進めるごとにStateInfoが積まれていく。これは千日手の検出のために必要。 states->emplace_back(); if (m == MOVE_NULL) // do_move に MOVE_NULL を与えると死ぬので { cout << "MOVE_NULL " << m << endl; pos.do_null_move(states->back()); } else { cout << "not MOVE_NULL " << m << endl; pos.do_move(m, states->back()); } cout << pos << endl; cout << "pos.is_mated()=" << pos.is_mated() << endl; // cout << "pos.lastMove=" << pos.lastMove << endl; // ERROR // undo_move してみる pos.undo_move(m); cout << pos << endl; cout << "pos.is_mated()=" << pos.is_mated() << endl; } Move mymove = USI::to_move("7f7g"); cout << mymove << endl; // 生成して、待機させていたスレッドの停止 Threads.set(0); return 0; } /* // 指し手のリストをパースする(あるなら) while (is >> token && (m = USI::to_move(pos, token)) != MOVE_NONE) { // 1手進めるごとにStateInfoが積まれていく。これは千日手の検出のために必要。 states->emplace_back(); if (m == MOVE_NULL) // do_move に MOVE_NULL を与えると死ぬので pos.do_null_move(states->back()); else pos.do_move(m, states->back()); } Move USI::to_move(const Position& pos, const std::string& str) { // 全合法手のなかからusi文字列に変換したときにstrと一致する指し手を探してそれを返す //for (const ExtMove& ms : MoveList<LEGAL_ALL>(pos)) // if (str == move_to_usi(ms.move)) // return ms.move; // ↑のコードは大変美しいコードではあるが、棋譜を大量に読み込むときに時間がかかるうるのでもっと高速な実装をする。 if (str == "resign") return MOVE_RESIGN; if (str == "win") return MOVE_WIN; // パス(null move)入力への対応 {UCI: "0000", GPSfish: "pass"} if (str == "0000" || str == "null" || str == "pass") return MOVE_NULL; // usi文字列を高速にmoveに変換するやつがいるがな.. Move move = USI::to_move(str); // 上位bitに駒種を入れておかないとpseudo_legal()で引っかかる。 move = pos.move16_to_move(move); #if defined(MUST_CAPTURE_SHOGI_ENGINE) // 取る一手将棋は合法手かどうかをGUI側でチェックしてくれないから、 // 合法手かどうかのチェックを入れる。 if (!MoveList<LEGAL>(pos).contains(move)) sync_cout << "info string Error!! Illegal Move = " << move << sync_endl; #endif if (pos.pseudo_legal(move) && pos.legal(move)) return move; // いかなる状況であろうとこのような指し手はエラー表示をして弾いていいと思うが…。 // cout << "\nIlligal Move : " << str << "\n"; return MOVE_NONE; } */
12.3 コンパイル実行
make myMain
12.4 この章のまとめ
- 指定の一手を行った後、その手の取り消し
13 Python+cppyyを利用して、PythonからYaneuraouのライブラリの直接利用
- CERNのROOTをいれて数ヶ月前にトライしたが、ヘッダーファイルにC++の新しい規格が使われていて、ROOTでサポートされておらずエラー多発。ソース変更が面倒なので放置
- PythonにcppyyというCERNのROOTの技術を利用したC++やCの外部ライブラリを利用できるパッケージがあることを知り、試してみたら上手くいった。
- CERNのROOTで何故上手くいかず、こちらで上手くいったのか、原因は調べてない。(よくわかんない)
- 関連動画
- cppyyの概要説明 https://youtu.be/700Tf0H4C5g
- cppyyの簡単な使い方説明 https://youtu.be/-R9sY4c78vI
- cppyyで外部ライブラリの利用方法の説明 https://youtu.be/uFHLfleIwS4
13.1 以下の操作を行っている動画
13.2 実際の手順
- 以下のソースを実行すると、盤面を平手に設定して、盤面が表示される
- 平手の設定をPython側から行おうとしたが、書き方がわからず、cppyy.cppdefを利用して実現した(書き方わかる方はコメント欄で教えてください)
- 失敗した命令はコメントアウトして残してあります。
import cppyy from array import array cppyy.include("search.h") cppyy.include("thread.h") cppyy.include("tt.h") cppyy.include("usi.h") cppyy.include("misc.h") cppyy.include("iostream") cppyy.load_library("./libYaneuraOu-by-gcc.so") cppyy.cppdef('char* argv[]={{}};') cppyy.cppdef('unsigned long tmp01=Options["Threads"];') cppyy.gbl.Misc.init(cppyy.gbl.argv) cppyy.gbl.USI.init(cppyy.gbl.Options) cppyy.gbl.Bitboards.init() cppyy.gbl.Position.init() cppyy.gbl.Search.init(); cppyy.gbl.Threads.set(4) cppyy.gbl.Eval.init() cppyy.gbl.Eval.load_eval(); cppyy.cppdef('StateListPtr create_states() { return StateListPtr(new StateList(1));};') cppyy.cppdef('void setMyPosition(Position& pos, std::string sfen, StateListPtr states) { pos.set(sfen,&states->back(),Threads.main()); }; ') cppyy.cppdef('void myPrintPosition(Position& pos) { std::cout << pos << std::endl; };') pos=cppyy.gbl.Position() states=cppyy.gbl.create_states() print("cppyy.gbl.Threads.size()") print(cppyy.gbl.Threads.size()) print(pos.sfen()) cppyy.gbl.setMyPosition(pos,cppyy.gbl.SFEN_HIRATE,states) #pos.set(cppyy.gbl.SFEN_HIRATE,cppyy.addressof(states.back()),cppyy.gbl.Threads.main()) #ERR #pos.set(cppyy.gbl.SFEN_HIRATE,states.back(),cppyy.gbl.Threads.main()) #Error cppyy.gbl.myPrintPosition(pos)
13.3 この章のまとめ
- Python+cppyyを利用することで、インタプリタ環境から、Yaneuraouさんの将棋ライブラリを利用することが可能になった
- 何故かCERNのROOTでも数ヶ月前に試したがダメだった
- ヘッダーの読み込みで新しいC++の規格が利用できないというエラーが発生
- 修正が面倒で放置
- 何の修正もなく利用可能に
- 試行錯誤が非常にやりやすくなった
- 一部cppyyで書き方がわからないものは、cppyy.cppdefで定義した関数を利用して、動作できるものを作成した
- cppyy.cppdefを利用せずとも、平手に設定出来る方法わかるかたはコメントして教えて下さい
- 何故かCERNのROOTでも数ヶ月前に試したがダメだった
14 最新ソースをダウンロード(2020/11/19)して、トーナメント用、詰将棋用のエンジンコンパイル、それらのライブラリコンパイル用のスクリプトについて の章を作成
- 2020/07頃の動画や、文書(上の方の章)での手順では、現在(2020/11/19)では上手くいかなくなっていた(ライブラリのコンパイル)
- 関連動画
14.2 以下の操作を行っている動画
14.3 2020/11/19で、最新のYaneuraOuさんの将棋エンジン、詰将棋エンジン、tanukiさんの詰将棋エンジン、それらのライブラリ作成するスクリプトについて
14.3.1 ソースダウンロードして、コンパイルするスクリプトファイルの作成
- get というファイルを以下の内容で作成
- CPUがSSSE42以外を希望する場合は、以下のどれか希望の物にSSR42という文字列を全部置き換える(文字列置換を一括で行えるエディタを利用すると便利)
- AVX512VNNI
- AVX512
- AVX2
- SSE42
- SSE41
- SSSE3
- SSE2
- NO_SSE
- OTHER
- ZEN1
- ZEN2
- 使えるCPUの確認は、 cat /proc/cpuinfo | grep -i sse や cat /proc/cpuinfo | grep -i avx 等で確認可能(Ubuntu等、Linuxマシンの場合)
- 使えるCPUの種類の確認方法の解説動画は[[]]等があります(Ubuntuで行った動画,他のLinuxでも同じ手順で多分いける)
#!/bin/bash D=`date +%Y%m%d` DT=`date +%Y%m%d_%H%M` mkdir ${DT} cd ${DT} git clone https://github.com/yaneurao/YaneuraOu.git #tar cvzf YaneuraOu_${DT}_000.tgz YaneuraOu/ #(cd YaneuraOu/ ;git checkout 9bbd0f38498b22e9f3e6cf9493a7f8849c02e496) tar cvzf YaneuraOu_${DT}.tgz YaneuraOu/ git clone https://github.com/nodchip/tanuki-.git #tar cvzf tanuki-_${DT}_000.tgz tanuki- #(cd tanuki-/ ;git checkout 258d55331385a9e594ed8e624409ea3bfdd53602) tar cvzf tanuki-_${DT}.tgz tanuki- (cd YaneuraOu/source && make clean tournament TARGET_CPU=SSE42) 2>&1 | tee ./log001.txt tar cvzf YaneuraOu_${DT}_build.tgz YaneuraOu/ ( mkdir MATE2LIB cd MATE2LIB tar xvzf ../tanuki-_${DT}.tgz (cd tanuki-/source && patch -p2 < ../../../../06makefile_DEBUG_lib_tanuki.patch && make clean tournamentlib TARGET_CPU=SSE42 YANEURAOU_EDITION=MATE_ENGINE ) 2>&1 | tee ./log010.txt ) ( mkdir MATELIB cd MATELIB tar xvzf ../YaneuraOu_${DT}.tgz (cd YaneuraOu/source && patch -p2 < ../../../../06makefile_DEBUG_lib.patch && make clean tournamentlib TARGET_CPU=SSE42 YANEURAOU_EDITION=MATE_ENGINE ) 2>&1 | tee ./log010.txt ) # cp main.cpp myMain.cpp # make myMain TARGET_CPU=SSE42 YANEURAOU_EDITION=MATE_ENGINE # LD_LIBRARY_PATH=. ./myMain ( mkdir MATE2 cd MATE2 tar xvzf ../tanuki-_${DT}.tgz (cd tanuki-/source/ && make clean tournament TARGET_CPU=SSE42 YANEURAOU_EDITION=MATE_ENGINE ) 2>&1 | tee ./log004.txt ) ( mkdir LEARN cd LEARN tar xvzf ../YaneuraOu_${DT}.tgz (cd YaneuraOu/source && make clean evallearn TARGET_CPU=SSE42) 2>&1 | tee ./log002.txt ) ( mkdir MATE cd MATE tar xvzf ../YaneuraOu_${DT}.tgz (cd YaneuraOu/source && make clean tournament TARGET_CPU=SSE42 YANEURAOU_EDITION=MATE_ENGINE ) 2>&1 | tee ./log003.txt ) ( mkdir TOURNAMENTLIB cd TOURNAMENTLIB tar xvzf ../YaneuraOu_${DT}.tgz (cd YaneuraOu/source && patch -p2 < ../../../../06makefile_DEBUG_lib.patch && make clean tournamentlib TARGET_CPU=SSE42 ) 2>&1 | tee ./log011.txt ) # cp main.cpp myMain.cpp # make myMain TARGET_CPU=SSE42 # LD_LIBRARY_PATH=. ./myMain
14.3.2 作ったスクリプトに実行権限を与える
chmod +x get
14.3.3 上のスクリプトで利用するバッチファイルの生成
- 06makefile_DEBUG_lib.patch
- 以下のテキストはbase64でエンコードしてあるので、デコードして 06makefile_DEBUG_lib.patch というファイル名で保存
LS0tIFlhbmV1cmFPdS5vcmcvc291cmNlL01ha2VmaWxlCTIwMjAtMTEtMTkgMDg6MzY6MzUuMDAw MDAwMDAwICswOTAwCisrKyBZYW5ldXJhT3Uvc291cmNlL01ha2VmaWxlCTIwMjAtMTEtMTkgMDg6 NDc6NDcuMzkyOTU1OTMyICswOTAwCkBAIC01Niw4ICs1Niw4IEBAIFRBUkdFVF9DUFUgPSBBVlgy CiAKIAogIyDjg4fjg5Djg4Pjgqzjg7zjgpLkvb/nlKjjgZnjgovjgYsgKGRlYnVnZ2VyKQotREVC VUcgPSBPRkYKLSNERUJVRyA9IE9OCisjIERFQlVHID0gT0ZGCitERUJVRyA9IE9OCiAKIAogIyDk vb/nlKjjgZnjgovjgrPjg7Pjg5HjgqTjg6kgKGNvbXBpbGVyKQpAQCAtMTUzLDcgKzE1Myw4IEBA IExERkxBR1MgKz0gLVdsLC1zCiAjIENQUEZMQUdTICAgKz0gLW1hcmNoPW5hdGl2ZQogCiAjIOOD h+ODkOODg+OCsOaDheWgseOCkuS7mOWKoAotIyBDUFBGTEFHUyAgKz0gLWczIC1nZ2RiCitDUFBG TEFHUyAgKz0gLWczIC1nZ2RiCitDUFBGTEFHUyAgKz0gLWZQSUMKIAogIyBPcGVuTVDjgpLkvb/j gYbjgajjgY3jgatDUFBGTEFHU+OBqOOBl+OBpuaMh+WumuOBmeOCi+OCquODl+OCt+ODp+ODswog IyDigLsg5a2m57+S6YOo44Gn44GvT3Blbk1w44KS55So44GE44KL44Gu44Gn44CB5a2m57+S55So 44Gu44OT44Or44OJ44Gn44Gv44GT44Gu44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44CC CkBAIC0yMDIsOCArMjAzLDkgQEAgaWZlcSAiJChzdHJpcCAkKE9CSkRJUikpIiAiIgogZW5kaWYK IAogI1NPVVJDRVMgID0gJCh3aWxkY2FyZCAqLmNwcCkKKyMJbWFpbi5jcHAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAor IwogU09VUkNFUyAgPSBcCi0JbWFpbi5jcHAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogCXR5cGVzLmNwcCAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IFwKIAliaXRib2FyZC5jcHAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICBcCiAJbWlzYy5jcHAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXApAQCAtMzg4LDYg KzM5MCwxNSBAQCBhbGw6IGNsZWFuICQoVEFSR0VUKQogJChUQVJHRVQpOiAkKE9CSkVDVFMpICQo TElCUykKIAkkKENPTVBJTEVSKSAtbyAkQCAkXiAkKExERkxBR1MpICQoQ1BQRkxBR1MpCiAKK215 TWFpbi5vIDogbXlNYWluLmNwcAorCSQoQ09NUElMRVIpICQoQ1BQRkxBR1MpICQoSU5DTFVERSkg LW8gJEAgLWMgJDwKKworbXlNYWluIDogbXlNYWluLm8gJChMSUJTKSBsaWIkKFRBUkdFVCkuc28K KwkkKENPTVBJTEVSKSAtbyAkQCBteU1haW4ubyBsaWIkKFRBUkdFVCkuc28gJChMREZMQUdTKSAk KENQUEZMQUdTKQorCitsaWIkKFRBUkdFVCkuc286ICQoT0JKRUNUUykgJChMSUJTKQorCSQoQ09N UElMRVIpIC1zaGFyZWQgLW8gJEAgJF4gJChMREZMQUdTKSAkKENQUEZMQUdTKQorCiAkKE9CSkRJ UikvJS5vOiAlLmNwcAogCUBbIC1kICQoZGlyICRAKSBdIHx8IG1rZGlyIC1wICQoZGlyICRAKQog CSQoQ09NUElMRVIpICQoQ1BQRkxBR1MpICQoSU5DTFVERSkgLW8gJEAgLWMgJDwKQEAgLTQwOSw2 ICs0MjAsMTAgQEAgZXZhbGxlYXJuOgogdG91cm5hbWVudDoKIAkkKE1BS0UpIENQUEZMQUdTPSck KENQUEZMQUdTKSAtREZPUl9UT1VSTkFNRU5UJyBMREZMQUdTPSckKExERkxBR1MpICQoTFRPRkxB R1MpJyAkKFRBUkdFVCkKIAorIyDjg4jjg7zjg4rjg6Hjg7Pjg4jnlKhsaWIKK3RvdXJuYW1lbnRs aWI6CisJJChNQUtFKSBDUFBGTEFHUz0nJChDUFBGTEFHUykgLURGT1JfVE9VUk5BTUVOVCcgTERG TEFHUz0nJChMREZMQUdTKSAkKExUT0ZMQUdTKScgbGliJChUQVJHRVQpLnNvCisKICMg5pWZ5bir 5qOL6K2c55Sf5oiQ55SoKOmWi+eZuueUqOOBquOBruOBp+mdnuWFrOmWiykgLy8gY3VycmVudGx5 IHByaXZhdGUKIGdlbnNmZW46CiAJJChNQUtFKSBDUFBGTEFHUz0nJChDUFBGTEFHUykgJChPUEVO TVApICQoQkxBUykgLURFVkFMX0xFQVJOIC1ER0VOU0ZFTjIwMTknIExERkxBR1M9JyQoTERGTEFH UykgJChPUEVOTVBfTERGTEFHUykgJChCTEFTX0xERkxBR1MpICQoTFRPRkxBR1MpJyAkKFRBUkdF VCkK
- 上の内容を 06makefile_DEBUG_lib.patch.base64というファイルに保存して、それをデコードする場合は以下のコマンドでデコード可能
cat 06makefile_DEBUG_lib.patch.base64 | base64 -d > 06makefile_DEBUG_lib.patch
- 06makefile_DEBUG_lib_tanuki.patch
- 以下のテキストはbase64でエンコードしてあるので、デコードして 06makefile_DEBUG_lib_tanuki.patch というファイル名で保存
- tanukiのMakefileが現在のYanauraOuさんの最新のMakefileと異る為、別ファイルを作成する必要がありました。tanukiのMakefileがYaneuraOuさんの最新Makefileに追いついたら、 06makefile_DEBUG_lib_tanuki.patchは前の 06makefile_DEBUG_lib.patch と同じ内容でいけるはず
LS0tIHRhbnVraS0ub3JnL3NvdXJjZS9NYWtlZmlsZQkyMDIwLTExLTE5IDA5OjQwOjQxLjU5NzM5 Njg0OSArMDkwMAorKysgdGFudWtpLS9zb3VyY2UvTWFrZWZpbGUJMjAyMC0xMS0xOSAwOTo0Njow Ny4yNTE4OTU5NzcgKzA5MDAKQEAgLTQxLDggKzQxLDggQEAgVEFSR0VUX0NQVSA9IEFWWDIKIAog CiAjIOODh+ODkOODg+OCrOODvOOCkuS9v+eUqOOBmeOCi+OBiwotREVCVUcgPSBPRkYKLSNERUJV RyA9IE9OCisjREVCVUcgPSBPRkYKK0RFQlVHID0gT04KIAogCiAjIGNsYW5n44Gn44Kz44Oz44OR 44Kk44Or44GX44Gf44G744GG44GMZ2Nj44KI44KK5pWwJemAn+OBhOOBo+OBveOBhOOAggpAQCAt MTIyLDYgKzEyMiw5IEBAIExERkxBR1MgKz0gLVdsLC1zCiAKICMg44OH44OQ44OD44Kw5oOF5aCx 44KS5LuY5YqgCiAjIENGTEFHUyAgKz0gLWczIC1nZ2RiCitDRkxBR1MgICs9IC1nMyAtZ2dkYgor Q0ZMQUdTICArPSAtZlBJQworCiAKICMgT3Blbk1Q44KS5L2/44GG44Go44GN44GrQ0ZMQUdT44Go 44GX44Gm5oyH5a6a44GZ44KL44Kq44OX44K344On44OzCiAjIOKAuyDlrabnv5Lpg6jjgafjga9P cGVuTXDjgpLnlKjjgYTjgovjga7jgafjgIHlrabnv5LnlKjjga7jg5Pjg6vjg4njgafjga/jgZPj ga7jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgIIKQEAgLTE3NSw4ICsxNzgsOSBAQCBp ZmVxICIkKHN0cmlwICQoT0JKRElSKSkiICIiCiBlbmRpZgogCiAjU09VUkNFUyAgPSAkKHdpbGRj YXJkICouY3BwKQorIwltYWluLmNwcCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisjCiBTT1VSQ0VTICA9IFwKLQltYWlu LmNwcCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICBcCiAJdHlwZXMuY3BwICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogCWJpdGJvYXJkLmNwcCAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IFwKIAltaXNjLmNwcCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICBcCkBAIC0zMTYsNiArMzIwLDE4IEBAIERFUEVORFMgID0g JChPQkpFQ1RTOi5vPS5kKQogJChUQVJHRVQpOiAkKE9CSkVDVFMpICQoTElCUykKIAkkKENPTVBJ TEVSKSAtbyAkQCAkXiAkKExERkxBR1MpICQoQ0ZMQUdTKQogCitsaWIkKFRBUkdFVCkuc286ICQo T0JKRUNUUykgJChMSUJTKQorCSQoQ09NUElMRVIpIC1zaGFyZWQgLW8gJEAgJF4gJChMREZMQUdT KSAkKENGTEFHUykKKworbXlNYWluLm8gOiBteU1haW4uY3BwCisJJChDT01QSUxFUikgJChDRkxB R1MpICQoSU5DTFVERSkgLW8gJEAgLWMgJDwKKworbXlNYWluIDogbXlNYWluLm8gJChMSUJTKSBs aWIkKFRBUkdFVCkuc28KKwkkKENPTVBJTEVSKSAtbyAkQCBteU1haW4ubyBsaWIkKFRBUkdFVCku c28gJChMREZMQUdTKSAkKENGTEFHUykKKworbGliJChUQVJHRVQpLnNvOiAkKE9CSkVDVFMpICQo TElCUykKKwkkKENPTVBJTEVSKSAtc2hhcmVkIC1vICRAICReICQoTERGTEFHUykgJChDRkxBR1Mp CisKICQoT0JKRElSKS8lLm86ICUuY3BwCiAJQFsgLWQgJChkaXIgJEApIF0gfHwgbWtkaXIgLXAg JChkaXIgJEApCiAJJChDT01QSUxFUikgJChDRkxBR1MpICQoSU5DTFVERSkgLW8gJEAgLWMgJDwK QEAgLTMzOSw2ICszNTUsMTAgQEAgZXZhbGxlYXJuOgogdG91cm5hbWVudDoKIAkkKE1BS0UpIENG TEFHUz0nJChDRkxBR1MpIC1ERk9SX1RPVVJOQU1FTlQnIExERkxBR1M9JyQoTERGTEFHUykgJChM VE9GTEFHUyknICQoVEFSR0VUKQogCisjIOODiOODvOODiuODoeODs+ODiOeUqGxpYgordG91cm5h bWVudGxpYjoKKwkkKE1BS0UpIENGTEFHUz0nJChDRkxBR1MpIC1ERk9SX1RPVVJOQU1FTlQnIExE RkxBR1M9JyQoTERGTEFHUykgJChMVE9GTEFHUyknIGxpYiQoVEFSR0VUKS5zbworCiAjIOaVmeW4 q+aji+itnOeUn+aIkOeUqAogZ2Vuc2ZlbjoKIAkkKE1BS0UpIENGTEFHUz0nJChDRkxBR1MpICQo T1BFTk1QKSAkKEJMQVMpIC1ER0VOU0ZFTjIwMTknIExERkxBR1M9JyQoTERGTEFHUykgJChPUEVO TVBfTERGTEFHUykgJChCTEFTX0xERkxBR1MpICQoTFRPRkxBR1MpJyAkKFRBUkdFVCkK
- 上の内容を 06makefile_DEBUG_lib_tanuki.patch.base64というファイルに保存して、それをデコードする場合は以下のコマンドでデコード可能
cat 06makefile_DEBUG_lib_tanuki.patch.base64 | base64 -d > 06makefile_DEBUG_lib_tanuki.patch
14.3.4 作ったスクリプトを実行
- 以下のコマンドでソースゲット、色々コンパイルしてくれる
- 変化が激しい為、今後修正しないと動かなくなる可能性あり
- 動作確認した時のgitのバージョンは YaneuraOuが 9bbd0f38498b22e9f3e6cf9493a7f8849c02e496
- Mon Nov 16 03:16:47 2020 +0900
- 動作確認した時のgitのバージョンは tanuki が 258d55331385a9e594ed8e624409ea3bfdd53602
- Tue May 5 00:32:13 2020 +0900
- 動作確認した時のgitのバージョンは YaneuraOuが 9bbd0f38498b22e9f3e6cf9493a7f8849c02e496
- コンパイル出来ない時は、git checkout xxxx (xxxはバージョン)として、過去のソースにすることで、コンパイル可能に
- get の以下の行のコメントを外すと(先頭の#をはずず)、指定のバージョンのソースでコンパイル
- #tar cvzf YaneuraOu_${DT}_000.tgz YaneuraOu/
- #(cd YaneuraOu/ ;git checkout 9bbd0f38498b22e9f3e6cf9493a7f8849c02e496)
- #tar cvzf tanuki-_${DT}_000.tgz tanuki-
- #(cd tanuki-/ ;git checkout 258d55331385a9e594ed8e624409ea3bfdd53602)
- get の以下の行のコメントを外すと(先頭の#をはずず)、指定のバージョンのソースでコンパイル
./get
- 20201119_2000 のような、年月日、時間、分の名前のディレクトリが作成され、その中に、githubからソースをダウンロードしてコンパイルが実行される
- YaneuraOu/source に通常のものがコンパイルされる YaneuraOu-by-gcc
- TOURNAMENTLIB/YaneuraOu/source に上のライブラリバージョンが作成される libYaneuraOu-by-gcc.so
- main.cppをmyMain.cppとコピーして、これをベースに改造したメイン関数を作成
- make myMain TARGET_CPU=SSE42 でmyMainをコンパイル
- SSE42は利用しているCPUに
- LD_LIBRARY_PATH=. ./myMain で実行
- MATE/YaneuraOu/source に詰将棋エンジンが作成される YaneuraOu-by-gcc
- MATELIB/YaneuraOu/source 上のライブラリ libYaneuraOu-by-gcc.so
- main.cppをmyMain.cppとコピーして、これをベースに改造したメイン関数を作成
- make myMain TARGET_CPU=SSE42 YANEURAOU_EDITION=MATE_ENGINE でmyMainをコンパイル
- SSE42は利用しているCPUに
- LD_LIBRARY_PATH=. ./myMain で実行
- MATE2/tanuki-/source にtanukiさんのgithubのソースから作成した詰将棋エンジンが作成される YaneuraOu-by-gcc
- MATE2LIB/tanuki-/source にtanukiさんのgithubのソースから作成した詰将棋エンジンが作成される libYaneuraOu-by-gcc.so
- main.cppをmyMain.cppとコピーして、これをベースに改造したメイン関数を作成
- make myMain TARGET_CPU=SSE42 YANEURAOU_EDITION=MATE_ENGINE でmyMainをコンパイル
- SSE42は利用しているCPUに
- LD_LIBRARY_PATH=. ./myMain で実行
14.4 この章のまとめ
- 最新ソースでは以前の修正内容では対応出来なくなっていたのを修正
- パッチファイルとスクリプトファイルを用意して、楽に最新ソースをコンパイル可能にしてみた
15 Ayaneの利用(PythonからYaneuraOuを利用する別の方法)
15.1 関係リンク
- https://github.com/yaneurao/Ayane
- https://github.com/gunyarakun/python-shogi
- 実装されている、USIコマンド ソースの YaneuraOu/source/usi.cpp で確認可能
15.2 以下の操作を行っている動画
15.3 この章での手順
15.3.1 バーチャル環境作成
cd
virtualenv yaneuraou01
15.3.2 バーチャル環境に入る
cd yaneuraou01/ source bin/activate
15.3.3 python-shogiインストール
pip3 install python-shogi
15.3.4 Ayaneゲットとバックアップ
git clone https://github.com/yaneurao/Ayane.git
tar cvzf Ayane.`date +%Y%m%d`.tgz Ayane/
15.3.5 Ayaneインストール
- カレントディレクトリで動くように
ln -s Ayane/source/shogi .
15.3.6 前の章で作成したエンジンの実行ファイルのパス確認
- 実行ファイルが必要です。詰将棋エンジンは評価関数等が不要で楽
- 通常の将棋エンジンを利用する場合は、評価関数や、定跡ファイルを用意
15.3.7 動作確認
- 配布サイトの文書のコマンドを試してみる
15.4 この章について
- Yaneura王さんが作成した、Python用のインターフェイスライブラリを試してみた
- エンジンを実行ファイルとして、利用するのに便利
16 Ayaneの利用2(PythonからYaneuraOuを利用する別の方法)
- 前の章の手順だと、Ayaneとpython-shogiの同時利用が不可能であったので、インストール方法を変更することで、同時利用可能に
16.1 関係リンク
- https://github.com/yaneurao/Ayane
- https://github.com/gunyarakun/python-shogi
- 実装されている、USIコマンド ソースの YaneuraOu/source/usi.cpp で確認可能
16.2 以下の操作を行っている動画
16.2.1 Ayaneインストール
- カレントディレクトリで動くように以下を行ったが、これ(shogiディレクトリへのリンク)を消して、直接python-shogiのインストール先のディレクトリにAyane.pyをコピーする
- インストール先のディレクトリ名は、Pythonのバージョンで異るので、異るバージョンの場合は、それにあわせる
cd ~/yaneuraou01/
rm shogi
cp Ayane/source/shogi/Ayane.py lib/python3.8/site-packages/shogi/
16.2.2 Ayaneとpython-shogiを同時に動かせる確認
- 以下でバーチャル環境に入る
source bin/activate
- ipythonを起動した後以下を行って、エラーが発生しなければOK
import shogi import shogi.KIF import shogi.Ayane as ayane
16.3 この章について
- 前の章の手順だと、Ayaneとpython-shogiの同時利用が不可能であったので、インストール方法を変更することで、同時利用可能に
17 python-shogiの基本的な使い方
17.1 関係リンク
- https://github.com/yaneurao/Ayane
- https://github.com/gunyarakun/python-shogi
- 実装されている、USIコマンド ソースの YaneuraOu/source/usi.cpp で確認可能
17.2 以下の操作を行っている動画
17.3 試した手順
- バーチャル環境のディレクトリに入る
cd ~/yaneuraou01/
- 以下でバーチャル環境に入る
source bin/activate
- 必要なものをインポート
import shogi import shogi.KIF import shogi.Ayane as ayane
- kifuファイルの読み込み
- kifデータを読み込む時、xxxx.kifu の感じで .kifu で終わるファイル名なら utf-8 仮定で読み込まれるようだ(utf-8の場合こういうファイル名に変更)
kif=shogi.KIF.Parser.parse_file("kifu/20201117-02.kif.kifu")[0]
- 読み込んだ全ての手を表示
for i in kif['moves']: print(i)
- ボード作成
board = shogi.Board()
- ボード表示
print(board.kif_str())
- ボードのsfen表示
print(board.sfen())
- 一手目の内容を表示後、一手目を動かして、盤面とsfen文字を表示
print(kif['moves'][0]) board.push_usi(kif['moves'][0]) print(board.kif_str()) print(board.sfen())
17.4 この章について
- python-shogiの基本的な使い方を確認した
18 USIを直接使って、内容を確認してみよう1(詰将棋エンジンで、指定の盤面を解いてみる)
18.1 関係リンク
- https://github.com/yaneurao/Ayane
- https://github.com/gunyarakun/python-shogi
- 実装されている、USIコマンド ソースの YaneuraOu/source/usi.cpp で確認可能
18.2 以下の操作を行っている動画
18.3 試した手順
18.3.1 詰将棋エンジンを起動
- 詰将棋エンジンを起動する(最近紹介した、githubからダウンロードして、コンパイルするスクリプトを改造し、tournament モードじゃなく normalモードで今日コンパイルしたもの。前の動画のコンパイルの仕方をしたものでも同じ手順で可能)
- 例えば./20201125_2103/MATE/YaneuraOu/source/ に実行ファイルが有る場合は以下
./20201125_2103/MATE/YaneuraOu/source/YaneuraOu-by-gcc
- 将棋エンジンの実行ファイルが入っているディレクトリ名は修正してください。今回はカレントディレクトリに入っているものとします
./YaneuraOu-by-gcc
18.3.2 USIコマンドを入れていく
- 最初はusi
- 以下を入れてEnterキーを押す
usi
- 私の環境だと以下がかえってきた
id name YaneuraOu mate solver Material 5.32 64SSE42 id author by yaneurao option name Threads type spin default 4 min 1 max 512 option name USI_Hash type spin default 4096 min 1 max 33554432 option name WriteDebugLog type check default false option name NetworkDelay type spin default 120 min 0 max 10000 option name NetworkDelay2 type spin default 1120 min 0 max 10000 option name MinimumThinkingTime type spin default 2000 min 1000 max 100000 option name SlowMover type spin default 100 min 1 max 1000 option name MaxMovesToDraw type spin default 0 min 0 max 100000 option name DepthLimit type spin default 0 min 0 max 2147483647 option name NodesLimit type spin default 0 min 0 max 9223372036854775807 option name Contempt type spin default 2 min -30000 max 30000 option name ContemptFromBlack type check default false option name EvalDir type string default eval option name MorePreciseMatePv type check default true usiok
- 次はisreadyを入れる
- 以下を入れてEnterキーを押す
isready
- 私の環境だと以下がかえってきた
readyok
- 盤面を設定する
- 以下を入れてEnterキーを押す
- positionはsfenでもYaneuraOuさんの詰将棋エンジンは大丈夫なようです
position lnsgkgsnl/1r5b1/pppp+P1ppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGS1L b Np 0
- 何もかえってきません。
- デバッグ用に用意されている d コマンドで現状の盤面を確認。(これは他の詰将棋エンジンでは実装されてないかも)
- 以下を入れてEnter
d
- 私の環境だと以下がかえってきた
- 桂馬をと金の横にうてば、詰む状態を作ってある。
^香^桂^銀^金^玉^金^銀^桂^香 口^飛 口 口 口 口 口^角 口 ^歩^歩^歩^歩 と 口^歩^歩^歩 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 歩 歩 歩 歩 歩 歩 歩 歩 歩 口 角 口 口 口 口 口 飛 口 香 桂 銀 金 玉 金 銀 口 香 先手 手駒 : 桂 , 後手 手駒 : 歩 手番 = 先手 sfen lnsgkgsnl/1r5b1/pppp+P1ppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGS1L b Np 0
- 詰将棋を探索させる
go mate infinite
- 私の環境だと以下がかえってきた
info string pn 0 dn 100000000 nodes_searched 0 info time 1 nodes 0 nps 0 hashfull 0 checkmate N*4c
- 平手で探索させて、詰まないことを確認
- 平手に盤面を設定して、盤面表示
sfen startpos d
- 私の環境だと以下がかえってきた
^香^桂^銀^金^玉^金^銀^桂^香 口^飛 口 口 口 口 口^角 口 ^歩^歩^歩^歩^歩^歩^歩^歩^歩 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 口 歩 歩 歩 歩 歩 歩 歩 歩 歩 口 角 口 口 口 口 口 飛 口 香 桂 銀 金 玉 金 銀 桂 香 先手 手駒 : , 後手 手駒 : 手番 = 先手 sfen lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1
- 探索させる
go mate infinite
- 私の環境だと以下がかえってきた
info string pn 100000000 dn 0 nodes_searched 0 checkmate nomate
18.4 この章のまとめ
- USIを取り扱えるGUIを利用せずに直接詰将棋エンジンを操作して、詰将棋を解かせてみた
19 USIを直接使って対戦(GUIを使わず直接エンジンと対話)
19.1 関連リンク
- YaneuraOu https://github.com/yaneurao/YaneuraOu
- ソースの YaneuraOu/docs/USI拡張コマンド.txt にYaneuraOUさん独自のUSI拡張コマンドの説明がある
- USIプロトコルの文書 https://github.com/yaneurao/YaneuraOu (ネット検索するなら、 USI SHOGIで検索すればOK)
19.2 以下の操作を行っている動画
19.3 試した手順
19.3.1 事前準備
- YaneuraOuをあからじめコンパイル
- 評価関数、定跡ファイルを準備
- ファイル構成は以下で動画で行っている
.
├── YaneuraOu-by-gcc
├── book/
├──── standard_book.db
├──── yaneura_book1.db
├──── yaneura_book3.db
├── eval/
└──── nn.bin
19.3.2 詰将棋エンジンを起動
- 以下はUbuntu等のLinuxマシンの場合、Windowsなら、将棋エンジンのexeファイルを起動
./YaneuraOu-by-gcc
19.3.3 USIでの操作
- 事前準備
- usiにたいしてはusiokがかえってくればOK
usi
- isreadyにたいしてはreadyokがかえってくればOK
- 評価関数ファイル nn.binが必要(デフォルトでは実行ディレクトリにあるevalディレクトリ無いに必要。option等で設定すれば他の場所でもいけるかも)
- 定跡ファイルも必要かも
- エラーがでて、readyokが帰ってこなければ、評価関数ファイルと、定跡ファイルを用意しましよう
isready
- ゲーム開始
usinewgame
- 盤面確認(YaneuraOuの将棋エンジン特有のUSI拡張命令 d を利用
d
- 駒の移動1
- 以下は飛車先の歩をすすめる
position startpos moves 2g2f
- 将棋エンジンに手を考えさせる1
- 動画では以下のgoコマンドで、bestmove 5a4b ponder 2f2eがかえってきてた
- この時5a4bがベストと将棋エンジンが思考した手で、ponderの後の2f2eが相手の手の予想になります
go
- 将棋エンジンに手を考えさせる2(先読みさせる)
- 思考させた手と予想手を追加したposition命令を入れる
position startpos moves 2g2f 5a4b 2f2e
- dコマンドで盤面確認するとわかりやすくなる(他の将棋エンジンでは、このUSIコマンドは装備されてないかも)
d
- 終了
- 上の繰り返しを行って最後終わる時は
quit
19.4 この章のまとめ
- GUIを利用せずに、直接将棋エンジンとUSIプロトコルで対話して、対戦してみた
- USIの理解をするのに、これをやってみるのは良い感じ
20 検討の時にどのようなUSIコマンドを使うべきか、将棋エンジンの設定について調べてみた
20.1 関連リンク
- やねうら王さんのオススメ設定https://yaneuraou.yaneu.com/2018/11/03/%E3%82%84%E3%81%AD%E3%81%86%E3%82%89%E7%8E%8B%E3%81%AE%E6%A4%9C%E8%A8%8E%E7%94%A8%E8%A8%AD%E5%AE%9A%E3%81%AE%E3%81%8A%E5%8B%A7%E3%82%81%E3%82%92%E6%95%99%E3%81%88%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95/
- ConsiderationModeをtureに https://yaneuraou.yaneu.com/2017/05/15/%E6%A4%9C%E8%A8%8E%E3%83%A2%E3%83%BC%E3%83%89%E7%94%A8%E3%81%AE%E8%AA%AD%E3%81%BF%E7%AD%8B%E5%87%BA%E5%8A%9B%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/
20.2 以下の操作を行っている動画
20.3 説明
- やねうら王さんのオススメ設定https://yaneuraou.yaneu.com/2018/11/03/%E3%82%84%E3%81%AD%E3%81%86%E3%82%89%E7%8E%8B%E3%81%AE%E6%A4%9C%E8%A8%8E%E7%94%A8%E8%A8%AD%E5%AE%9A%E3%81%AE%E3%81%8A%E5%8B%A7%E3%82%81%E3%82%92%E6%95%99%E3%81%88%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95/
- USI_Hash : 置換表のサイズ(単位[MB])
- 大きい方が良いけど全部はダメ
- 1GBのメモリを使う場合「1000」を設定らしい。メモリ全部を割り当てちゃダメ
- Threadsは物理コア数に。Androidなら1が良いみたい
- ConsiderationModeをtureに https://yaneuraou.yaneu.com/2017/05/15/%E6%A4%9C%E8%A8%8E%E3%83%A2%E3%83%BC%E3%83%89%E7%94%A8%E3%81%AE%E8%AA%AD%E3%81%BF%E7%AD%8B%E5%87%BA%E5%8A%9B%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/
- USI_Hash : 置換表のサイズ(単位[MB])
- 配布物のソースのdocディレクトリにある、YaneuraOu/docs/USI拡張コマンド.txt ファイル
- go depth X depth指定での思考。
- 例 go depth 6
- 例 go depth X mate infinite
- go nodes X 探索node数を指定しての思考
- 例 go nodes 10000
- 例 go nodes X mate infinite
- go depth X depth指定での思考。
20.4 実際にやってみる
- 最初の定形
usi setoption name Threads value 2 setoption name ConsiderationMode value true isready usinewgame
- 適当な盤面(最近の私の対戦の1つの局面)
position 4B2Sl/l4g1k1/5pnpp/p2pp1p2/1p7/P2+s2P2/1P3PN1P/3+n2S2/+r1+rPGK2L b Lb2gsn4p 101 go depth 20
- その時の出力。私のPCでだいたい30秒くらい思考
info depth 1 seldepth 1 score cp -2391 nodes 271 nps 135500 time 2 pv 5a4b+ 6h5i 4i3i info depth 2 seldepth 3 score cp -2391 nodes 483 nps 241500 time 2 pv 5a4b+ 6h5i 4i3i 2b2a G*3b 2a1b info depth 3 seldepth 4 score cp -513 nodes 676 nps 338000 time 2 pv 5a4b+ 6h5i 4i3i 2b2a G*3b 2a1b info depth 4 seldepth 6 score cp -513 nodes 864 nps 288000 time 3 pv 5a4b+ 6h5i 4i3i 2b2a G*3b 2a1b info depth 5 seldepth 7 score cp -2310 nodes 1554 nps 518000 time 3 pv 5a4b+ 6h5i 4i3i 2b2a G*3b 2a1b 3b3c info depth 6 seldepth 8 score cp -513 nodes 1912 nps 637333 time 3 pv 5a4b+ 6h5i 4i3i 2b2a G*3b 2a1b 3b3c 7i6i info depth 7 seldepth 10 score cp -1207 nodes 3768 nps 753600 time 5 pv 5a4b+ 6h5i 4i3i 2b2a G*3b 2a1b 4b3c 5i4i 3i2i info depth 8 seldepth 9 score cp -1207 nodes 4249 nps 849800 time 5 pv 5a4b+ 6h5i 4i3i 2b2a G*3b 2a1b 4b3c 5i4i 3i2i info depth 9 seldepth 13 score cp -913 nodes 6952 nps 993142 time 7 pv 5a4b+ 6h5i 4i3i 2b2a G*3b 2a1b 4b3c 5i4i 3i2i info depth 10 seldepth 12 score cp -2164 nodes 13621 nps 1047769 time 13 pv 5a4b+ 6h5i 4i3i G*4h 3i2h 4h3h 2h2g S*1h 1i1h 3h3g 2g3g N*4e 3g2f info depth 11 seldepth 17 score cp -5278 nodes 65211 nps 869480 time 75 pv 4i3i 4b4a L*4f S*5b 5i6h 4a5a N*2e B*5i 2e3c+ 2b3c N*2e 3c4b 3i2h 5i6h+ 6i6h 7i1i 2h2g info depth 12 seldepth 19 score cp -5045 nodes 87268 nps 831123 time 105 pv 4i3i 4b4a 5a8d+ 6f5f 5i6h 7i6h N*2e 3c2e 3g2e 9i6i 3i2h info depth 13 seldepth 16 score cp -4986 nodes 104602 nps 823637 time 127 pv 4i3i 4b4a 5a8d+ 6f5f 8d8e S*5b 5i6h 7i6h 3i2h 2b2a 6i6h info depth 14 seldepth 15 score cp -4741 nodes 118104 nps 814510 time 145 pv 4i3i 4b4a 5a8d+ 6f5f 8d8e S*5b 5i6h 7i6h 8e5b info depth 15 seldepth 23 score cp -5741 nodes 1532976 nps 876487 hashfull 592 time 1749 pv 4i3i 4b5b 5i6h 5b5a L*5c 5a4b N*4f 2b2a 4f3d 4b5c 3g2e 3c2e 3h4i 2a3b P*2b G*4a 2b2a+ info depth 16 seldepth 26 score cp -5807 upperbound nodes 2639289 nps 851108 hashfull 820 time 3101 pv 4i3i 4b5b 5i6h 5b5a L*5c 5a4b N*4f 2b2a 4f3d 4b5c 3g2e 3c2e 3h4i 2a3b P*2b G*4a 2b2a+ 3b2a info depth 16 seldepth 26 score cp -5848 upperbound nodes 3112688 nps 845609 hashfull 890 time 3681 pv 4i3i 4b5b 5i6h 5b5a L*5c 5a4b N*4f 2b2a 4f3d 4b5c 3g2e 3c2e 3h4i 2a3b P*2b G*4a 2b2a+ 3b2a info depth 16 seldepth 26 score cp -5905 upperbound nodes 3977493 nps 819257 hashfull 951 time 4855 pv 4i3i 4b5b 5i6h info depth 16 seldepth 26 score cp -5981 upperbound nodes 4851367 nps 828726 hashfull 983 time 5854 pv 4i3i 4b5b 3i2h 6h5i L*1b 1a1b 2a1b+ 2b3b 5a8d+ B*5g 1g1f info depth 16 seldepth 26 score cp -5920 lowerbound nodes 5580566 nps 835039 hashfull 994 time 6683 pv 4i3i B*5g 3i2i 4b5b L*5c S*3i 2a3b+ 2b3b 5a3c+ 3b3c N*2e 3c4b info depth 16 seldepth 26 score cp -5927 nodes 5701475 nps 836606 hashfull 996 time 6815 pv 4i3i B*5g L*4h 4b5b 5a3c+ 2b3c N*4i 5g2d+ 5i6h 3c4d N*5h N*5f 5h6f 5f6h+ 6i6h 2d6h 3i2i 4d5e info depth 17 seldepth 24 score cp -5946 upperbound nodes 5867366 nps 838914 hashfull 996 time 6994 pv 4i3i B*5g L*4h 4b5b 5a3c+ 2b3c N*4i 5g2d+ 5i6h 3c4d N*5h N*5f 5h6f 5f6h+ 6i6h 2d6h 3i2i 4d5e info depth 17 seldepth 24 score cp -5965 upperbound nodes 5962177 nps 839979 hashfull 996 time 7098 pv 4i3i B*5g L*4h 4b5b 5a3c+ 2b3c N*4i 5g2d+ 5i6h 3c4d N*5h N*5f 5h6f 5f6h+ 6i6h 2d6h 3i2i 4d5e info depth 17 seldepth 24 score cp -5994 upperbound nodes 6148436 nps 842713 hashfull 997 time 7296 pv 4i3i B*5g L*4h 4b5b 5a3c+ 2b3c N*4i 5g2d+ 5i6h 3c4d N*5h N*5f 5h6f 5f6h+ 6i6h 2d6h 3i2i 4d5e info depth 17 seldepth 24 score cp -6035 upperbound nodes 6667511 nps 846990 hashfull 998 time 7872 pv 4i3i B*5g L*4h 4b5b 5a3c+ 2b3c N*4i 5g2d+ 5i6h 3c4d N*5h info depth 17 seldepth 24 score cp -6092 upperbound nodes 7174905 nps 851317 hashfull 998 time 8428 pv 4i3i B*5g L*4h 4b5b 5a3c+ 2b3c N*4i 5g2d+ 5i6h 3c4d N*5h info depth 17 seldepth 24 score cp -6167 upperbound nodes 8101274 nps 855467 hashfull 1000 time 9470 pv 4i3i B*5g L*4h 4b5b 5a3c+ 2b3c N*4i 5g2d+ 5i6h 3c4d N*5h info depth 17 seldepth 24 score cp -6177 nodes 8583451 nps 858430 hashfull 1000 time 9999 pv 4i3i B*5g L*4h 4b5b 5a3c+ 2b3c N*4i 5g2d+ 5i6h 3c4d N*5h 6f6e 3i2h G*2b 4i5g 2b2a 5g6e info depth 18 seldepth 29 score cp -6196 upperbound nodes 9405168 nps 860569 hashfull 1000 time 10929 pv 4i3i B*5g L*4h 4b5b 5a3c+ 2b3c N*4i 5g2d+ 5i6h 3c4d N*5h info depth 18 seldepth 29 score cp -6215 upperbound nodes 10363702 nps 862061 hashfull 1000 time 12022 pv 4i3i B*5g L*4h 4b5b 5a3c+ 2b3c N*4i 5g2d+ 5i6h N*5f N*1f 2d1d 3g4e 3c4d 2a3b 4d5e 3b4a 5b6b info depth 18 seldepth 29 score cp -6244 upperbound nodes 11624861 nps 865782 hashfull 1000 time 13427 pv 4i3i B*5g L*4h 4b5b 5a3c+ 2b3c N*4i 5g2d+ 5i6h N*5f N*1f info depth 18 seldepth 29 score cp -6285 upperbound nodes 13213656 nps 870120 hashfull 1000 time 15186 pv 4i3i B*5g L*4h info depth 18 seldepth 29 score cp -6252 lowerbound nodes 13296528 nps 869850 hashfull 1000 time 15286 pv 4i3i B*5g L*4h info depth 18 seldepth 29 score cp -6180 nodes 13306369 nps 869867 hashfull 1000 time 15297 pv 4i3i B*5g L*4h 4b5b 5a8d+ 2b2a 8d8e 5b4b 8e4i 6h6i 5i6i 7i6i N*4e 2a2b 3i2h 3c4e 3g4e S*3i 4i3i 6i3i 2h2g info depth 19 seldepth 25 score cp -6198 upperbound nodes 13474472 nps 870106 hashfull 1000 time 15486 pv 4i3i B*5g L*4h 4b5b 5a8d+ 2b2a 8d8e 5b4b 8e4i 6h6i 5i6i 7i6i N*4e 2a2b 3i2h G*3b info depth 19 seldepth 25 score cp -6217 upperbound nodes 13947562 nps 870688 hashfull 1000 time 16019 pv 4i3i B*5g L*4h info depth 19 seldepth 25 score cp -6246 upperbound nodes 14057638 nps 870927 hashfull 1000 time 16141 pv 4i3i B*5g L*4h 4b5b 5a8d+ 2b2a 8d8e 5b4b 8e4i 6h6i 5i6i 7i6i N*4e info depth 19 seldepth 25 score cp -6222 lowerbound nodes 14619891 nps 871632 hashfull 1000 time 16773 pv 4i3i B*5g L*4h info depth 19 seldepth 27 score cp -6287 upperbound nodes 15112718 nps 872709 hashfull 1000 time 17317 pv 4i3i B*5g L*4h 4b5b 5a3c+ 2b3c N*4i 5g2d+ 5i6h N*5f 3g4e 3c4d 2a3b 4d5e 6h5g info depth 19 seldepth 29 score cp -6226 lowerbound nodes 17538540 nps 872911 hashfull 1000 time 20092 pv 4i3i B*5g 3i2i 4b5b 3g2e info depth 19 seldepth 29 score cp -6363 upperbound nodes 18354145 nps 874548 hashfull 1000 time 20987 pv 4i3i B*5g 3i2i 4b5b 3g2e info depth 19 seldepth 29 score cp -6244 lowerbound nodes 23156655 nps 875322 hashfull 1000 time 26455 pv 4i3i B*5g L*4h info depth 19 seldepth 29 score cp -6317 nodes 23173727 nps 875272 hashfull 1000 time 26476 pv 4i3i B*5g L*4h 4b5b 5a3c+ 2b3c N*4i 5g2d+ 5i6h 3c4d 2a3b N*5f 3g4e 4d5e N*5h 5f6h+ 5h6f 5e6f 6i6h info depth 20 seldepth 23 score cp -6336 upperbound nodes 24103006 nps 875199 hashfull 1000 time 27540 pv 4i3i B*5g L*4h info depth 20 seldepth 23 score cp -6317 lowerbound nodes 24117267 nps 875114 hashfull 1000 time 27559 pv 4i3i B*5g L*4h info depth 20 seldepth 23 score cp -6288 lowerbound nodes 24122255 nps 875104 hashfull 1000 time 27565 pv 4i3i B*5g L*4h info depth 20 seldepth 27 score cp -6355 upperbound nodes 24338011 nps 875027 hashfull 1000 time 27814 pv 4i3i B*5g L*4h info depth 20 seldepth 27 score cp -6301 lowerbound nodes 24353457 nps 874984 hashfull 1000 time 27833 pv 4i3i B*5g L*4h info depth 20 seldepth 27 score cp -6293 nodes 24694818 nps 875237 hashfull 1000 time 28215 pv 4i3i B*5g L*4h 4b5b 5a3c+ 2b3c N*4i 5g2d+ 5i6h 3c4d 2a3b N*5f 3g4e 4d5e N*5h 5f6h+ 6i6h 2d6h 3i2h S*5i 3b4c 5b4c bestmove 4i3i ponder B*5g
- 将棋エンジン停止
quit
- 次に詰みがある盤面をやってみた。
usi setoption name Threads value 2 setoption name ConsiderationMode value true isready usinewgame position lnsg3nl/4k1G2/p1pp1pp1p/4p4/7r1/P1P1P1R+B1/1PSPbPP1P/2G6/LN2KGSNL b SP2p 1 go depth 20
- 一瞬でおわった
- 詰みがあると 「mate 詰みまでの手数」がエンジンからinfoで送られてくる
info depth 1 seldepth 2 score mate 3 nodes 206 nps 206000 time 1 pv S*5c 5b5a 3b4b info depth 2 seldepth 4 score mate 3 nodes 479 nps 479000 time 1 pv S*5c 5b5a 3b4b info depth 3 seldepth 4 score mate 3 nodes 698 nps 349000 time 2 pv S*5c 5b5a 3b4b info depth 4 seldepth 4 score mate 3 nodes 911 nps 455500 time 2 pv S*5c 5b5a 3b4b info depth 5 seldepth 4 score mate 3 nodes 1122 nps 561000 time 2 pv S*5c 5b5a 3b4b info depth 6 seldepth 4 score mate 3 nodes 1345 nps 672500 time 2 pv S*5c 5b5a 3b4b info depth 7 seldepth 4 score mate 3 nodes 1562 nps 781000 time 2 pv S*5c 5b5a 3b4b
20.5 この章のまとめ
- 検討したいときに、USIコマンドでどのようなコマンドをYaneuraOuエンジンに送れば良いのかをネット検索した
- 他の将棋エンジンも、このUSIコマンドをサポートしているか不明。方言あるため
- 実際に直接USIコマンドで、どの程度時間かかるのかと、どのような情報が将棋エンジンから送られるのかを確認した。
- ネット対局の棋譜の解析を今は手動で行っているが、今回の調査を元に、自動化したいと考えてます。
21 今後
- 今後も文書追加していきます。
22 この文書のチェンジログ
- 2020/07/06 初版
- 2020/07/08 一括でソースゲットしてコンパイルするプログラム修正、情報URLの修正
- 2020/07/09 下準備の章追加
- 2020/07/09 下準備2の章,Positionクラス(盤面クラス)の初期化と表示の章 追加
- 2020/07/10 詰みチェック,指定の一手を行う,指定の一手を行った後、その手の取り消しの章追加
- 2020/09/02 Python+cppyyを利用して、PythonからYaneuraouのライブラリの直接利用 の章追加
- 2020/11/19 最新ソースをダウンロード(2020/11/19)して、トーナメント用、詰将棋用のエンジンコンパイル、それらのライブラリコンパイル用のスクリプトについて の章を作成
- 2020/11/19 Ayaneの利用(PythonからYaneuraOuを利用する別の方法) の章追加
- 2020/11/20 Ayaneの利用2(PythonからYaneuraOuを利用する別の方法) の章追加
- 2020/11/20 python-shogiの基本的な使い方 の章追加
- 2020/11/25 USIを直接使って、内容を確認してみよう1(詰将棋エンジンで、指定の盤面を解いてみる) の章追加
- 2020/12/09 USIを直接使って対戦(GUIを使わず直接エンジンと対話) の章追加
- 2021/01/19 検討の時にどのようなUSIコマンドを使うべきか、将棋エンジンの設定について調べてみた の章追加
Created: 2021-01-21 木 06:12