Simulator 0.6

中国ルールでプレイアウトを行い、結果を SGF として記録し、再生できます。Simulator 0.5 のバグ(初手が棋譜に記録されない等)を修正しました。 また、プレイアウトではなく盤上をクリックして打った手も記録、再生できるようにしました。両者がパスをすると棋譜を表示します。 石の数と活路の和を得点として表示しており、プレイアウト終局時には中国ルールでの得点(石と地の和)と等しくなります。

実行結果

Simulator 0.6 には HTML5 Canvas が必要です。 Simulator 0.6 には HTML5 Canvas が必要です。 Simulator 0.6 には HTML5 Canvas が必要です。
0 0
得点 Score 0 得点 Score 0 間隔 Interval 300
棋譜がここに入ります。 Game record will be here.

ドキュメント

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.