駒選択時の処理 ~手番の駒の時だけ選択する~

この記事の所要時間は約 5 分 です。

前回の記事にて、駒クリック時の挙動を整理した。

改めて、これを実装していくわけだが、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が渡る。

selectedPiece_yokofu_2

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関数を考えてみたいが、だいぶソースコードが汚れてきたので、その前に、リファクタリングの時間も取りたい。