将棋UI実装への道 ~将棋盤の初期配置を実装する~

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

前回の記事で試したオセロの実装例を参考に将棋盤を作ってみたので、気になったところを述べてみる。

オセロを実装する上で参考になる動画を見つけた
前回記事の続きである。 目指しているのは、将棋盤のUIをJavaScriptで実装することなのだが、まずは、ルールが単純な...

なお、駒と将棋盤の画像は、以下のものをダウンロードして使用させてもらった。

駒を数値と配列で定義する

駒の定義については、以下のサイトを参考に自分の駒(歩から玉まで)を数値(1~8)で定義した後、それぞれの成駒(と~龍)については、元の定義に8加算した数字で定義。敵の駒については、通常の駒も成駒も、それぞれに16を加算した数字で定義する。

var PROMOTED = 8;
var ENEMY = 16;

var EMPTY = 0;
var FU = 1;
var KY = 2;
var KE = 3;
var GI = 4;
var KI = 5;
var KA = 6;
var HI = 7;
var OU = 8;

var TO = PROMOTED + FU;
var NY = PROMOTED + KY;
var NK = PROMOTED + KE;
var NG = PROMOTED + GI;
var UM = PROMOTED + KA;
var RY = PROMOTED + HI;

var EFU = ENEMY + FU;
var EKY = ENEMY + KY;
var EKE = ENEMY + KE;
var EGI = ENEMY + GI;
var EKI = ENEMY + KI;
var EKA = ENEMY + KA;
var EHI = ENEMY + HI;
var EOU = ENEMY + OU;
var ETO = ENEMY + TO;
var ENY = ENEMY + NY;
var ENK = ENEMY + NK;
var ENG = ENEMY + NG;
var EUM = ENEMY + UM;
var ERY = ENEMY + RY;

リンク先のページでは、自分の駒を判別するために、”SELF”という定数を定義し、各駒に”SELF”を足しているが、その意味合いが理解できなかったため、一旦、 ここは省略した。

ここで定義された駒の定数を用いて、将棋盤UIで表示される画像を判別していくことになる。

piece = [
document.getElementById("cell"),
document.getElementById("FU"),
document.getElementById("KY"),
document.getElementById("KE"),
document.getElementById("GI"),
document.getElementById("KI"),
document.getElementById("KA"),
document.getElementById("HI"),
document.getElementById("OU"),
document.getElementById("TO"),
document.getElementById("NY"),
document.getElementById("NK"),
document.getElementById("NG"),
document.getElementById("cell"),
document.getElementById("UM"),
document.getElementById("RY"),
document.getElementById("cell"),
document.getElementById("EFU"),
document.getElementById("EKY"),
document.getElementById("EKE"),
document.getElementById("EGI"),
document.getElementById("EKI"),
document.getElementById("EKA"),
document.getElementById("EHI"),
document.getElementById("EOU"),
document.getElementById("ETO"),
document.getElementById("ENY"),
document.getElementById("ENK"),
document.getElementById("ENG"),
document.getElementById("cell"),
document.getElementById("EUM"),
document.getElementById("ERY")
];

駒画像については、オセロで実装したのと同様にスタイルで非表示にした要素の中に格納したものを”document.getElementById”で取得してくるようにコーディングする。

ちなみにHTML側は、下記のような感じだ。

<div style="display:none">
 <div id="cell" style="position:absolute;">
  <img style="position:relative;" src="images/blank.png"></img>
 </div>
 <div id="FU" style="position:absolute;">
  <img style="position:relative;" src="images/FU.png"></img>
 </div>
 <div id="KY" style="position:absolute;">
  <img style="position:relative;" src="images/KY.png"></img>
 </div>
 <div id="KE" style="position:absolute;">
  <img style="position:relative" src="images/KE.png"></img>
 </div>
~
 <div id="ERY" style="position:absolute;">
  <img style="position:relative" src="images/ERY.png"></img>
 </div>
</div>

 将棋盤の初期配置を定義する

前述の将棋駒の定義ができたので、以下の要領で、将棋の初期配置を定義する。

boardの二重配列に、どの駒がどの升目に入っているかを設定しておく。

  for(var i = 0; i <= 9 ; i++) {
    board[i]=[];
    for(var j = 0; j <= 9; j++) {
    board[i][j]=0;
    }
  }
  board[9][1] = EKY;
  board[8][1] = EKE;
  board[7][1] = EGI;
  board[6][1] = EKI;
  board[5][1] = EOU;
  board[4][1] = EKI;
  board[3][1] = EGI;
  board[2][1] = EKE;
  board[1][1] = EKY;

  board[2][2] = EHI;
  board[8][2] = EKA;

  board[1][3] = EFU;
  board[2][3] = EFU;
  board[3][3] = EFU;
  board[4][3] = EFU;
  board[5][3] = EFU;
  board[6][3] = EFU;
  board[7][3] = EFU;
  board[8][3] = EFU;
  board[9][3] = EFU;
  
  board[9][9] = KY;
  board[8][9] = KE;
  board[7][9] = GI;
  board[6][9] = KI;
  board[5][9] = OU;
  board[4][9] = KI;
  board[3][9] = GI;
  board[2][9] = KE;
  board[1][9] = KY;

  board[2][8] = KA;
  board[8][8] = HI;
  
  board[1][7] = FU;
  board[2][7] = FU;
  board[3][7] = FU;
  board[4][7] = FU;
  board[5][7] = FU;
  board[6][7] = FU;
  board[7][7] = FU;
  board[8][7] = FU;
  board[9][7] = FU;

  showBoard();
};

最後にコールしている”showBoard”関数が、このboard配列を元に、将棋盤の上の駒画像を表示するためのものだ。今後の駒の移動も、このboard配列の中を変更し、showBoard関数を呼ぶことで実装するつもりだ。

将棋盤の初期配置を表示する

というわけで、showBoard関数の中身はこんな感じだ。

var showBoard = function() {
  var b = document.getElementById("board");
  while(b.firstChild) {
    b.removeChild(b.firstChild);
  }
  for(var y = 1; y <= 9; y++){
  for(var x = 1; x <= 9; x++){
    var c = piece[board[x][y]].cloneNode(true);
    c.style.left = (30+(x-1) * 60) + "px";
    c.style.top = (30+(y-1) * 64) + "px";		
    b.appendChild(c);
  }
  }
};

オセロの実装例だと、この時にクローンノードされた”石”要素にクリック時のイベントを付加していたが、これに相当するロジックは、次回以降にしたい。

まずは、このコードで実行してみる。

Shogi-Board

無事に表示された。ちなみに、これがきれいに表示されるまでに、前述のshowBoard関数の位置調整しているpixel数の部分を何度か微調整した。

クリックイベントの定義は次回に

さて、各々の駒ノードにクリックイベントを付加してみたのだが、表示された将棋盤のどの駒をクリックしたときも、「10:10」とログに出力された。

var showBoard = function() {
  var b = document.getElementById("board");
  while(b.firstChild) {
    b.removeChild(b.firstChild);
  }
  for(var y = 1; y <= 9; y++){
  for(var x = 1; x <= 9; x++){
    var c = piece[board[x][y]].cloneNode(true);
    c.style.left = (30+(x-1) * 60) + "px";
    c.style.top = (30+(y-1) * 64) + "px";		
    c.onclick = function(){
   		console.log(x + ":" + y);
    };
    b.appendChild(c);
  }
  }
};

つまり、x変数もy変数も、このループを抜けた時の10という数字がセットされているわけで、どうやら変数のスコープ問題に遭遇した。

この解決策は、次回に。