JavaScriptで動く将棋盤のページを作る。コンセプトの整理

あらためて、考え方を整理してみる。

Webページは HTMLファイル、CSSファイル、JavaScriptファイルという三つの構成要素から成り立っている。そこで今回試作したページのすみわけを考えると以下のようになる。

html ファイル:将棋盤の入れ物を定義し、CSS,JavaScriptファイルにリンクさせる。
CSSファイル:将棋盤と駒の表示の仕組みを定義する。これをHTMLのエレメントの属性に対するスタイル定義で行う。
JavaScriptファイル: 将棋盤の初期配置と駒の動きのデータ、および、駒を初期配置の通りに並べて表示し、駒を動かす関数およびボタンの表示。 データ部分と機能部分を分けて二つのファイルで構成するようにする。
JavaScriptでも”描画”作業は行っていない。WebのDOM(DataObjectModel)を操作してHTMLのエレメント属性を変更させているだけで、あとはブラウザにお任せである。
一度画像データをサーバーから読み込めばデータがローカルにキャッシングされる。ブラウザとしては初期画面で盤と駒のデータを読み込んだあとは時々成り駒のデータをダウンロードしにいくだけなので、作画速度で目に見えるような遅れはない。
Web page を表示するためには将棋の盤、マス目、各コマの画像データの他に
filename.html
shogiboard.css
boarddata.js
boardfunction.js
の4つのファイルが必要、boarddata.jsに棋譜データを書き込んで動きを指定する、ということになる。実際にはboarddata01.js, boarddata02.js などと作っておいて、html からのリンク先指定を変えてやるような操作になる。
HTML内部、JavaScriptへのリンク部分
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script> 
<script src="boardfunction.js"></script> 
<script src="boarddata01.js"></script>
HTML内部、CSSファイルへのリンク部分
<link href="shogiboard.css" rel="stylesheet">
ところで、
この将棋盤、自分のサイトに表示するには少し大きすぎる。
もっと小さい画像データがないかなあ、と思っていたのだが、CSSでイメージをスケーリングすれば解決できることに気が付いた。 Cascaded Style Sheet は変更部分だけ記述すれば、最後に置かれた記述が依然の記述を書き換えるので
約65%のスケールダウンには以下のような内容のCSSファイルをリンク先に追加すればよい。
.board {width:286px; height: 312px;} 
.komadai {width:100px; height:150px;} 
.komadai img,.koma, .marker {width:30px; height:33px;} 
.comment {padding-left:7px; width:450px;min-height:100px;}
#boardbase {width:323px; height:337px;} 
.c1 {left:258px;} .c2 {left: 228px;} .c3 {left:198px;} 
.c4 {left:168px;} .c5 {left: 138px;} .c6 {left:108px;} 
.c7 {left:78px;} .c8 {left: 48px;}  .c9 {left: 18px;} 
.r1 {top:17px;}   .r2 {top:50px;}    .r3 {top:83px;} 
.r4{top:116px;}   .r5{top:149px;}    .r6 {top:182px;} 
.r7{top:215px;}   .r8{top:248px;}    .r9{top:281px;}
このファイル名、shogiboard-small.css とすれば HTML内部、CSSファイルへのリンク部分は
<link href="shogiboard.css" rel="stylesheet">
<link href="shobiboard-small.css rel="stylesheet">
となる。
動くサンプルはこちら
下にファイルと機能のまとめをマインドマップで整理したものをリンクしておく

将棋盤に戻しボタンをつけてみる(JavaScript)

将棋盤の上の駒がボタンを押すごとに一手づつうごくようになって喜んだのもつかの間、手を戻すボタンがないのがひどく問題に見えてきた。 これは機能を追加せねば、と考えたのだが、最初の設計時点で履歴をとるような構想は一切なかったのではたと困った。動きを逆になぞってみても、駒を取る、というアクションがデータ構造上明示されていないので、もとに戻すのが無理なんである。 何か方法があるはずだと思いつつ2~3日、ほおっておいた。

