前回の記事にて、駒クリック時の挙動を整理した。
改めて、これを実装していくわけだが、replaceNode時に置き換えるノードに対して付加するonclick時の処理を工夫することで、駒の選択と選択解除がきれいに実装できそうだと考えた。
手番の時だけ処理をする
先手番の時には、先手の駒だけを……後手番の時には、後手の駒だけを選択できるようにするために、手番を保持する変数”turn”を定義する。
var turn = "b";
「b」は、blackの略で、すなわち、”先手”を意味する。後手の場合は、whiteで「w」となる。この変数”turn”は、movePiece関数内の処理で変更することを想定している。(今回は、movePieceの実装までは辿り着かないため、これは次回以降のテーマとする)
この変数”turn”を用いた判定を実施し、その結果によって、駒クリック時の挙動を調整する。
以下は、showBoard関数の中に記述した駒要素のonclickイベント時の処理だ。
(function(){ var _i = i; c.onclick = function(){ if(board[_i] !== EMPTY){ if(turn ==="b"){ selectPiece(_i,board[_i] < ENEMY); }else{ selectPiece(_i,board[_i] > ENEMY); } }else{ selectPiece(_i,false); }; }; })();
selectPiece関数は、駒の選択状態を管理するための関数であり、1つ目の引数には「盤上のインデックス」を設定、2つ目の引数には「選択処理をするか否か」を設定する。
手番が”b”の場合は、クリックされた駒が先手の駒の場合のみ、2つ目の引数にtrueが渡る。手番が”b”以外の場合は、後手の駒の場合のみ、trueとなる。そもそもクリックされた升目が空(”EMPTY”)だった場合には、どんな場合でもfalseが渡る。
selectPiece関数の実装
コードを以下の通りに載せる。
var selectPiece = function(_i,mode) { var b = document.getElementById("board"); var c; //選択中の駒の初期化処理 if(selectedPiece){ c = b.childNodes[selectedPiece - 11].cloneNode(true); c.style.backgroundImage = "url('')"; (function(){ var _s = selectedPiece; c.onclick = function(){ selectPiece(_s,true); }; })(); b.replaceChild(c, b.childNodes[selectedPiece-11]); selectedPiece = EMPTY; }; //手番の駒の時だけ、駒選択処理 if(mode){ c = b.childNodes[_i-11].cloneNode(true); c.style.backgroundImage = "url('./images/selected.png')"; (function(){ var _j = _i; c.onclick = function(){ selectPiece(_j,false); } })(); b.replaceChild(c, b.childNodes[_i-11]); setCanMove(_i); selectedPiece = _i; } };
ここでも、クロージャが大事だ。この関数の中では、まず、選択中の駒を非選択状態に戻す処理を記述しており、その後、第2引数にtrueが入ってきた場合のみ、駒選択時の処理を行う。
setCanMove関数は、引数として、インデックスを渡し、駒の移動できる範囲を判定するためのものだ。現在は未実装なので、コンソールにログを出力する処理だけを埋めてある。
とりあえず、上記のロジックだと、selectPiece関数は、盤上の駒にしか反応しないが、引数の数を増やして、盤ノードや駒台ノードを指定して渡せるようにすれば、駒台上の駒選択についても、処理できるようになるはずだ。(この部分は、上記の応用例なので、割愛する。)
次は、setCanMove関数を考えてみたいが、だいぶソースコードが汚れてきたので、その前に、リファクタリングの時間も取りたい。
コメント