本将棋のサブセットである「5五将棋」のAIを ちょろちょろ書いている, 気づいたことをメモしておく.
データ構造
それぞれの駒をビットボードで管理している. 例えば先手の歩が7番目の位置に存在すれば,bitboard[B_PAWN] = 0x40 のように表す. 飛車および角の効きはAVX2の_pext_u32命令を使い導出する[5].
探索方針
基本はアルファベータ法で探索する. それに加えて,合法手をソーティングしつつ,反復深化させる. また,同一局面が現れた場合は,置換表を用いてalpha-betaのウィンドウ幅を狭める. Null-Window(PVS)探索も試してみたが,対して速くならなかった.むしろ遅い場合もある. 多分ソーティング方法が悪い.
評価関数
単純に駒の損得だけで評価している. 改善が必須.
USI(Universal Shogi Interface)プロトコル
将棋GUIソフト[8]とAIを接続するプロトコルの1つがUSIである[6,7]. AIは,GUIソフトから局面や持ち時間を受け取り,決定した指し手を返す. とりあえず対応させた.
OpenMPによる並列化
探索はOpenMPを使って並列化している. 与えられた局面の合法手をそれぞれ並列に探索する. 出来るだけ静的にリンクしたいので,ちょっと調べてみた.
- visual c++
- 構成プロパティ - C/C++ - 言語 - OpenMPのサポートを「はい」にする
- 構成プロパティ - C/C++ - コード生成 - ランタイムライブラリを「マルチスレッド(/MT)」にする
- VCOMP{90,100,110,120}.dllに依存する
- VCOMP{90,100,110,120}.dllは,/MTを設定しても動的にリンクされるため, どこかで配布されているものを使ってみようかな[1,2].
- gcc
- libcompに依存するが,静的リンクする方法はあるみたい[4].
- intel compiler
- libiomp5m.libを静的リンクすることができるらしい[2].
- 静的リンクは非推奨らしいが,-openmp-link staticオプションを付けると良いみたい(icpc -openmp -openmp-link static hello.cpp)[3].
参考
- [1] Stack Overflow, Is there a way to load in omp.h at compile time, therefore a machine never needs to fetch it at run time?
- [2] Visual Studio UserVoice site, Statically link openmp (vcomp*.dll)
- [3] Intel® C++ Compiler XE 13.1 User and Reference Guide - Using the OpenMP* Libraries
- [4] Stack Overflow, How to link libgomp statically when linking other libraries dynamically?
- [5] インテル C++ コンパイラー 14.0 ユーザー・リファレンス・ガイド - _pext_u32/64
- [6] 将棋所
- [7] The Universal Shogi Interface
- [8] プチ将棋の使い方