いっそのこと、一手ごとに将棋盤全部のスナップショットを取ってそれを変数配列に格納してはどうだろうと考えついた。 スナップショットとは言っても、画像データをコピーするのではなく、JavaScriptが精製したhtmlのツリー構造をそのまま変数にコピーしてしまおうというわけだ。JavaScript ではinnerHTMLといタグ内の文字列をそっくりコピーできる関数がある。JQueryでは.html()メソッドにファクタリングされているので、これを使えばなんとかなるのではないかと実験してみたらあっさり動いてしまった。
ちなみに40枚駒を並べた将棋盤のスナップショットは文字列の大きさで5キロバイト程度だった。 これなら200手動かしてもでも1メガバイトで収まる。 Z80でプログラミングしている時代なら、5キロバイトとわかった時点で、間抜け扱いだったが、時代は変わったのだ。これでいいのだと自分を納得させる。 ブラウザ上の JavaScript で動いているわけだから、データがネットワークを移動するわけでもなく、単にブラウザの使用メモリーがそれだけ増えるだけ、ということになる。
まずはデータを格納する配列変数を用意する。
var board {
.
.
history:[],
}
という具合にGloval variable に Array としてhistory[]を定義しておき、次に<div id=”snapshot”>…</div> 内のhtml構文をboard.history[]にセーブする関数 takesnapshot()を定義する。
function takeSnapshot(i){
board.history[i]=$('.forSnapshot').html();
}
次に、このboard.history[]配列から現状の<div id=”forsnapshot”>…</div>内に内容をロードする関数を定義する。 同時に”一手進めるボタン”が無効化されていれば、それを有効にする作業も行う。
function setBoardToHistory(i){
$('#aButton').removeAttr("disabled");
$('.forSnapshot').empty().html(board.history[i]);
}

>

次に上記の関数を呼び出して、一手だけ戻る関数 stepback()を定義する。ここでは一応board.index が0以下にならないようにチェックを入れている。
function stepback(){
if(board.index>0)
setBoardToHistory(--board.index);
}
そして、animateBoard() function に太字部分を追加。
function animateBoard(){
var zAction=board.moves[board.index];
takeSnapshot(board.index);
parseAction(zAction);
board.index+=1;
if (board.moves[board.index].charAt(0)=='x') $('#aButton').attr("disabled","disabled")
;

}
ボタン機能を追加
function setupButton() {
$("#aButton").click(function () {animateBoard()}).attr("value","Forward for solution");
$("<input type='button'>").click(function() {stepback()}).attr('value','Step back').appendTo('#buttonBar');
}

 
上のルーチンで、

<div id='buttonBar'>
<input  type="button"  id="aButton" value="Javascript did not load" />
</div>

というエレメントにStep back というボタンが動的に追加される。(aButton のほうも同じように動的に追加したほうがコードがコンパクトになりそうだ)

これでもとに戻るボタンを追加することができた。 デモはこちら

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();

});

 

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

 

将棋駒をJavaScriptで動かす

前回作った将棋盤で、初期画面を表示することができたので、ここから駒を動かすしかけをJavaScriptで作成していく。

駒の動きを表すデータ形式をまず決める。やはり、boardというグローバルオブジェクトの中にmoves というString配列 として用意することにする。

一文字目:先手・後手の指示、s (先手)またはg(後手)の一文字で表記。先手が2手続けて指す、ような場合にも対応、  ‘x’で終了。
二文字目:駒を打つ場合にはd(drop) ,駒をなる場合には’+’, それ以外は読み込まない。
三、四文字目:駒の移動先の座標 3四の場合は34 etc.,
五、六文字目:二文字目、drop指定以外は駒の移動元の座標 3三の場合は33 etc.,
二文字目がDrop指定の場合、五文字目は駒の指定一文字jとなる。(p,l,n,s,g,r or b)

たとえば、後手3三の駒が3四に行く場合の表記は “g-3433″となる。 コマの種類に無頓着に3三にあった駒を3四に移動する、という考え方である。

また、後手側が歩を2三に打つ場合は”gd23p”となる。

駒をとる、という表記がないが、これは移動した先に駒があれば、それを取るということにする。よって明示的には記述しない。

また、’*’以下の文字列をコメントとして認識し、コメント欄に表示できるようにする。 一文字目にあれば、駒を動かさず、コメントのみ更新する。

 

配列のポインターとしてboard.index という変数を指定しておく。 初期値は当然0.

これらのルールによって、一連の駒の動きをあらわすとたとえば以下のようなデータ配列となる。


object={
.
.
.

moves:[
"*this is a comment that should go to comment line",
"s-2627 *here, the sente moves a piece from 27 to 26",//2六歩
"g-8483", //8四歩
"s-2526", // 2五歩
"g-7261", // 7二金
"s-2425", // 2四歩
"g-2423 *capturing the piece is implied", //同歩
"s-2428", // 同飛車
"gd23p", // 2三歩打
"s+2324",// 同飛車成り
"g-3241", //3二金
"s-2223", // 2二竜
"g-2231", //同銀
"x" //終了
],
index:0,
.
.
}

