5.1 パターン更新も含めた着手 |
本章ではパターン状態の更新を着手時に行なうようにします。
これまでは評価関数の中でパターンの抽出を行なっていましたが、
今後はBoardの内部で各パターンの状態を保持しておき、1手打つ毎に状態の更新を行ないます。
評価関数ではBoardが保持しているパターンの状態を参照するだけにします。
1手で変更されるパターンの数は少ないので、全パターンの状態を計算するよりも少ない時間で局面評価を行なえるようになります。
最初に必要な定数を定義します。
"board.h"にパターンIDを定義します。
これはBoardクラスにパターンの状態を問い合わせるときに使用します。
例えば辺のパターンの状態を知りたかったら、PATTERN_ID_EDGE8_1〜PATTERN_ID_EDGE8_8を使用します。
/* パターンID */ #define PATTERN_ID_LINE4_1 0 #define PATTERN_ID_LINE4_2 1 #define PATTERN_ID_LINE4_3 2 #define PATTERN_ID_LINE4_4 3 #define PATTERN_ID_LINE3_1 4 #define PATTERN_ID_LINE3_2 5 #define PATTERN_ID_LINE3_3 6 #define PATTERN_ID_LINE3_4 7 #define PATTERN_ID_LINE2_1 8 #define PATTERN_ID_LINE2_2 9 #define PATTERN_ID_LINE2_3 10 #define PATTERN_ID_LINE2_4 11 #define PATTERN_ID_DIAG8_1 12 #define PATTERN_ID_DIAG8_2 13 #define PATTERN_ID_DIAG7_1 14 #define PATTERN_ID_DIAG7_2 15 #define PATTERN_ID_DIAG7_3 16 #define PATTERN_ID_DIAG7_4 17 #define PATTERN_ID_DIAG6_1 18 #define PATTERN_ID_DIAG6_2 19 #define PATTERN_ID_DIAG6_3 20 #define PATTERN_ID_DIAG6_4 21 #define PATTERN_ID_DIAG5_1 22 #define PATTERN_ID_DIAG5_2 23 #define PATTERN_ID_DIAG5_3 24 #define PATTERN_ID_DIAG5_4 25 #define PATTERN_ID_DIAG4_1 26 #define PATTERN_ID_DIAG4_2 27 #define PATTERN_ID_DIAG4_3 28 #define PATTERN_ID_DIAG4_4 29 #define PATTERN_ID_EDGE8_1 30 #define PATTERN_ID_EDGE8_2 31 #define PATTERN_ID_EDGE8_3 32 #define PATTERN_ID_EDGE8_4 33 #define PATTERN_ID_EDGE8_5 34 #define PATTERN_ID_EDGE8_6 35 #define PATTERN_ID_EDGE8_7 36 #define PATTERN_ID_EDGE8_8 37 #define PATTERN_ID_CORNER8_1 38 #define PATTERN_ID_CORNER8_2 39 #define PATTERN_ID_CORNER8_3 40 #define PATTERN_ID_CORNER8_4 41 #define NUM_PATTERN_ID 42
次に関数の追加を行ないます。
パターンの初期化関数、取得関数、着手と同時にパターン更新を行なう関数を追加します。
Boardクラスが保持しているパターン状態の初期化を行ないます。
後述しますが保持しているパターン状態は必ずしも正しいわけではありません。
パターン取得を行なう前にこの関数を呼ぶ必要があります。
引数
self : Boardクラスへのポインタ
戻り値 なし
指定したパターンの状態を取得します。
引数
self : Boardクラスへのポインタ
in_id : 状態を取得するパターンID
戻り値 パターン状態
パターン更新を行なう着手関数です。
引数
self : Boardクラスへのポインタ
in_color : 着手する石の色
in_pos : 着手するマスの位置
戻り値 着手できた場合には返した石の数(着手したマスの石は数に含まない)。着手できない場合には0
パターン更新を行いながら1手戻します
引数
self : Boardクラスへのポインタ
戻り値 直前の手によって返した石の数(着手したマスの石は数に含まない)。盤面が初期状態の場合には0を返す
今回の修正によって、着手と1手戻す処理をそれぞれ2種類の関数で行なえるようになりました。
それぞれは対になっていて、以下に注意しなければなりません。
これを守らないとBoardで保持しているパターン状態の整合がとれなくなります。
またBoard_Flip()を呼び出した後には正しいパターン状態の取得はできません。
Board_Flip()ではパターン状態の更新は行なわないためです。
ただし、Board_Flip()を数回呼び出した後、同じ回数だけBoard_Unflip()を呼び出した場合にはパターン状態の取得が可能です。
探索と局面評価時には以上の点に注意してください。