前回までの記事で、「将棋盤の初期配置を実装する」と「駒クリック時のイベントを実装する」において、将棋盤UI実装のスタートラインに立った。
ただ、その後、いくつかのアイデアが浮かんだので、これを忘れないうちにメモしておきたい。方針レベルの話は、コーディングを進める前に変更しておかないと、後からだと手戻りが大きい。
MovePiece関数の挙動に関するメモ
movePiece関数の挙動について、少し考え始めているわけだが、移動元座標と移動先座標、駒種別を渡し、1)移動可能かどうかを判定する、2)移動可能であれば、移動先の駒を取って、駒台に置く、3)移動先が相手の陣地であれば、成るかどうかの判定をする等、やるべきことは多い。
— T.Shimizu (@43memo_com) 2016年8月28日
なお、成るかどうかの判定については、強制的に成らないといけない場合もあるため、実は、そんなに単純ではない。駒が歩、香、桂だった場合の対応が必要となるわけだ。
— T.Shimizu (@43memo_com) 2016年8月28日
次にコーディングするべきは、MovePiece関数だと思っていたので、前回の記事執筆後に仕様をメモっていた。ただ、よくよく考えると、駒をクリックした時に、いきなり駒移動はしないわけで、駒クリック時に呼び出されるべき処理は、その駒の可動域判定だろう。
局面を一次配列で保持するアイデア
思いついたことは、一旦、Twitterに公開状態でメモる。将棋盤UIの実装において、局面情報をsfen形式で入出力するのであれば、盤面の情報は、二次配列ではなくて、一次配列に格納した方が良さそうだ……ということに気が付いた。
— T.Shimizu (@43memo_com) 2016年8月29日
ちなみに、盤外かどうかを判定するために、9×9の81マスだけではなく、その周囲の壁も升目と同様にプログラム上は実装しておくべきかもしれない。そして、その壁にあたる升目には、自駒も敵駒も移動できないように、番兵とも言うべきダミーの駒情報を配置しておくのが、実際的なアイデアだ。
番兵データを扱いやすくするために
あ。もしかして、駒データは、2進数で考えた方がビットで自駒か敵駒かの判断ができて便利だったりするのだろうか。と気が付いた。
— T.Shimizu (@43memo_com) 2016年8月29日
歩香桂銀金角飛玉に1から8までの数字を割り当てて、成り駒には、各々、8を加算する。敵駒には16を加算すると、自駒は5ビット目が0に、敵駒は1になる。そういうことなのかな。
— T.Shimizu (@43memo_com) 2016年8月29日
駒データを2進で考える意味としては、自駒か敵駒かについて、5ビット目を見ると良い……というのもあるが、もう少し、別のアイデアもありそうだ。
— T.Shimizu (@43memo_com) 2016年8月29日
歩香桂銀金角飛玉に1から8を割り当てて、成り駒には、各々8を加算……までは、先のツイートと同様。自駒には16を加算し、敵駒に32を加算すると、5ビット目が1なら自駒、6ビット目が1なら敵駒、ということになりそう。こちらの方がビットの旨味を活かせそうだ。
— T.Shimizu (@43memo_com) 2016年8月29日
駒移動の際に、移動先に味方の駒がいたら移動できないわけで、自駒の移動は5ビット目で判定。敵駒の移動は6ビット目で判定。そして、盤外の升目には、全て48を入れておくことで、自駒も敵駒も移動できないように判定させる方法がある。
— T.Shimizu (@43memo_com) 2016年8月29日
移動先が壁かどうかの判定と移動先に味方の駒がいるかどうかの判定が一回のロジックで実装できるのが心地よい気がする。
— T.Shimizu (@43memo_com) 2016年8月29日
これは、上記のツイートの通りの内容だ。前述した盤の外側にダミーの升目を実装し、そこには、自駒でも敵駒でもない番兵駒(2進だと”110000″、10進だと”48″)を配置しておく。
自駒であれば、移動先に自駒がいると移動できないわけだが、この判定は、5ビット目が”1″かどうかで判定する。敵駒も、移動先に敵駒がいる場合には移動できず、これは、6ビット目で判定することになる。
というわけで、番兵駒として”48″を配置しておいて、これで判断すると、自駒でも敵駒でもそこには移動できなくなるわけで、可動域を計算するロジックが単純化される。
というわけで、このあたりの実装をしてから、次のステップに進みたい。
コメント