#はじめに
三目並べは小規模ながら簡単なルールを持つボードゲームであるため,プログラミング入門として良く作られる。実際,HTML上で動く三目並べは,JavaScript,Java,Ruby で多く作られている 1 2 3 4 5。中でも JavaScript は初心者向きであり,多くの人が最初に取り組もうとすると思われる。一方,HTML5 でサポートされた Canvas は,美しい図形を容易に描くことができ,位置を座標で指定できるため,リバーシや囲碁のような大きな盤面にも容易に拡張できる。そこで,三目並べの作成に Canvas を使いたいと思うのは自然であろう。
JavaScript のボタンやテーブルを使うときは,マウスボタンのクリックイベントに対して,関数の引数にオブジェクトを取得することができ,そのオブジェクトに対する処理を順次記述していくことになる。それに対して,HTML5 Canvas を使うときは,マウスボタンのクリックイベントに対して,jQuery のカスタム trigger を発行してそれを受信した時,ユーザの処理を記述する手順が必要となる。ここでは,この手順について解説する。実際に動いているプログラムは,ここを参照されたい。プログラムも置いてある 6。
完成後にプログラムを見直したところ,わざわざ,カスタム trigger を使わなくても良いことがわかった。しかし,カスタム trigger の使い方としては役立つので,初版としてそのまま残すことにした。三目並べに関しては,より簡潔なコード改訂版として,改めて提示することにした6。
実を言えば,HTML5 Canvas と jQuery を使った囲碁の対局サイトがある7。但し,そのプログラムの解説はなく,開発日誌8 が見られるだけなので詳細が判らない。そのため,ここに自分なりに作成したプログラムを紹介して,ご批判を仰ぎたい。
#Canvas による画面の作成
Canvas を利用すると,美しい図形を容易に描くことができる。作成した三目並べの初期画面を,下図に示す。
この画面を表示するための JavaScript は,下に示すように,簡単である。
function boardset(){
ctx.fillStyle = 'rgb(0, 160, 80)';
ctx.rect(60, 20, 180, 180);
ctx.fill();
ctx.strokeStyle = 'black';
ctx.lineWidth = 2;
ctx.beginPath();
for (var i = 0; i <= 3; i++) {
ctx.moveTo(60, 20+60*i);
ctx.lineTo(240,20+60*i);
ctx.stroke();
}
for (var j = 0; j <= 3; j++) {
ctx.moveTo(60+60*j, 20);
ctx.lineTo(60+60*j,200);
ctx.stroke();
}
message("あなたの番です");
r2message("再度挑戦 終了");
drawsq(dx,dy,dw,dh,dr,dcolor);
drawsq(dx+110,dy,dw-30,dh,dr,dcolor);
}
#jQuery カスタム trigger の利用方法
先に述べたように,マウスボタンのクリックイベントに対して,jQuery のカスタム trigger を発行してそれを受信した時,ユーザの処理を記述する手順が必要となる。その主要部分を示すと,下記のようになる。
// ユーザーの一手
// user カスタムイベントを作成・受信
$(document).on('user', function() {
console.log('user カスタムイベントが実行されました');
if (value[p] != 0) {
message("そこは置けません");
}
else if(value[p] == 0) {
value[p] = 1;
circle(p);
turn++;
if (5 <= turn) r = judge();
if ( r == 0 ) {
// cpu にカスタムイベントを送る
message("CPU の番です");
$(document).trigger('cpu');
}
}
});
// マウスボタンのクリックイベントに対する処理
$('#board').on('click', function(e) {
var m = e.target.getBoundingClientRect();
x = e.clientX - m.left;
y = e.clientY - m.top;
if ( (60 <= x && x < 240) && (20 <= y && y < 200 )) {
if ( 60 <= x && x < 240 ) {
if( 20 <= y && y < 80 ) {
if( x < 120 ) p = 0;
else if( x < 180 ) p = 1;
else if( x < 240 ) p = 2; }
...
}
// user にカスタムイベントを送る
$(document).trigger('user');
return;
}
上記で大事な点は,$(document).trigger('user') {},すなわち,user にカスタムイベントを送る命令の前に,それを受信する命令 $(document).on('user', function() {} ) を作成しておくことである。マウスクリックイベントを受信すると,ここに制御が渡ってくるので,ユーザーの一手を記述しておく。ユーザーはその後で,cpu にカスタムイベントを送ることになる。当然ながら,このカスタムイベントを送る命令の前に,これを受信する命令を記述しておかなければならない。このように考えると,ゲームを進める構造が見えてくる。
#trigger を省略したコード改訂版について
上記のプログラムを見直したところ,わざわざ,カスタム trigger を使わなくても良いことがわかった。trigger を使わない簡潔なコードは,下記のようになる。
// マウスボタンのクリックイベントに対する処理
$('#board').on('click', function(e) {
var m = e.target.getBoundingClientRect();
x = e.clientX - m.left;
y = e.clientY - m.top;
if ( (60 <= x && x < 240) && (20 <= y && y < 200 )) {
if ( 60 <= x && x < 240 ) {
if( 20 <= y && y < 80 ) {
if( x < 120 ) p = 0;
else if( x < 180 ) p = 1;
else if( x < 240 ) p = 2; }
...
}
// ユーザーの一手
if (value[p] != 0) {
message("そこは置けません");
}
else if(value[p] == 0) {
value[p] = 1;
circle(p);
turn++;
if (5 <= turn) r = judge();
if ( r == 0 ) {
message("CPU の番です");
// コンピュータの一手
...
初版で,$(document).trigger('user') {},すなわち,user にカスタムイベントを送る命令を書いた部分に,それを受信する命令 $(document).on('user', function() {} ) の中で書いたコード部分を直接書くことによって,コードが簡潔になることがわかった。
#CPU の一手と終局の判定方法
三目並べの対局途中画面を,下図に示す。左側の図にみられるように,〇印はユーザーの手を示し,✖印は cpu の手を示す。現在,5 手まで進んだ局面である。
cpu の一手は,ランダムに決められる。すなわち,三目並べの枠 0 - 8 の数値を乱数で発生させて,対応する枠がすでに使われている場合は,再度試行する。9 回繰り返しても,空きが見つからない場合は,0 番から順に検索して,最初の空きに入れる。
ここで,枠内に描く図形と枠内を表す値は,対応関係さえあれば良い。そこで,終局の判定をしやすい値を用いた。上図の右側に示したように,ユーザーの手は 1 ,cpu の手は 10 を対応させる。これによって,縦横斜めいずれかの枠内合計値が 3 のときユーザーの勝ち,合計値が 30 のとき cpu の勝ちと判定できる。合計する枠内に相手の手が入っていても,この判定で良いことを確かめられたい。
従って,判定プログラムは,下記のように簡単になる。
function judge() {
// 勝ち
if ((value[0]+value[1]+value[2]) == 3 ||
(value[3]+value[4]+value[5]) == 3 ||
(value[6]+value[7]+value[8]) == 3 ||
(value[0]+value[3]+value[6]) == 3 ||
(value[1]+value[4]+value[7]) == 3 ||
(value[2]+value[5]+value[8]) == 3 ||
(value[0]+value[4]+value[8]) == 3 ||
(value[2]+value[4]+value[6]) == 3 ) {
message("あなたの勝ちです");
return 1;
}
...
}
#おわりに
三目並べを作るときに,HTML5 Canvas を利用する方法について述べた。本文で示したように,プログラムの可読性は良いと考えている。頭書に示した URL から,プログラム HTML と JavaScript ファイル6 をダウンロードして実行しながら見れば,より理解しやすいと思われる。