駒選択時の処理 ~駒クリック時の挙動を整理する~

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

駒台が実装できた勢いにのって、コーディングを進めたい。現状のプログラムだと、駒クリック時には、その駒が問答無用で1マス進む……という実装になっているので、ここを将棋らしくしたい。

将棋を指す時の動作を参考にする

実際に将棋を指す時の動作をイメージしてみよう。

  1. 駒を持つ
  2. 駒を移動可能な升目に置く

というパターンを基本とするが、

  1. 駒を持つ
  2. 駒を移動可能な升目に置く
  3. 移動先の升目にあった相手の駒を自分の駒台に乗せる

というパターン(※)もある。

※厳密な所作としては、マナー違反だが、これはプログラム上の話だと理解してほしい。本来は、移動先の升目の駒を駒台に乗せてから、駒を移動させるのが正しい所作なわけだが。

更には、

  1. 駒を持つ
  2. その駒を放す
  3. 別の駒を持つ
  4. 指し手に迷って、やっぱり駒を放す

という場合もあるかと思う。

つまり、「駒を持つ」という動作と「駒を放す」という動作をプログラム上で表現する必要があるわけだ。

駒を選択中かどうかを保持する

Selectedという変数で、今、どの駒を選択中か……という情報を管理したい。更には、つまみ上げたその駒を好き勝手に移動させる訳にはいかないので、選択中の駒の可動域もこの時に併せて判定しておきたい。

そして、駒選択中に、稼動域がクリックされたら、駒を移動させる処理を呼ぶような実装としたい。Selected変数で管理するだけでなく、ユーザ目線で、どの駒が選択中であるのかが判別できるように、その駒の背景画像も変更するとよさそうだ。

  • 駒クリック
    • 選択された駒か?
      • Yes → 選択解除(背景画像のクリア&可動域の解除)
      • No  → 選択処理(駒背景画像の変更&可動域の判定)
  • 可動域クリック
    • 駒移動処理
      • 移動先の駒を持ち駒に追加
      • 駒の移動

駒選択時の背景画像変更だけ、実装してみた。

selectedPiece_yokofu

もともとは、背景色を”#ff0000”に変更していたのだが、背景色の変更は目に痛い。半透明の透過画像を用意し、背景画像を差し替えるといい感じだ。

プログラムコード

盤上に配置済みのノードに対して、直接、背景画像を差替える操作はできない。なので、再度、ノードのクローンを作り、背景画像を設定した上で、replaceNode関数を使い、対象のノードを置き換えるロジックとなる。

以下のような感じだ。

 var showBoard = function() {
  var b = document.getElementById("board");
  while(b.firstChild) {
    b.removeChild(b.firstChild);
  }

  for(var i = 11; i <= 99; i++){

    var c = piece[board[i]].cloneNode(true);
    var x = file(i);
    var y = rank(i);

    c.style.left = (30+(x-1) * 60) + "px";
    c.style.top = (30+(y-1) * 64) + "px";		

      (function(){
        var _i = i;
        c.onclick = function(){
          if(board[_i] != EMPTY){
            var e = b.childNodes[_i-11].cloneNode(true);
            e.style.backgroundImage = "url('./images/selected.png')";
            b.replaceChild(e, b.childNodes[_i-11]);
//	    movePiece(board[_i],_i);
          };
        };
      })();

    b.appendChild(c);

  }
};

cloneNodeする対象を探すのに、盤配列のインデックスをそのまま使えないのが不便なので、ここは別の実装方法も考えた方がよいかもしれない。

前述した実装方針と併せて、後でリファクタリングする中で改善したい。