将棋盤と駒をWEB上に表示する2

というわけで、将棋の駒の個々の画像データ表示位置をCSSに記述することによって将棋盤に将棋の駒を配置することができるようになったが、いちいち

<img href=”……png” alt=”” > という属性をつけたイメージタグを駒の数だけ書いてWebページを作るのも気が利かない、というか、手間がかかってしょうがない。 そこで JavaScript を使って作業を簡単にすることを考える。

まずは駒配置のデータ形式を グローバルバリアブル(board)に格納することとし、その構文を以下のようObject literal で記述する

var board;

board= { onBoard:{ G:
['11l','21n','31s','41g','51k','61g','71s','81n','91l', '22b','82r', '13p','23p','33p','43p','53p','63p','73p','83p','93p'],
S:
['19l','29n','39s','49g','59k','69g','79s','89n','99l', '28r','88b', '17p','27p','37p','47p','57p','67p','77p','87p','97p'] },

onHand:{ S:['g', 'g', 'l', 'p'], G:['b', 'l', 'l', 'p'] },

盤面の配置はonBoard とし、その中にS配列(先手) G配列(後手)をつくる。同じく持ち駒の配列をonHand.S, Onhand.G という二つの配列に記述する。

駒の種類については英語文字一文字であらわす。 (香車=Lanceー&gt;l、桂馬=Knight→n、銀=Silver→s、 金=Gold→g、角=Bishop→b,飛車=Rook→r, 王=King→k)  なお、成駒はすべてそれぞれの英文字の大文字とする(成銀→S、成桂→N etc.,)

ちなみに上の例では平手の初期画面となる。(よって、onHand 部分は本当は空行列になるべきだが、これはテスト用のデータなのでこうなってます)こうやって先手、後手の駒の配置をまとめて記述することによって前回よりはデータを作る手間が楽になる。

次にこのデータを読み込んでイメージタグを生成するfunction を定義する。

JQuery の拡張機能を多用するのでまずは以下の記述が必要

 <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js">
function cordToClass(cord){ return 'koma c'+cord.charAt(0)+' r'+cord.charAt(1);}

そして function initializeBoard() で将棋板と駒台を表示

function initializeBoard() { var i,cord,png;

for (i=0; i<board.onBoard.S.length; i++){

png=komatopng(board.onBoard.S[i].charAt(2)); cord=board.onBoard.S[i].substr(0,2);

$('<img alt=""/>') .addClass(cordToClass(cord)).attr('src',board.pathname+'S'+png).attr('data-koma',png).appendTo('#boardbase'); } for (i=0; i<board.onBoard.G.length; i++){

png=komatopng(board.onBoard.G[i].charAt(2)); cord=board.onBoard.G[i].substr(0,2);

$('<img alt=""/>') .addClass(cordToClass(cord)).attr('src',board.pathname+'G'+png).attr('data-koma',png).appendTo('#boardbase'); }

for (i = 0; i < board.onHand.S.length; i++) { png=komatopng(board.onHand.S[i]);
$('<img class="" alt=""/>') .attr('src', board.pathname+'S' + png ).attr('data-koma',png).appendTo('#senteMochigoma'); }

for (i = 0; i< board.onHand.G.length; i++) { png=komatopng(board.onHand.G[i]);
$('<img class="" alt=""/>') .attr('src', board.pathname + 'G' + png).attr('data-koma',png).appendTo('#goteMochigoma'); }

}

上記のfunction をブラウザーがデータを読み込んだ直後に実行させるために、

$(function () {initializeBoard();}

Jquery 大活躍の図である。

きもは

$('<mg alt=""/>') .addClass(cordToClass(cord)).attr('src',board.pathname+'S'+png).attr('data-koma',png).appendTo('#boardbase');

という一行なのだが、 これほとんどJquery のlibrary 機能ををつかっているわけで、

$(‘<img alt=”” />’) で新規にイメージエレメントをつくり、

.addClass(“…”) で クラス情報を追加し、(.addClass(“koma  c7  r9″)など
.att(…) で src属性を追加(src=”images/shogiboard/Sgin.png”など) (.attr(‘data-koma.png’) は data-koma属性を追加したもので、これは後述する。 ) そして最後にこのイメージエレメントを <div id=”boardbase”> というエレメントの最後尾に追加する

こうやってスタイルシートを使ってブラウザーにならべさせた将棋の駒を動かすのは実はわりと簡単にできる。

たとえば 例えば先手の銀を7九から6八に動かそうとした場合は

<img src=”….Sgin.png” alt=””> というエレメントをJQueryのクラス名指定($(‘.koma.c7.r9’)で探し出し

classを”koma c6 r8″ と書き換えてやれば、あとはブラウザの描画機能がイメージを動かし銀が動いたようにみせることができる。

ただそうは言っても、駒を取る場合はもともとそこにあった駒を先手後手の判断をして駒台に乗せる必要があるし、駒が成れば、画像ファイル指定も変えてやる必要がある。  場所を示すために動いた升目をハイライトする必要もある。

次回はこのあたりのインプリメンテーションを紹介する。

将棋盤と駒をWEB上に表示する1

まずは静的に将棋盤と駒をWEBページに表示してみる。
HTMLの記述は以下のごとくなる。
当該部分のみ

<link href="boardstyle.css"  rel="stylesheet" >
.
.

<div class="table"> <!-- outer table -->

<div class="row">
<div id="boardbase" class="cell">
<img class="board" src="assets/images/shogiboards/ban_kaya_a.png" alt=""/> <!-- 盤を表示-->
<img class="board" src="assets/images/shogiboards/masu_dot_xy.png" alt=""/><!-- マス目を表示 -->
<img class="koma c5 r9" src="assets/images/shogiboards/Sou.png" alt=""/><!--先手王を 59に -->
<img class="koma c5 r1" src="assets/images/shogiboards/Gou.png" alt=""/><!-- 後手王を 51に-->
<img class="koma c3 r7" src="assets/images/shogiboards/Ggin.png" alt=""/><!--後手銀を 37に -->
<img class="koma c9 r7" src="assets/images/shogiboards/Sfu.png" alt=""/><!--先手の歩を97に-->
<img class="koma c4 r9" src="assets/images/shogiboards/Skin.png" alt=""/><!--先手の金を49に-->
</div>

<div class="table"><!-- inner table -->
<div class="row">
<div id="goteMochigoma" class="komadai cell"> <!-- 後手の駒台-->
<img src="assets/images/shogiboards/Gou.png" alt=""/>
<img src="assets/images/shogiboards/Ggin.png" alt=""/>
<img src="assets/images/shogiboards/Gfu.png" alt=""/>
<img src="assets/images/shogiboards/Gfu.png" alt=""/>
<img src="assets/images/shogiboards/Gkin.png" alt=""/>
</div>
</div>
<div class="row">
<div class="cell empty" ></div>
</div>
<div class="row">
<div id="senteMochigoma" class="komadai cell"><!--先手の駒台-->
<img src="assets/images/shogiboards/Sgin.png" alt=""/>
<img src="assets/images/shogiboards/Sfu.png" alt=""/>
<img src="assets/images/shogiboards/Sfu.png" alt=""/>
<img src="assets/images/shogiboards/Skyo.png" alt=""/>

</div>
</div>
</div><!-- innter table -->
</div><!-- shogirow for the outer css-table-->
</div><!--shogitable-->

一方、boardstyle.cssは

.forSnapshot {position:relative;}
.table {display:table;}
.row {display:table-row;}
.cell {display:table-cell;}
.empty {height:25px;}
#boardbase {position:relative; width: 440px; height:490px;}
#senteMochigoma {vertical-align:bottom;}
.komadai {height:220px; width:160px; background-image:url(assets/images/shogiboards/ban_kaya_a.png);}
.board {position: absolute; left:10px; top:9px; }
.comment {padding-left:10px; width:590px;min-height:120px;}
.koma {position: absolute ; width:43px; height:48px;}
.marker {position:absolute; width:43px; height:48px;}
.lostworld {left:-20000px; top: -20000px;}
.c1 {left:365px;} .c2 {left: 322px;} .c3 {left:279px;}
.c4 {left:236px;} .c5 {left: 193px;} .c6 {left:150px;}
.c7 {left:107px;} .c8 {left: 64px;}  .c9 {left: 23px;}
.r1 {top:20px;}   .r2 {top:68px;}    .r3 {top:116px;}
.r4{top:164px;}   .r5{top:212px;}    .r6 {top:260px;}
.r7{top:308px;}   .r8{top:356px;}    .r9{top:404px;}
画像ファイルはすべてassets/images/shogiboards フォルダーに格納しておく。
ポイントとしては


<div id=boardbase> で将棋板ブロックのコンテクストを作り、この中に画像を放り込む。この画像の位置については koma属性でabsolute とし、列と行の位置をcx, rx でそれぞれ指定する。 r1=20px, c9=23px を起点に cxは横幅43px  lxは 縦高さ48pxづつ変化させている。駒台のブロックには単純に駒のイメージファイルを放り込んでおくと順番に表示される。

html において、将棋板と駒台をアレンジするのに、CSSのdisplay:table 属性を使っている。 htmlの一連のtable tag類 を使うことも考えたが、これはデータをリストアップするのとはちょっと違ったような気がしたので。cssで処理をすることにした。

結果はこちら

 

一応表示できるようになったが、これで将棋の駒40枚をならべるのは大変なので、 次回はたとえば文字列 ”s44g”,”g65p” などの羅列をつくり、これをJavascriptで処理して駒の配置表示する方法をかんがえる。

将棋盤をHTML/CSSで構成し、駒をJavaScriptで動かしてみる。

趣味で英語の将棋入門サイトをホストして5年くらい経つ。 駒の動きとか手筋、などをみせるのに過去ネット上で入手できる色々なアプリに世話になってきた。一番お世話になっているのが柿木さんのkifu for Flash で、定跡の紹介などは、このアプリケーションが欠かせない。 他にもユモケンさんのFlashを使った将棋盤を使って歩の手筋の紹介などをしてきた。 数年前に簡単な詰め将棋集をつくるのにBCM将棋で画像を生成し、これを順次表示して詰め手順を示すしくみを当時覚えたてのJavaScriptで書いてみた。 ただそのときわかったのだが、手数ごとの画像をいちいちセーブしてそれを組みたてる、というのはJavaScriptを使っていても結構手間がかかる。 今回駒職人1さんのサイトからCreative common license による駒と将棋盤の画像が入手できたのでこれを機会に初期の駒配置と動きのデータをJavaScriptファイルに書いておけば、それをなぞって実行してくれるようなしかけを作ってみた。

一応うごくようになったので、ここに公開しておくことにする。

特徴としては

駒の配置をCSSで処理しているということで、具体的にいうと たとえば先手の銀を34におきたい場合、銀のイメージファイルがSgin.png とすると

<img  src=”Sgin.png” class=”koma c3 r4″ alt=”” /> というようなイメージエレメントをJavascriptで動的に生成して将棋盤の3四の位置に銀を表示させる、というような手法をとっている。

動くサンプルをここにおいておく。 また、3年経つと何をやっているのかわからなくなる、というのが前回の経験でよくわかったので少し詳しい説明を順次ここに書きのこしておくことにする。 誰かの参考になればうれしいし、もっと経験のある方から助言をいただけるとありがたい。

ねらい: サイトの教材作成に使えるような動く将棋盤
データのエラーチェックなどはつけない(自分でしか使わないので)
前もって用意しておいたデータファイルをもとに初期配置およびその後の駒の動きを表示できる
CSSとJavaScript、HTMLの3種の神器のみで記述、JavaScriptはJqueryLibraryも使用

上記のページにはHTML記述に余計なものは入れていないので、ブラウザーの開発ツールを使って二つのJSファイルの中身とCSSファイルの中身も一緒に見てもらえれば、それなりにコメントも入れたので、ほぼ全容がつかめると思う。

 

81dojo

81dojoでの81oui戦、OneyeとTellmarchとの激戦を見ると自分がこの二人にまがりなりにも勝ち星を挙げている、という事実が信じられない。駒の動きに勢いがある。 自分とやるときには年寄りだから、と手をぬいてくれているのだろうか。力戦とB級戦法ばかりでかく乱できているからなのか、二人とも定跡オタクではないから、そんなこともないか。 まあどっちみちそのうちまったく勝てなくなるだろうから、今のうちの話、というのは間違いなさそう。

Tellmarch は自分のサイトが無かったら将棋をやっていたかどうかわからなかった、とうれしいことを言ってくれたし、Oneyeはあじゃ盤で読みを磨いたそうだ。 そんなことをいわれると、やっててよかったな、と思ったりもする。

東大将棋DS

DSで東大将棋が動く、ということで、 先月日本に出張したときに購入してきた。

ずーっとやってみているのだが、

弱い

一応フリーモードでは10級から二段まで手合いを選べるようになっているが、二段に設定しても苦労せずに勝ててしまう。 どうも終盤がゆるい。 

これは比較論の問題で、大体においてコンピューター将棋は終盤が辛くて、よほど良い形勢でも逆転されてしまうことがよくある。 このソフト、それが無い。 それと序盤の筋が悪い。

どこだかのコンピューター将棋のページにパソコン用の将棋ソフトとゲーム機用の将棋ソフトを比較してはいけない、というような事が書いてあった。 ゲーム機はグラフィック機能にかけては高性能だが、計算能力にかけてはパソコンの足元にも及ばない、と。

よって、パソコンの東大将棋では5段くらいまであるはずの手合い設定が、DS用では二段までとなり、考慮時間も人間側よりも長くかけて必死に読んでいるようだが、それでもハードスペック的につらいか。

というわけでメインモードではC2級から始まって名人まで駆け上るのに連勝土付かず。 以後ずっと名人位継続中。

実は去年AI将棋のDS版も購入していたのだが、こちらのほうが相対的に強いと思う。 ところが思考時間がいらいらするほど長く、とても時間つぶしにちょっと楽しむ、というようなソフトではなくなっている。

帯に短したすきにながし。 DSの倍速化でもできれば状況が変わるかもしれない。 

 米国の子供に将棋レッスン

オークションで1時間のレッスンを購入した方から電話がかかってきて、Boardersという大型の本屋の喫茶室で待ち合わせをした。

やってきたのは小学校5年の女の子と2年の男の子、それに父親の3人

早速将棋盤と駒の説明から入る。 聞けば3人ともチェスはかなり熱心にPlay しているようで (だから興味を持ってくれたということなんだろう)、ゲームのコンセプトは最初の3分で理解した。 持ち駒の説明に4分。 Wikipediaで少し調べていたようだが、それでも

駒に敵と見方の区別はないのか? どうやって判別するのか、

という質問がでて、 駒のおき方を上下逆にすることによって区別する。 とう考えを理解するのに少し手間取る。

チェスを知っているということで既成概念ができあがっており、まったく知らない人に教えるのとはまた違った難しさがありそうだ。

特にしんどそうだったのが、それぞれの駒の移動範囲を教える時の駒の種類の判別。 当然といえば当然だが、 飛車と王将と香車の区別がつかない。 いきなり(なりゴマ抜きでも)8種類の漢字のコンビネーションを見せられ それぞれの動きがどうの、という説明は、まともにやれば多分それだけで1時間かかってしまいそうだ。 最初はシンボル駒を使ったほうが良いのかもしれない。 そこを10分で駆け抜け、ハム将棋のサイトを教えて逃げる。日本語のサイトだが、印刷したイメージでガイドをチェックすればそれぞれの駒の移動範囲が表示されることを説明し、10枚落ちくらいで練習すればよい、とサジェスト。

改めて教えてみると

禁じ手の説明、

千日手の説明

と、囲碁に比べると最初におぼえなければならないルールが多い。

成りのコンセプトは、三段目以下に入って成る、必ず成る必要はない、一度成らなくても次回動かすときにも成ることができる、三段目から引き成ることもできる、 ということで、 説明していて我ながら、「将棋って結構ルールが難しいな。」と思った。

お互いに飛車先を伸ばして行く形で、なぜ7八金を省いて先行するとまずいのか、の説明と原始棒銀の説明をしながら、実際の駒の動かし方を覚えてもらい、  まだ先の話だけど、こういう形もある、いう前置きでお互いに角道を空けたあとの、振り飛車の形の基本説明。 四間飛車の急戦の基本形に持っていくだけの手順でも「わー、そんなに複雑!」というのが5年の子の正直な感想。囲いの説明でも、チェスなら1手しかかからないのを美濃囲いは5手かける。 

角道を空けるか、飛車先を突く、というOpeningは Kurnikで色々すごいのをみているので、どうしても説明しておきたかったのだ。

あとは1手と3手の詰め将棋を数題見せて時間切れ。 最後に見せた玉方、4一銀、5一玉、6一銀、責め方5三銀、1六角、持ち駒 銀、のパターンは角を歩の持ち駒に変えて考えさせたあと、もう一度解かせたら、すぐにできた。 解いた瞬間、子供達の顔が輝いて見えたのは気のせいか。

終わった後、Takodoriさんのブログページを教え、英文の資料はここから、とサジェストしたが、 

さて。

将棋のルールを教えるのも一仕事なのに、その魅力を1時間で伝える、というのはとてつもなく大変なことだ。 と改めて認識した。

少しは興味をもって続けてくれる可能性は2パーセントくらいかな。ゼロではないと思うが。