一次元配列による将棋盤表現の実装と棋譜出力関数の素

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

将棋盤をプログラム上で表現する上でのアイデア」の記事の中で言及した一次元配列による盤の表現を実際のプログラムコードに落としてみた。

肝は、配列のインデックスを盤の段筋に変換する部分だが、このあたりは、除算演算子と剰余演算子を使用すれば、特に難しくはない。

コードは以下のような感じだ。

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){
            movePiece(board[_i],_i);
          };
        };
      })();
    b.appendChild(c);
  }
};

rank関数とfile関数

rank関数とfile関数は、盤配列のインデックスを段と筋を表す数字に変換する役割を担う。

var file = function(_i) {
  return _i%10;
};

var rank = function(_i) {
  return (_i-_i%10)/10;
};

returnされるのは、x座標とy座標だ。

棋譜出力関数

前回までは、kazu2file関数、kazu2rank関数、kazu2koma関数という各座標と駒情報を棋譜の譜号用に変換する仕組みを準備していたが、実際、これらの関数の用途は、あくまで表示用であり、棋譜出力にしか用いられることはなさそうだ。

というわけで、これらの関数は、棋譜出力関数に置き換えてしまう。

var outputKifu = function(_i) {	

  var kazu2koma={
    1:"歩", 2:"香", 3:"桂", 4:"銀", 5:"金", 6:"角", 7:"飛", 8:"王",
    9:"と",10:"杏",11:"圭",12:"全",13:"",14:"馬",15:"龍",16:"",
    17:"歩", 18:"香",19:"桂",20:"銀", 21:"金",22:"角", 23:"飛",24:"王",
    25:"と",26:"杏",27:"圭",28:"全",29:"",30:"馬",31:"龍",32:""
  };

  var kazu2file={
    1:"9", 2:"8", 3:"7", 4:"6", 5:"5", 6:"4", 7:"3", 8:"2",	9:"1"
  };

  var kazu2rank={
    1:"一", 2:"二", 3:"三", 4:"四", 5:"五", 6:"六", 7:"七", 8:"八",	9:"九"
  };

  return (kazu2file[file(_i)] + kazu2rank[rank(_i)] + kazu2koma[board[_i]]);
};

もう少し、ロジックをすっきり書けないものか!?という気もするが、暫定版としては、これでいいだろう。

この関数をmovePiece関数の中に埋め込む。

var movePiece = function(_koma,_i) {
  board[_i] = EMPTY;
  if(_koma <= ENEMY){
    board[_i-10] = _koma;
    console.log(outputKifu(_i-10));
  }else{
    board[_i+10] = _koma;
    console.log(outputKifu(_i+10));
  };
  showBoard();
};

試しに挙動を確認してみる。

outputKifu_Banmen

この盤面までで、出力されたログが下記のような感じ。

outputKifu_console

無事に棋譜が出力されているようだが、難点が残っており、これだけだと、「同歩」のような記録や「5二金右」のような譜号は出力できない。ここは次回以降の課題だ。

次に取り組むべき課題はなにか?

叩き台としては、クリックすると駒が1マス進む!という動きが表現できたので、一旦、満足してもよいのではないだろうか?もっとも、駒移動においては、移動先に敵駒がいた場合には、相手の駒を自分の駒台に置く……といった処理も実装する必要があり、まだ、やるべきことは多い。

とりあえず、このあたりは、駒台上に駒を表示することができるようになってから、改めて取り組んでみたい。

次回、やってみたいことを列挙してみる。

  1. 盤面情報のSFEN形式での入出力
  2. 駒をクリックした際に可動範囲を表示する実装
  3. 駒移動時の強制成りなどの判定

ここまで書いて気がついたわけだけれど、最低限、成不成の選択ボックスなども用意しないと将棋盤としては使い物にならなさそうだ。

先は長い。