JavaScriptで将棋の駒を動かす2

前述のグローバルデータを読み込んで、駒の処理をする関数を定義していく。

function animateBoard(){
var zAction=board.moves[board.index];
parseAction(zAction);
board.index+=1;
if (board.moves[board.index].charAt(0)=='x') $('#aButton').attr("disabled","disabled")   ;
}

上がメインの関数になる。これは呼ばれるごとにboard.indexで指定されるboard.moves[]文字列を読み出し、parseAction関数に渡す。 ’x’ を読み込んだ時点で、駒を動かすボタンを無効化するようにしている。

function parseAction(aAction) {

if (aAction.charAt(0) == '*') postComment(aAction.slice(1));
else {
if (aAction.charAt(1) == 'd') makeAdrop(aAction.charAt(0), aAction.charAt(4), aAction.substr(2, 2));
else {
makeAmove(aAction.charAt(0).toUpperCase(), aAction.charAt(1), aAction.substr(4, 2), aAction.substr(2, 2));

}
if(aAction.indexOf('*')>0){postComment(aAction.slice(aAction.indexOf('*')+1))}
}
}

parseAction 関数では文字列を解析し、コマンドを実行する。コメントであれば、postComment,  駒を打つのであれば、makeAdrop, それ以外はmakeAmove関数にパラメーターを渡し、最後にもう一度コメントの有無を確認している。

function postComment(comment) {$('#scomment').empty().append(comment);}

postComment はid=”scomment”のhtml エレメントをまず空にしてから、コメントを張り付ける、というだけのもの。

function makeAdrop(side,koma,position) {
var png=side.toUpperCase()+komatopng(koma);
if (side.toUpperCase()=='S') side='#senteMochigoma';
else side='#goteMochigoma';
setMarker(position);
position=cordToClass(position);
emptyComment();
var selector=side+' [src$="'+png+'"]';
$(selector).first().addClass(position).appendTo('#boardbase');
}

駒をドロップする、ということは先手、または後手の駒台から当該する駒のイメージエレメントを探し出し、このイメージエレメントのクラスを変更して将棋板のブロックにぶら下げる(appendTo)という作業になる。appendTo自体はエレメントを移動するコマンドなので、駒台のイメージエレメントをdetachする必要はない。

function makeAmove(side,promote, from, to) {
emptyComment();
//if to position is already occupied, then capture that image element to 'side's mochigoma
//for this we check the lenth of selector. ie, if $(".c6 .r7").length>0 then there is an element.
if ($(cordToSelector(to)).length>0) captureKoma(side,to);
// then set a marker to "to" position
setMarker(to);
// then move the piece, it just involves the changing of class
$(cordToSelector(from)).attr('class', cordToClass(to));
// then check if the piece is promoted by checking the variable promote
if (promote=='+') {promoteKoma(side,to);}
}

駒を動かすmakeAmoveという関数は、駒の移動先にすでに他の駒がいるかどうかを判定し、もし存在すればそのコマを自分の駒台におくという作業(captureKoma)を行う。 次に駒を移動させ、もし、成る、という行為が指定されていれば駒を昇進させる(promoteKoma) 駒の移動自体前述したごとくClass属性を変更するだけという非常に簡単な作業。

function captureKoma(side,cord){
var komaban,koma;
komaban=(side=='S')?'#senteMochigoma':'#goteMochigoma';
koma=$(cordToSelector(cord)).data("koma");
$(cordToSelector(cord)).first().attr("class","").attr("src",board.pathname+side+koma).appendTo(komaban);
}

captureKoma では先手か後手かを判断して、どちらの駒台に駒を移動するかを決める。駒の移動は当該イメージエレメントのClass属性を削除して駒台エレメントにappendするだけ。

function promoteKoma(side,cord) {
var koma;

koma = $(cordToSelector(cord)).data("koma");
koma = (koma == "hi.png") ? "ryu.png" : koma = (koma == "kaku.png") ? "uma.png" : 'n' + koma;
$(cordToSelector(cord)).first().attr("src", board.pathname + side + koma);
}

promoteKoma では、画像ファイルの名前を変更する。 なお、駒の画像ファイル名をイメージエレメント自体に記録しておくために”data-koma”という属性をエレメント作成時に追加しているのだが、これはjquery では.data(“koma”) というメソッドで読むことができる。駒がなっても、この画像ファイル名自体は変更していない。(駒を取った時に、このデータを読み込んで駒台に置かれる駒の画像としている。竜を取っても、駒台に置かれるのは飛車、というわけ)

上記の関数に使われるサブ関数の定義は以下の通り。

function emptyComment() {$('#scomment').empty();} コメント欄を空に
function cordToClass(cord){ return 'koma c'+cord.charAt(0)+' r'+cord.charAt(1);}

位置情報をクラス属性に変換(例:34→”koma c3 r4″)

function cordToSelector(cord){return ('.koma.c'+cord.charAt(0)+'.r'+cord.charAt(1));}

位置情報をjQueryのセレクター情報に変換(例:34→’.koma.c3.r4 ‘)

function setMarker(cord){
var markerClass;
markerClass="marker c"+cord.charAt(0)+' r'+cord.charAt(1);
$('#marker').attr("class",markerClass);
}

これは、動いた駒を示すために、駒の背景色を変えてるためのmarkerセットするルーチン。

 

動かすためのボタンを設定

function setupButton() {
$("#aButton").click(function () {animateBoard()}).attr("value","Forward for solution");
}

 

初期設定にボタン設定を追加

$(function () {
initializeBoard();
setupButton();

});

 

これで一応ボタンをクリックすることにより、駒が一手づつ動く将棋盤ができた。(デモサンプル) とたんに気が付いたのが、手を戻す機能がほしい、ということ。 というわけで次回は戻しボタンの実装をする。

 

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload the CAPTCHA.

This site uses Akismet to reduce spam. Learn how your comment data is processed.