Ubuntuで将棋倶楽部24(2020/11/20)

Ubuntuで将棋倶楽部24(2020/11/20)

1 概要

  • Ubuntuで将棋倶楽部24を試してみたいと思って、色々調べたら、ORACLEのソフトを入れないと無理的な情報多かったけど、icedtea-netx (標準パッケージ)を入れたら動いたので、この文書作ることにした。

2 リンク

3 Ubuntu 20.04で将棋倶楽部24を動かす

  • 推奨環境じゃないのはご承知おきを
    • Javaなので互換性はあるはずだけど、Ubuntuの環境でopenjdkではテストされてないので、信頼性は推奨環境より落ちる
    • まだ対局はしてないけど、動いて、動かした範囲内で不具合は発生しなかった
  • 動かすには会員登録が必要

3.1 以下の操作を行っている動画


3.2 Ubuntu 20.04で将棋倶楽部24を動かす手順について

3.2.1 必要なパッケージのインストール

  • アプリバージョン(jnlpファイル)を動かすのに必要パッケージのインストール
  • apt-cache search jnlp でパッケージ検索してヒットした icedtea-netx を入れて試したら将棋倶楽部24のアプリ動いた
sudo apt install icedtea-netx

3.2.2 必要なアプリのダウンロード

  • https://www.shogidojo.net/dojo/play/から2020/11/20ではダウンロードできました。以下がそのページで調べたURLをwgetでダウンロードするコマンド
  • wgetじゃなくて、ブラウザでダウンロードしてもOK
wget -m -l 1 http://internet2.shogidojo.net/dojo/24TokyoDojo.jnlp http://internet3.shogidojo.net/dojo/24OsakaDojo.jnlp http://internet2.shogidojo.net/dj2/24TokyoKifu.jnlp http://internet3.shogidojo.net/dj2/24OsakaKifu.jnlp

3.2.3 実行

  • カレントディレクトリに jnlp ファイルがあるなら、 javaws 対象のjnlpファイル名 で動く
  • 上のwgetコマンドでダウンロードしたら、以下のパスにjnlpがあるので以下のコマンドになる
  1. 大阪道場
    javaws ./internet3.shogidojo.net/dojo/24OsakaDojo.jnlp
    
  2. 大阪棋譜
    javaws ./internet3.shogidojo.net/dj2/24OsakaKifu.jnlp
    
  3. 東京道場
    • 起動に10分弱かかった。起動後の速度は遅くない
    javaws ./internet2.shogidojo.net/dojo/24TokyoDojo.jnlp
    
  4. 東京棋譜
    • 起動に10分弱かかった。起動後の速度は遅くない
    javaws ./internet2.shogidojo.net/dj2/24TokyoKifu.jnlp
    

3.3 この章のまとめ

  • Ubuntu 20.04の標準パッケージだけで、将棋倶楽部24が動いた
  • 推奨環境じゃないので、自己責任でご利用ください
  • 他のサイトの推奨のORACLEの純正のものを入れた方が良いのかも(東京サーバーの起動遅いよ問題)

4 今後

  • 今後も文書追加していきます。

5 この文書のチェンジログ

  • 2020/11/20 初版

著者: NM Max

Created: 2020-11-21 土 13:09

Validate

YaneuraOuさんの将棋ソフトのUbuntuへのインストール(2020/7 バージョン)

YaneuraOuさんの将棋ソフトのUbuntuへのインストール(2020/7 バージョン)

目次

1 概要

  • ここ数年YaneuraOuさんの将棋ライブラリを利用した将棋ソフトがコンピューター将棋大会で優勝
  • C++とアセンブラベース
  • Stockfishというチェスソフトをかなり取り込んだ作りになってるらしい
  • GitHubにてソース公開されている
  • バージョンによって使い方が相当変化している
    • 昔のバージョンに戻せば、過去の動画の使い方も出来る(今は同じ方法で同じように使えない)
    • スレッド等他のライブラリとの依存関係があり、使う難易度が高い

2 リンク

3 エンジン部分のインストール

3.1 Ubuntuでコンパイル

3.1.1 以下の操作を行っている動画





3.2 手順

