今日の予定
早くに帰って来れたんで、今日は少し開発する事にします。
…が、その前に復習も兼ねて*1将棋盤の各マスの表現方法について書いてみます。
まず、1マスの情報はsigned char型の変数一個に詰め込みます。実際のビット配置はこんな感じ。
7・6 | 5 | 4 | 3 | 2〜0 |
---|---|---|---|---|
未使用 | 先手が移動可(1)か否(0)か | 後手が移動可(1)か否(0)か | 成(1)・不成(0) | 生駒の駒種 |
4・5ビット目ですが、具体的にビットパターンとその意味はこういう風になります。
意味 | 5 | 4 |
---|---|---|
壁 | 0 | 0 |
先手の駒 | 0 | 1 |
後手の駒 | 1 | 0 |
空きマス | 1 | 1 |
こうすると何が嬉しいかというと、特定のマスに先手(後手)の駒が移動可能か否かを求めるのが、ビット演算だけで求まります。
以下、GA将!!!!!!のソースから抜粋。
// squareInfoがマス情報、playerが移動する駒の手番(先手なら0、後手なら1)。 bool lib::shogi::isMovable( const SquareInfo squareInfo, const Player player ) { return ( squareInfo & ( 1 << ( 5 - player ) ) ) != 0; }// isMovable(...)
例えば先手の駒が移動する場合だと、5ビット目が1なら(後手の駒か空きマスなら)移動可能、そうでなければ移動不可能です。
んで、その判定を引き算・シフト演算・論理積と比較で実現可能です。
それからもう一つ、0〜2ビット目の「生駒の駒種」ですが、桂馬(0)・歩(1)・香車(2)・銀(3)・金(4)・角(5)・飛車(6)・王(7)という風にしています。
手生成時に敵陣1段目の歩・香車・桂馬や敵陣2段目の桂馬は非合法なので、その判定が必要です。
んで、桂馬が0で歩・香車が1・2だと「敵陣1段目は3以上の駒が合法」「敵陣2段目は1以上の駒が合法」と判定出来るので、コードが少し*2スッキリします。
GA将でやってる工夫は大体こんな感じで、他は何の工夫も面白みも無い構成です。
…さて、それでは実装に移りますか。