昨日のエントリーでは「将棋盤をメモリ上にどう持つか」「駒を数で扱うために」の二点を説明しました。
んで今回は「駒をどう動かすか」の説明になります。
まず
1:行き先が駒の働きと合っているか(歩なら前に一歩、金なら六方向)
2:盤の端より先に行こうとしていないか(行列の特性上、インデックス値が駒の左端と上の行の右端が連番で繋がっているため、上下左右の端であるチェックが必要)
3:行き先が自分の駒ならそこには進めない
4:行き先が相手の駒なら取って手駒とする(手駒の構造は説明がまだでしたね)
5;香車、飛車、角の場合、飛び利きが自分の駒の手前、相手の駒の位置で切れる
これらの処理はいちばん簡単な実装で行くと、IF~ELSEで全部書く!初期の将棋ベーシックはそうでした。
それから、もう少しスマートな実装、事前計算テーブルとビットボードを使うように改変して来ました。ほとんど趣味の領域です。メモリの少ない昔のコンピュータ将棋では必須であったかもですが、ウインドウズマシンですので、IF~ELSEで全部書くのと結果として計算速度も大差はありませんでした。
ただまあ、やったらやったなりに、積み重ねで少しは速くなっていますが、思考部から計算で出る手と定跡部から1局面1手のテーブルを引いた手では、30秒から数分と、コンマ数秒の違いがあり、指し手が早いと感じるコンピュータ将棋は基本は定跡によって速いだけで、思考部の改良というアプローチは趣味です。
勝負においても定跡が大切で、思考部を通ること自体が作戦からすると少なくとも定跡の作戦からは外されたという事になります。論理的に定跡だけで勝つのが最善手だとすると、定跡から外れた以上は最善ではなく勝ち筋がある、と考えるのも分かりますが、定跡の最善が最善たるゆえんもハッキリしませんし、外れたら定跡が無いわけで、しらみつぶしの定跡が手続き上難しい以上は、思考部は思考部でそれなりの広がりがあるわけです。
とはいえ、ちょっと将棋を遊びたいだけの時にコンピュータが何時間も考えて突っ張るのは考えものですので、市販の将棋ベーシック改では反復3手読みで探索を打ち切ります。もちろん、将棋ソフト同士の対局も持ち時間がありますので無限に考えるわけではなく、どこかで探索を打ち切っています。VBでは遅いかな、とも思いましtが、ポナンザはC#でも優勝していますから、定跡をしっかり作れば遅い言語でも勝てたようです。
定跡を使うなら、合法手生成という思考部のためのアプローチではなく、定跡の手が合法手なら問題ないわけで、すっ飛ばしてもよいプロセスかも知れません。
それでも将棋ベーシック改の仕様が知りたくて、ソースコードを読んでも分からない、という変わった人がいたら、多分もう何らかSNSかメールでお問い合わせをいただいているとは思います。直接絡むほどではないけど、なんとなく読みたい、くらいの方に向けて書いているのです。