3.2.1 依存パッケージのインストール

  • 色々あると思う、私は色々入れていたので、私の環境の場合以下を入れる必要があった
sudo apt install bash vim clang make lldb gdb git libc6-dev wget unar
sudo apt install libomp-dev libopenblas-dev
sudo apt install uci2wb xboard 

3.2.2 利用PCのCPUチェック

  • avx拡張命令の利用可能チェック
grep -i avx /proc/cpuinfo
  • sse拡張命令の利用可能チェック
grep -i sse /proc/cpuinfo

3.2.3 ソースゲット

git clone https://github.com/yaneurao/YaneuraOu.git

3.2.4 ソースバックアップ

tar cvzf YaneuraOu.org.tgz YaneuraOu

3.2.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 等)
cd YaneuraOu/source 
make clean tournament TARGET_CPU=SSE42
  • これでコンパイルが実行され、YaneuraOu-by-gcc っていう実行可能なファイルが生成される(必要なライブラリやツールがインストールされていた場合、不足している場合はエラーメッセージから必要なパッケージをインストールしていく)
  • 取得してソースバックアップし、コンパイル後にコンパイル後のファイルも保存するスクリプトが以下
  • 現状はSSE42用(CPUタイプ)
    • それ以外のCPUタイプ希望の場合は他のものを有効にし(行頭の#をとる)、SSE42のところをコメントに(行頭に#をいれる)
#!/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.2.6 コンパイル(学習タイプの場合、評価関数ファイルを生成できるタイプ)

  • 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.3 ゼロの評価関数ファイルの生成

  • 学習タイプの YaneuraOu-by-gcc の起動
./YaneuraOu-by-gcc
  • YaneuraOu/docs/解説.txt にある文書の手順で行う
EvalDir xyz              // 存在しないフォルダを評価関数の読み込みフォルダに指定する
SkipLoadingEval true     // こうしておけば評価関数ファイルの読み込みに失敗してもエラーにならない
isready                  // このタイミングで評価関数が読み込まれるが存在しないフォルダから読み込むのでゼロクリアされた評価関数を読み込んだことになる。
EvalSaveDir eval_zero    // 保存フォルダ名を"eval_zero"に設定(何でも良い)
test evalsave            // メモリ上の評価関数を保存するコマンド
  • 停止
quit                     // 停止
  • これにより eval_zero/nn.bin に評価関数ファイル nn.binが生成される
  • nn.binを競技用YaneuraOu-by-gccのあるディレクトリのevalの中に入れる
cp -i eval_zero/nn.bin ../../../YaneuraOu/source/eval/

3.4 動作確認

  • 以下のコマンドで起動
./YaneuraOu-by-gcc
  • usiコマンドをいれて動作確認(usi,d等)
usi
isready
d
  • quitで停止
quit

3.5 評価関数の準備

  • いくつか有力なものある
  • どれかを選択し、解凍したnn.binを eval ディレクトリにいれる

3.6 KristallweizenさんのKristallweizen_kaiV0.4.zipの場合

wget https://github.com/Tama4649/Kristallweizen/raw/master/Kristallweizen_kaiV0.4.zip
unar Kristallweizen_kaiV0.4.zip

3.7 評価関数 orqha レーティング約4330の評価関数

wget https://www.qhapaq.org/static/media/bin/orqha.7z
unar orqha.7z

3.8 Elmo wcsc29バージョン

unar elmo_wcsc29_eval.zip

3.9 定跡の準備

3.10 YaneuraOuさんの定跡

wget https://github.com/yaneurao/YaneuraOu/releases/download/BOOK-700T-Shock/700T-shock-book.zip https://github.com/yaneurao/YaneuraOu/releases/download/v4.73_book/standard_book.zip https://github.com/yaneurao/YaneuraOu/releases/download/v4.73_book/yaneura_book1_V101.zip https://github.com/yaneurao/YaneuraOu/releases/download/v4.73_book/yaneura_book3.zip 
unar 700T-shock-book.zip 
unar standard_book.zip 
unar yaneura_book1_V101.zip 
unar yaneura_book3.zip 

3.11 解凍したものを book というディレクトリを作成していれる

3.12 起動用のスクリプトファイルを用意

3.13 YaneuraOu-by-gccの起動用スクリプトファイル作成

#!/bin/sh
cd `dirname $0`
./YaneuraOu-by-gcc

3.14 実行権限を与える

chmod +x 作成したスクリプトファイル名
  • 例 startYaneuraOu.shなら
chmod +x startYaneuraOu.sh

3.15 ファイルの再配置

  • YaneuraOu-by-gcc はトーナメント用の実行ファイルを利用
.
├── FEN
├── YaneuraOu-by-gcc
├── book
│   ├── standard_book.db
│   ├── yaneura_book1.db
│   └── yaneura_book3.db
├── eval
│   └── nn.bin
└── startYaneuraOu.sh

3.16 エンジンの動作確認

  • startYaneuraOu.shを起動した後に以下を入れる
  • isready に対して readyok が返ってきたらOK (評価関数や、定跡ファイルとしてどれが利用されているか確認すること)
usi
isready
quit

4 GUIの準備

5 xboardの場合

  • インストールが一番簡単
  • 見た目がイマイチ
xboard -fcp "uci2wb debug -s /opt/shogi/20200707/startYaneuraOu.sh" -scp "uci2wb debug -s  /opt/shogi/20200707/startYaneuraOu.sh" -variant shogi  -coords  -pid /usr/share/games/xboard/themes/shogi/ -highlightSquareColor  "#00FFFF" -clockMode true -tc 5 -mps 30 -showMoveTime true -positionDir /opt/shogi/20200707/FEN -useBoardTexture true -liteBackTextureFile /usr/share/games/xboard/themes/textures/wood_d.png -darkBackTextureFile /usr/share/games/xboard/themes/textures/wood_d.png

6 Android用のYaneuraOuをビルド

  • Android用のバイナリを作るためのファイルも配布物に同梱されているらしいことに気づいたので、コンパイルしてみました。
  • 前準備として、Andrido NDKをインストールする必要があります。https://youtu.be/3U5_330aySk

6.1 以下の操作を行っている動画


6.2 Android用のYaneuraOuをビルド する手順

6.2.1 最新バージョンをコンパイル(2021/01/19時点)

  • 頻繁に更新されるため、これ以下の方法では、今後のバージョンコンパイルできない可能性あり
  • gitのタグだと 9bbd0f38498b22e9f3e6cf9493a7f8849c02e496 のものは以下でコンパイル出来ている(通常モードは作成可だった。能詰将棋エンジンはコンパイル中にエラーになる)
  1. YaneuraOuのソースゲット
    git clone https://github.com/yaneurao/YaneuraOu.git
    
  2. ソースのバックアップ
    • 最初の命令はdateコマンドで日付と時間をバックアップファイル名にする方法
    • 後の方はYaneuraOu_000.tgz というファイル名でバックアップ。別の名前でバックアップとっておいてもよい
    • 別のツールでバックアップもOK
    • バックアップ取らない選択もあり
    tar cvzf YaneuraOu_`date +%Y%m%d_%H%M`.tgz YaneuraOu/
    とか
    tar cvzf YaneuraOu_000.tgz YaneuraOu/
    
  3. コンパイル
    • コンパイルできるディレクトリに移動YaneuraOu/jni/
    cd YaneuraOu/jni/
    
    • 以下は64bit用の設定。
    • TARGET_ARCH_ABI=armeabi-v7a とすれば32bit用を作成可能
    • 他のCPUのタイプも含めて全部コンパイルするには TARGET_ARCH_ABI=なんちゃら を省略すればOK
    ndk-build TARGET_ARCH_ABI=arm64-v8a
    
    • 詰将棋エンジンをコンパイルするには以下(ただし、このバージョンではエラー発生してビルド失敗する)
      • ENGINE_NAME=YaneuraOu_MATE_arm64-v8a をいれてないとコンパイルエラーになる
    ndk-build YANEURAOU_EDITION=MATE_ENGINE TARGET_ARCH_ABI=arm64-v8a ENGINE_NAME=YaneuraOu_MATE_arm64-v8a
    

6.2.2 リリースバージョンをコンパイル(version4.88)

  1. YaneuraOuのソースゲット
    • https://github.com/ai5/YaneuraOuの右のReleasehttps://github.com/ai5/YaneuraOu/releasesに「Android版 やねうら王」となってる最新のところからダウンロード。2019/1/19時点で最新はv4.88https://github.com/ai5/YaneuraOu/releases/tag/android_488。zip版でもtar.gz版でもOK。私はtar.gzバージョンをダウンロードした。
    • もっと新しいバージョンでてるなら、そちらを選択してください。2021/1/19時点では4.88が最新
    • こちらは詰将棋エンジンバージョンもコンパイルは成功する。ただし、詰将棋をAndroidでとかせようとすると、セグメーテーションエラー発生。通常バージョンは正常動作していた。
  2. Android版 やねうら王v4.88のソース解凍
    tar xvzf YaneuraOu-android_488.tar.gz
    
  3. Android版 やねうら王v4.88のコンパイル
    • arm64-v8a (64bitCPU用)の詰将棋エンジンを作成します。
    cd YaneuraOu-android_488/jni/
    ndk-build ENGINE_TARGET=MATE_ENGINE TARGET_ARCH_ABI=arm64-v8a
    
    • ../libs/arm64-v8a/YaneuraOu-mate-arm64-v8a が作成されます。
      • ただ私がUmidigi F1Playで動作確認したところ、go mate infiniteするとセグメンテーションエラーで落ちてしまい、詰将棋とけませんでした。
      • エンジンオプションでなんとかならないか色々試しました(Hash減らすとか)が上手く動作せず
      • デバッガーオプションつけて、デバッガーでそのうち確認してみようと思ってますが。まだやってません。
    • arm64-v8a (64bitCPU用)の通常バージョンを作成します。
    ndk-build TARGET_ARCH_ABI=arm64-v8a
    
    • ../libs/arm64-v8a/YaneuraOu-nnue-halfkp256-arm64-v8aが作成されます。
      • こちらは上手く動作しました。Umidigi F1Playで。評価関数と、定跡ファイルをいれれば

6.3 この章のまとめ

  • Android用のバイナリをクロスコンパイルしてみた。
  • 通常の将棋エンジンは、上手くコンパイル実行できていました。また動作確認結果も良好。
  • 詰将棋エンジンは、最新のソースでは上手くコンパイルできず、リリースバージョンでも、コンパイルは出来るものの、詰将棋をとかせる命令(go mate infinite等))を入れるとセグメンテーションエラーが発生

