Simulator 0.6
中国ルールでプレイアウトを行い、結果を SGF として記録し、再生できます。Simulator 0.5 のバグ(初手が棋譜に記録されない等)を修正しました。
また、プレイアウトではなく盤上をクリックして打った手も記録、再生できるようにしました。両者がパスをすると棋譜を表示します。
石の数と活路の和を得点として表示しており、プレイアウト終局時には中国ルールでの得点(石と地の和)と等しくなります。
実行結果
ドキュメント
JsDoc Toolkit で作成したドキュメントは
こちら。
ソース
ソースへのリンク先には JsDoc Toolkit で作成したものを利用しています。expand source をクリックするとソースを展開します。元に戻すにはブラウザの[戻る]ボタンを押します。
simulator06.html
実行結果を表示する部分です。Goban で使っていた[はじめから]ボタンを復活しました。
<h2>実行結果</h2>
<div style="height: 640px; width: 640; position: relative">
<canvas width="640" height="480" id="table">Simulator 0.6 には HTML5 Canvas が必要です。</canvas>
<canvas width="640" height="480" id="shadow">Simulator 0.6 には HTML5 Canvas が必要です。</canvas>
<canvas width="640" height="480" id="stones">Simulator 0.6 には HTML5 Canvas が必要です。</canvas>
<div id="control">
<img style="vertical-align: bottom; padding-left: 10px" src="img/white22.png">
<input id="white" type="button" value="パス Pass" onclick="onPass()">
<span id="pw">0</span>
<img style="vertical-align: bottom; padding-left: 10px" src="img/black22.png">
<input id="black" type="button" value="パス Pass" onclick="onPass()">
<span id="pb">0</span>
<input style="margin-left: 20px" type="button" value="はじめから Restart" onclick="onRestart()">
<input style="margin-left: 10px" type="button" value="プレイアウト Playout" onclick="onPlayout()"><br>
<span style="margin-left: 10px">得点 Score</span> <span id="sw">0</span>
<span style="margin-left: 40px">得点 Score</span> <span id="sb">0</span>
<input id="play" style="margin-left: 50px" type="button" value="再生 Replay" onclick="onReplay()">
<span style="margin-left: 20px">間隔 Interval</span>
<input id="interval" style="margin-left: 10px" type="range" min="0" max="600" step="10">
<output for="interval" style="margin-left: 10px">300</output>
<pre id="sgf">棋譜がここに入ります。 Game record will be here.</pre>
</div><!-- end of control -->
</div><!-- end of 実行結果 -->
simulator06.js
結果を表示する部分は simulator05.js では onPlayout() の中にありましたが、他(onPass())からも呼び出せるよう showRecord() として独立させました。
/**
* Show game record
* @since 0.6
*/
function showRecord() {
// enable play button
playButton.disabled = false;
// set game record to SGF
var score = getScore(BLACK) - getScore(WHITE);
if (score == 0)
rec.score = "0";
else if (0 < score)
rec.score = "B+" + score;
else
rec.score = "W+" + (-score);
textbox = document.querySelector("#sgf");
textbox.innerHTML = rec.toSGF();
}
onClick() では棋譜を記録する処理とパスのフラグをクリアする処理を追加しました。
/**
* Mouse event handler - puts (moves) stone
* @since 0.1
*/
function onClick() {
var event = arguments[0];
var mx = event.pageX - this.parentNode.offsetLeft;
var my = event.pageY - this.parentNode.offsetTop;
var mv = brd.offsetToMove(mx, my);
if (mv.onBoard) {
brd.move(mv.col, mv.row, context3, context2);
rec.move(mv);
lastPass = false;
} else {
if (brd.p.turn == BLACK)
drawObject(mx - (PX_STONE / 2), my - (PX_STONE / 2), Z2_STONE, imgb, context2, context2);
else
drawObject(mx - (PX_STONE / 2), my - (PX_STONE / 2), Z2_STONE, imgw, context2, context2);
auError.play();
}
}
onPass() では棋譜を記録する処理、連続するパスでゲームを終了し結果を表示する処理を追加しました。
/**
* [Pass] button event handler
* @since 0.1
*/
function onPass() {
// sound of button
auSwitch.play();
brd.move(PASS, context3, context2);
rec.move(PASS);
// both pass becomes game end
if (lastPass)
inGame = false;
lastPass = true;
if (!inGame)
showRecord();
}
onPlayout() では結果の表示を単に showResult() を呼び出すだけに変更しました。
/**
* Playout timer event handler
* @since 0.5
*/
function onPlayout() {
if (!inGame) {
// enable play button
playButton.disabled = false;
// prepare game record
rec = new Rec(ro);
resetGame();
inGame = true;
}
if (0 < brd.p.c.abs()) {
// if there are possible moves, select one of them randomly
// TODO check whether this random number works correctly
var i = Math.floor(Math.random() * brd.p.order) + 1;
for (; ; i++) {
if (brd.p.order < i)
i = 1;
if (brd.p.c.getValue(i) == 1)
break;
}
var mv = brd.p.toMove(i);
brd.move(mv, context3, context2);
rec.move(mv);
lastPass = false;
} else {
// if there are no possible moves, pass
auSwitch.play();
brd.move(PASS, context3, context2);
rec.move(PASS);
// both pass becomes game end
if (lastPass)
inGame = false;
lastPass = true;
}
if (inGame)
window.setTimeout(onPlayout, ms);
else {
showRecord();
}
}
[はじめから]ボタンのイベントを処理する onRestart() を追加(復活)しました。
/**
* [Restart] button event handler
* @since 0.6
*/
function onRestart() {
// enable play button
playButton.disabled = false;
// prepare game record
rec = new Rec(ro);
resetGame();
inGame = true;
}
ソース全体は
こちら。
rec03.js
棋譜の日付の月がずれるバグと初手が記録されないバグをを修正しました。どちらも Small Basic では 1 オリジンだったものが JavaScript では 0 オリジンに変わっているのに 1 のまま処理していたのが原因です。
/**
* Convert to SGF
* @return {String} SGF string
* @since 0.1
*/
toSGF : function() {
// game of Go, format version, size of board
var buf = "(;GM[1]FF[4]SZ[" + this.ro + "]";
// player name
buf += "PB[" + this.players[P_BLACK] + "]PW[" + this.players[P_WHITE] + "]";
// score
buf += "RE[" + this.score + "]\n";
buf += "DT[";
var d = this.date;
buf += d.getFullYear().toString() + "-";
if ((d.getMonth() + 1).toString().length == 1)
buf += "0";
buf += (d.getMonth() + 1).toString() + "-";
if (d.getDate().toString().length == 1)
buf += "0";
buf += d.getDate().toString();
buf += "]KM[0.0]RU[Chinese]\n";
buf += "AP[" + programName + ":" + programVer + "]CA[UTF-8]\n";
for (var i = 0; i < this.record.length; i++) {
var turn = this.record[i].turn;
if (turn == BLACK)
buf += ";B[";
else if (turn == WHITE)
buf += ";W[";
if (!this.record[i].mv.isPass) {
var col = this.record[i].mv.col;
var row = this.record[i].mv.row;
buf += ALPHA.charAt(col - 1) + ALPHA.charAt(row - 1);
}
buf += "]";
if (i % 10 == 9) {
buf += "\n";
}
}
buf += ")\n";
return buf;
}
ソース全体は
こちら。
sgfparser02.js
viewer01.html から変更はありません。
ソース全体は
こちら。
lex04.js
viewer01.html から変更はありません。
ソース全体は
こちら。
source01.js
viewer01.html から変更はありません。
ソース全体は
こちら。
board06.js
viewer01.html から変更はありません。
ソース全体は
こちら。
pos09.js
viewer01.html から変更はありません。
ソース全体は
こちら。
move04.js
viewer01.html から変更はありません。
ソース全体は
こちら。
bvector07.js
viewer01.html から変更はありません。
ソース全体は
こちら。
bmatrix05.js
viewer01.html から変更はありません。
ソース全体は
こちら。
Copyright © 2012-2017 たかはしのんき. All rights reserved.