やねうらおうの定跡ファイルをサイトに使ってみた

ずーっと海外に住んでいて、将棋を指す相手がいなく、ヒカルの碁でネット碁の存在を知り、 こんなものがあるんだ、と検索して、Kurnickというゲームサイトを見つけ、そこでネット将棋を始めてみたら、みんな結構無茶苦茶な指し方をするのにびっくりして、英語の将棋入門サイトを作成したのが、今から17年くらい前、最初は静止画像をべたべたはりつけ、ブログに毛が生えたようなサイトだったが、フラッシュアプリを使った将棋盤というのが世の中にあるのがわかり、これを使って詰将棋やら最初の数手の説明、定跡の説明なんかをしていた。
割と早い段階で、フラッシュが駆逐されそうだということに気が付き、JavaScriptを勉強してフラッシュ無しでも動く将棋盤を自前で作成して自分のサイトで使い始めた。これがもうかれこれ12年以上前。これが幸いしてFlashが完全終息 した際のインパクトは避けることができた。

当時はそれなりに海外の将棋入門者の役にたったのではと思っているのだがそのうちYouTubeにHidetchさんが英語の将棋入門チャンネルを開き、さらに81道場を開設するにいたって、これは時代が変わったと悟った。 今ではほかのリソース、例えばYoutubeに上がる将棋の動画などもさらに充実し、DiscordではカロリーナのShogi Harborなど。 加えて自分もそろそろ終活を考慮しはじめるべき歳なのでこのサイト、もう閉じようかと思ったりするのだが、Statsを見るとまだ世界中からぼちぼちロボットではなく人間のアクセスがある。のでなんとなく続けている。 それにページを更新するごとにPHPの新しい使い方とかTypeScriptの勉強にもなるので、頭の老化防止にもつながっているような気がする。→どちらかというとこれが現在一番のモチベーションになっている。

最近何気にWikipediaの将棋の項目(英語版)を観たら外部リンクのリストの最初に自分のサイトが載っていて驚いた。ますます閉じにくくなった。

このサイトの中で何度か書き直しているページの中に、初めの数手の内容をまとめようとしたページがある。 最初はYamajunさんのサイトにある棋譜にリンクしていた。  しかしながら他のサイトへのリンクというのは実にあてにならないもので、 このリンクを含むリンク先の大部分が2019年時点で消失していた。 2009年当時Webの90%を占めていたFlash Player base のサイトが ほぼ全滅したのが大きいと思われる。
ならば自前でつくろうと考え、やり直しを重ねたこのページ。 一応形にはなったが、これは掘り下げていけばいくほど、もっと広げていきたい衝動に駆られる。

最近 やねうらお さんのGithubでやねうら王に使われている定跡の4年前のレベルのものが公開されているのに気が付いた。 自由にお使いくださいと書いてある。前にNHKの将棋講座の特集でだれかが将棋ソフトの作者さんたちは気前が良すぎるんですと言っていたが、まったくだ。  定跡フォーマットを見るとSFEN + move(s)の繰り返しのテキストファイルだ。 幸いSFENの読み込みと書き出し機能は自作のWeb用将棋盤表示アプリにすでに実装ずみなので、このファイルをそのまま使わせてもらってWebで定跡表示ができるのではないかと思いついた。

遠い昔 やねうらお さんというハンドルネームの方の、将棋界の内情を色々批評していたブログを見ていたようなきがするのだが、同一人物かどうかはさだかではない。 ただ、今や将棋プログラム界のドンとでもいえるような大活躍をされているようである。 5歳のときにTK‐80を使って8080のニーモニックを覚えたと書いているのを見ると、多分 自分より20歳くらい若い働き盛りなのでありましょう。自分がTK-80に触ったのはまだ日本にいたころ、取引先の業者がNECの代理店をやっていて、「遊んでみて」と持ってきたのが最初だ。モニターのルーチンを使ってスクロール表示をくるくる回しただけで満足して 終わったような気がする。

ともあれ、定跡ファイルをばらしてMySqlデータベースに落とし込んでみた。Pythonを覚える良い機会と思ったがコマンドラインでもPHPが使えることを思い出し、コードもあっさりかけてしまったので、Pythonの学習はまたもやお預けだ。(ファイルサイズが87メガバイトの大定跡ファイルは、MySQLに落とし込むのにPHPをコマンドラインで実行させて4~5時間ほどかかった。 専用サーバーではなく、他の業務と兼用なので、こんなものなのかもしれない)

局面数指し手数
やねうら王定跡(2016)130,182155,443
やねうら王大定跡(2016)428,2442,433,672
やねうら王テラショック【WCSC29】285,463512,860
各定跡ファイルの持つ局面数と指し手数

Web ServerにSFEN文字列を送るとと候補手のアレィをリスポンスとして返してくれるようなAPIを作成し、ページを追加してみた

我ながら GUI デザインのセンスが無いなあと思うのは毎度のことだが、 面白いなとおもったのは最初の定跡(説明によるとFloodGateで収集した棋譜を24手まで統計的にまとめたもの)の初手の頻度が人間の指す初手の頻度とほぼ一致していた点。2016年当時ということもあるのだろうが、ソフトというのは、もっと自由な手を指すのかと思っていた。この統計頻度の高い指し手を選び続けて行くと先手左美濃対後手四間飛車になる。 こういう風に指すんですねえ。
一方局面評価をしまくって精選したという100Tera Shock定跡なるデータファイルのほうでは評価値が高い指し手を選び続けると横歩取りに誘導される。

大定跡は一番充実しているはずなのだが、評価値の高い指し手を選んでいってもはやばやと定跡から外れるケースが多い。 原因は Mysqlへの落とし込みに失敗しているか、最初から定跡ファイルがそういう作りになっているかのどちらかだがよくわからない。ただ、下の表に示したように、初期局面1にたいし、二番目の(一手目)局面が14種類、三番目の局面(2手目)が56種類 と多くなっていくものの局面数が、指数関数的には広がっていないので結構枝をはらっているのはわかる。でも第一候補の次の指し手が無いというのはなんかおかしい。 暇ができたら見直してみます。

11
214
356
4135
5323
6678
71289
81922
92714
103623
114812
125995
137181
148407
159741
1611136
1712492
1814160
1915731
2017425
2118979
2220500
2321883
2423224
2524374
2625479
2726567
2827704
2928792
3029952
3131001
3231954

これだけの局面数と指し手を評価して枝をはらっていくというのは相当にリソースと時間が必要になると思うのだけど、それをgithub上にポンと公開してくれているのは 大丈夫ですか、と思ってしまう。恩恵にあずかっているわけですが。

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の倍速化でもできれば状況が変わるかもしれない。