7 Android用のYaneuraOuをビルド2(2021/05/17)

  • 前からノーマル将棋エンジンはクロスコンパイルに成功していた
  • 詰将棋エンジンはv4.88はコンパイルには成功するものの、動かすとセグメンテーションエラーで動かなかった
  • 詰将棋エンジンは最新バージョンでコンパイルに成功しなかった。(色々エラー出て)
  • 久しぶりにGitHubから最新ソースをゲットして、クロスコンパイルを環境変数の設定色々変更してやってみたら、上手くいった

7.1 以下の操作を行っている動画


7.2 Android用のYaneuraOuをビルド2(2021/05/17)を行う手順

  • 前準備として、Andrido NDKをインストールする必要があります。https://youtu.be/3U5_330aySk
  • sdkmanager –list_installed で確認したインストール済みのAndroid SDK NDK関係は以下の通り
    • コンパイルに利用したndkはndk-bundleを利用した
Installed packages:=====================] 100% Fetch remote repository...       
  Path                   | Version      | Description                             | Location               
  -------                | -------      | -------                                 | -------                
  build-tools;24.0.3     | 24.0.3       | Android SDK Build-Tools 24.0.3          | build-tools/24.0.3/    
  build-tools;29.0.2     | 29.0.2       | Android SDK Build-Tools 29.0.2          | build-tools/29.0.2/    
  build-tools;30.0.2     | 30.0.2       | Android SDK Build-Tools 30.0.2          | build-tools/30.0.2/    
  build-tools;30.0.3     | 30.0.3       | Android SDK Build-Tools 30.0.3          | build-tools/30.0.3/    
  build-tools;31.0.0-rc2 | 31.0.0 rc2   | Android SDK Build-Tools 31-rc2          | build-tools/31.0.0-rc2/
  cmake;3.10.2.4988404   | 3.10.2       | CMake 3.10.2.4988404                    | cmake/3.10.2.4988404/  
  cmake;3.6.4111459      | 3.6.4111459  | CMake 3.6.4111459                       | cmake/3.6.4111459/     
  cmdline-tools;latest   | 4.0          | Android SDK Command-line Tools (latest) | cmdline-tools/latest/  
  emulator               | 30.6.5       | Android Emulator                        | emulator/              
  ndk-bundle             | 22.1.7171670 | NDK                                     | ndk-bundle/            
  ndk;19.2.5345600       | 19.2.5345600 | NDK (Side by side) 19.2.5345600         | ndk/19.2.5345600/      
  patcher;v4             | 1            | SDK Patch Applier v4                    | patcher/v4/            
  platform-tools         | 31.0.2       | Android SDK Platform-Tools              | platform-tools/        
  platforms;android-27   | 3            | Android SDK Platform 27                 | platforms/android-27/  
  platforms;android-29   | 5            | Android SDK Platform 29                 | platforms/android-29/  
  platforms;android-30   | 3            | Android SDK Platform 30                 | platforms/android-30/  
  • 頻繁に更新されるため、これ以下の方法では、今後のバージョンコンパイルできない可能性あり
  • gitのタグだと a866bafb71aae5833be3d34c1227564c6ccb323b のものは以下でコンパイル出来ている。
    • YaneuraOuさんのソースの更新頻度高く、新しいバージョンで同じ手順で成功しなくなるかも。その時は上の git の id に git checkout a866bafb71aae5833be3d34c1227564c6ccb323b で戻して、そこで同じ手順でやれば上手くいくはず
  • 動画では、Docker Image( https://youtu.be/473GGAkxqy8に作成方法ある)を使ってコンパイルしています。
  1. YaneuraOuのソースゲット
    git clone https://github.com/yaneurao/YaneuraOu.git
    
  2. ソースのバックアップ
    • 最初の命令はdateコマンドで日付と時間をバックアップファイル名にする方法
    • 後の方はYaneuraOu_000.tgz というファイル名でバックアップ。別の名前でバックアップとっておいてもよい
    • 別のツールでバックアップもOK
    • バックアップ取らない選択もあり
    tar cvzf YaneuraOu_`date +%Y%m%d_%H%M`.tgz YaneuraOu/
    とか
    tar cvzf YaneuraOu_000.tgz YaneuraOu/
    
  3. コンパイル
    • コンパイルできるディレクトリに移動YaneuraOu/jni/
      • 備考 YaneuraOu/jni/ でなく YaneuraOu/ ディレクトリでもコンパイルできた 
    cd YaneuraOu/jni/
    
    • 以下は64bit用の設定。
      • TARGET_ARCH_ABI=armeabi-v7a とすれば32bit用を作成可能
      • 他のCPUのタイプも含めて全部コンパイルするには TARGET_ARCH_ABI=なんちゃら を省略すればOK
      • 実行ファイルのバックアップと、転送の手順は省略している
      • この実行ファイルの動作確認には、評価関数ファイルが必要
      • 定跡ファイルもあった方が良い
    ndk-build TARGET_ARCH_ABI=arm64-v8a clean #掃除
    ndk-build TARGET_ARCH_ABI=arm64-v8a
    mkdir -p arm64-v8a/ #バックアップ用のディレクトリ作成
    mv ../libs/arm64-v8a/YaneuraOu_NNUE_arm64-v8a arm64-v8a/ # 消さないようにビルドしたバイナリを移動
    
  4. tanuki詰将棋エンジンコンパイル
    • 詰将棋エンジンをコンパイルするには以下
      • ENGINE_NAME に設定必要
      • YANEURAOU_EDITION は MATE_ENGINE だとリンク時にエラー発生
      • YANEURAOU_EDITION は TANUKI_MATE_ENGINE か YANEURAOU_ENGINE_MATERIAL なら ビルド可能
    • YANEURAOU_EDITION=TANUKI_MATE_ENGINE と設定するとtanuki詰将棋エンジンビルド
    ndk-build YANEURAOU_EDITION=TANUKI_MATE_ENGINE TARGET_ARCH_ABI=arm64-v8a ENGINE_NAME=Tanuki_MATE_arm64-v8a  clean # 最初にファイルクリア
    ndk-build YANEURAOU_EDITION=TANUKI_MATE_ENGINE TARGET_ARCH_ABI=arm64-v8a ENGINE_NAME=Tanuki_MATE_arm64-v8a  2>&1 | tee log_tanukimate001.txt # ビルド
    mkdir -p arm64-v8a/
    mv ../libs/arm64-v8a/Tanuki_MATE_arm64-v8a_arm64-v8a arm64-v8a/  # 消さないようにビルドしたバイナリを移動
    
  5. YaneuraOu詰将棋エンジンコンパイル
    • YANEURAOU_EDITION=YANEURAOU_ENGINE_MATERIALと設定するとYaneuraOu詰将棋エンジンビルド
    ndk-build YANEURAOU_EDITION=YANEURAOU_ENGINE_MATERIAL TARGET_ARCH_ABI=arm64-v8a ENGINE_NAME=YaneuraOu_MATE_arm64-v8a clean #  最初にファイルクリア
    ndk-build YANEURAOU_EDITION=YANEURAOU_ENGINE_MATERIAL TARGET_ARCH_ABI=arm64-v8a ENGINE_NAME=YaneuraOu_MATE_arm64-v8a 2>&1 | tee log_yanemate001.txt # ビルド
    mkdir -p arm64-v8a/
    mv ../libs/arm64-v8a/YaneuraOu_MATE_arm64-v8a_arm64-v8a  arm64-v8a/ # 消さないようにビルドしたバイナリを移動
    

7.3 動作確認

7.3.1 ビルドしたファイル転送

  • 動作確認するAndroid端末とUSB接続してから以下を実行
adb push arm64-v8a/* /data/local/tmp
# or
# adb push ./arm64-v8a/YaneuraOu_NNUE_arm64-v8a ./arm64-v8a/Tanuki_MATE_arm64-v8a_arm64-v8a ./arm64-v8a/YaneuraOu_MATE_arm64-v8a_arm64-v8a /data/local/tmp

7.3.2 実行

  1. tanuki詰将棋エンジンの実行
    adb shell /data/local/tmp/Tanuki_MATE_arm64-v8a_arm64-v8a 
    
  2. YaneuraOu詰将棋エンジンの実行
    adb shell /data/local/tmp/YaneuraOu_MATE_arm64-v8a_arm64-v8a 
    
  3. USIコマンド
    • 最初はこれをいれて、エンター
    usi
    
    • 次にこれをいれて、エンター
    isready
    
    • テスト用の盤面設定
    position lnsgkgsnl/1r5b1/ppp1+Ppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b N 1
    
    • 盤面確認(YaneuraOuさんソフト用のUSI拡張コマンド)
    d
    
    • 詰将棋解く (制限時間60秒 秒はmsec単位で与える。無制限の場合は infinite)
    go mate 60000
    
    • 終了
    quit
    

7.4 この章のまとめ

  • Android用のバイナリをクロスコンパイルしてみた。
  • 昔ダメだった、詰将棋エンジンのコンパイルと動作に成功した。(ダメだったのは、コンパイルオプションがまずかったのか、他の原因なのか調べてない)
    • コンパイル時の環境変数の設定を変更したら、最新版のソースで上手くいった
    • リリースバージョンのv4.88では詰将棋エンジン関係は未確認

8 今後

  • 今後も文書追加していきます。

9 この文書のチェンジログ

  • 2020/07/07 初版
  • 2021/01/19 Android用のYaneuraOuをビルド の章追加
  • 2021/05/17 Android用のYaneuraOuをビルド2 の章追加(最新バージョンのソースで、詰将棋エンジンのコンパイルと動作に成功)

著者: NM Max

Created: 2021-05-19 水 06:52

Validate

YaneuraOuさんの将棋ライブラリで楽しむ(2020バージョン)

YaneuraOuさんの将棋ライブラリで楽しむ(2020/7バージョン)

目次

1 概要

  • ここ数年YaneuraOuさんの将棋ライブラリを利用した将棋ソフトがコンピューター将棋大会で優勝
  • C++とアセンブラベース
  • Stockfishというチェスソフトをかなり取り込んだ作りになってるらしい
  • GitHubにてソース公開されている
  • バージョンによって使い方が相当変化している
    • 昔のバージョンに戻せば、過去の動画の使い方も出来る(今は同じ方法で同じように使えない)
    • スレッド等他のライブラリとの依存関係があり、使う難易度が高い
  • YaneuraOuさんの将棋ソフトのUbuntuへのインストール(2020/7 バージョン) という別文書とリンク部分とインストール部分はほぼ同じ

2 リンク

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で何故上手くいかず、こちらで上手くいったのか、原因は調べてない。(よくわかんない)
  • 関連動画

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を利用せずとも、平手に設定出来る方法わかるかたはコメントして教えて下さい

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 上のスクリプトで利用するバッチファイルの生成

  1. 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
    
  2. 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 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
  • 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 関係リンク

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 関係リンク

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 関係リンク

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 関係リンク

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コマンドを入れていく

  1. 最初は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
    
  2. 次はisreadyを入れる
    • 以下を入れてEnterキーを押す
    isready
    
    • 私の環境だと以下がかえってきた
    readyok
    
  3. 盤面を設定する
    • 以下を入れて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
    
  4. 詰将棋を探索させる
    go mate infinite
    
    • 私の環境だと以下がかえってきた
    info string pn 0 dn 100000000 nodes_searched 0
    info  time 1 nodes 0 nps 0 hashfull 0
    checkmate N*4c
    
  5. 平手で探索させて、詰まないことを確認
    • 平手に盤面を設定して、盤面表示
    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 関連リンク

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での操作

  1. 事前準備
    • usiにたいしてはusiokがかえってくればOK
    usi
    
    • isreadyにたいしてはreadyokがかえってくればOK
    • 評価関数ファイル nn.binが必要(デフォルトでは実行ディレクトリにあるevalディレクトリ無いに必要。option等で設定すれば他の場所でもいけるかも)
    • 定跡ファイルも必要かも
    • エラーがでて、readyokが帰ってこなければ、評価関数ファイルと、定跡ファイルを用意しましよう
    isready
    
  2. ゲーム開始
    usinewgame
    
  3. 盤面確認(YaneuraOuの将棋エンジン特有のUSI拡張命令 d を利用
    d
    
  4. 駒の移動1
    • 以下は飛車先の歩をすすめる
    position startpos moves 2g2f
    
  5. 将棋エンジンに手を考えさせる1
    • 動画では以下のgoコマンドで、bestmove 5a4b ponder 2f2eがかえってきてた
    • この時5a4bがベストと将棋エンジンが思考した手で、ponderの後の2f2eが相手の手の予想になります
    go
    
  6. 将棋エンジンに手を考えさせる2(先読みさせる)
    • 思考させた手と予想手を追加したposition命令を入れる
    position startpos moves 2g2f 5a4b 2f2e
    
    • dコマンドで盤面確認するとわかりやすくなる(他の将棋エンジンでは、このUSIコマンドは装備されてないかも)
    d
    
    1. 将棋エンジンの予想手が当たってたとき
      ponderhit
      
    2. 将棋エンジンの予想手が外れてた時
      • stopコマンドで思考を止めて
      stop
      
      • 実際に相手が行った手を入れる(ここでは6i7hとすると)
      position startpos moves 2g2f 5a4b 6i7h
      
      • その後に思考させる(思考させるまえにdコマンドで盤面確認した方がわかりやすい
      go
      
  7. 終了
    • 上の繰り返しを行って最後終わる時は
    quit
    

19.4 この章のまとめ

  • GUIを利用せずに、直接将棋エンジンとUSIプロトコルで対話して、対戦してみた
  • USIの理解をするのに、これをやってみるのは良い感じ

20 検討の時にどのようなUSIコマンドを使うべきか、将棋エンジンの設定について調べてみた

20.2 以下の操作を行っている動画


20.3 説明

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コマンドを使うべきか、将棋エンジンの設定について調べてみた の章追加

著者: NM Max

Created: 2021-01-21 木 06:12

Validate

UbuntuでYaneuraOuコンパイル

UbuntuでYaneuraOuコンパイル

1 概要

  • Ubuntu(Debianでもほぼ同じと予想される)でYaneuraOuコンパイル

2 リンク

3 YaneuraOu をコンパイル

  • ソースファイル群から実行ファイルを作成

3.1 以下の操作を行っている動画


3.2 事前準備

  • コンパイラとしてclangをインストール
sudo apt install clang

3.3 作業用のディレクトリ作成

mkdir YaneuraOu
cd YaneuraOu/

3.4 YaneuraOuのソースゲット

git clone https://github.com/yaneurao/YaneuraOu.git

3.4.1 ソースのバックアップ

  • バックアップファイルをYaneuraOu.20191009.tgzで保存
tar cvzf YaneuraOu.20191009.tgz YaneuraOu/

3.5 CPUの命令セットの確認

  • 以下のコマンドを実行し、/proc/cpuinfoに含まれる命令セットに、使いたい命令セットが含まれているか確認。含まれているなら、希望の文字列が含まれた行が表示されるはずなので、出力を確認して、希望の命令セットが含まれるか確認。
  • avx5系かどうか?
grep -i avx5 /proc/cpuinfo
  • avx2系かどうか?
grep -i avx2 /proc/cpuinfo
  • sse42系かどうか?
grep -i sse4 /proc/cpuinfo

3.6 ソースディレクトリに移動

cd YaneuraOu/source/

3.7 必用ならMakefileを変更

  • 私のCPUセットはsse42なので、TARGET_CPU = SSE42 をコメントアウトして、CPUの命令セットを SSE42にした。使うマシンのCPUによっては変更の必用無い場合もある。
vi Makefile 

3.8 ビルド

  • 以下の命令で上手くエラーなくコンパイル出来ればOK
  • YaneuraOu-by-gcc というファイルが Makefileのあるフォルダに作成される。これが実行ファイル
  • YaneuraOu-by-gcc は将棋用のプロトコルと標準入力や出力でやりとりするソフトなので、これ単体で将棋を楽しむのはしんどいので、人間と将棋エンジンとの間をとりもってくれるソフトを利用して使う。
make

4 今後

  • 今後も文書追加していきます。

5 この文書のチェンジログ

  • 2019/12/12 初版

I

著者: NM Max

Created: 2019-12-12 木 12:05

Validate

将棋ウォーズでようやく勝てました。

3分切れ負けを4度くらいやったのですが、全部時間が足らずに負けました。

10分切れ負けにしたのですが、それでも負けて1度詰みまでいってたのに、金を打つべきところを角を打ってしまって、その後に逆転負け。

その後ようやく勝てて、内容は非常に悪かったけど。

最初に操作ミスで、飛車を歩の真ん前に移動してまって、いきなり飛車落ち状態になってしまって。その後色々ミスしたけど、相手の方もミスしてくれてなんとか勝てました。

以下が棋譜。リツートしてやるとこのURLを貰えるみたい。(リツイートしなくてももらえるのかもしれないけど、やり方まだわかってない)

https://kif-pona.heroz.jp/games/pano1-TheRyouta0731-20190528_174922?tw=1

動画にしようとしたのですが、よくよく考えると、将棋ウォーズのIDがまずかった。変更しようとしましたが、どうやら変更は不可能なようで、一旦上のIDを消すために、一旦大会して、再度登録しなおしました。

何度も繰り返すとブラックリスト入りして、復活不可能になるそうです。

新しいID一発目の将棋の棋譜が以下になります。

https://kif-pona.heroz.jp/games/NM_Max_game-Zaqwsxcderfvbgt-20190528_190938?tw=1

正直勝てないとおもったのですが、(相手の方の段位が5級だったので)

将棋下手で、将棋実況やってる人いないので、こっちもやってみることにします。

Youtube動画は以下になります。(将棋ウォーズで初勝利)

以下がIDを変更後の初勝利の動画になります。