Simulator 0.5

中国ルールでプレイアウトを行い、結果をSGFとして記録し、再生できるようにしました。 石の数と活路の和を得点として表示しており、プレイアウト終局時には中国ルールでの得点(石と地の和)と等しくなります。

実行結果

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

ドキュメント

JsDoc Toolkit で作成したドキュメントはこちら

ソース

今回からソースへのリンク先には JsDoc Toolkit で作成したものを利用しています。

simulator05.html

スタイルシートの部分です。ID #sgf のフォントを Courier New に変更し、クラス .code は使用していないので削除しました。
<style>
#table {
	margin: 0;
	color: white;
	background-image: url(img/table800.jpg);
	z-index: 1;
	position: relative;
	left: 0px;
	top: 0px
}
#shadow {
	margin: 0;
	z-index: 2;
	position: absolute;
	left: 0px;
	top: 0px
}
#stones {
	margin: 0;
	z-index: 3;
	position: absolute;
	left: 0px;
	top: 0px
}
#control {
	color: white;
	height: 150px;
	width: 630px;
	font-size: small;
	background-color: #553B32;
	padding: 5px;
	border-spacing: 0;
	margin: 0;
	position: absolute;
	left: 0px;
	top: 480px
}
#sgf {
	font-family: "Courier New";
	color: black;
	background-color: white;
	height: 76px;
	margin: 10px;
	padding: 4px;
	overflow-y: scroll
}
.list {
	font-family: "Courier New" !important;
	font-size: small !important;
	border: 1px solid lightgray;
	max-height: 300px
}
</style>
実行結果を表示する部分です。viewer01.html からバージョン番号を変更し、[プレイアウト]ボタンを実装しました。
<h2>実行結果</h2>
<div style="height: 640px; width: 640; position: relative">
<canvas width="640" height="480" id="table">Simulator 0.5 には HTML5 Canvas が必要です。</canvas>
<canvas width="640" height="480" id="shadow">Simulator 0.5 には HTML5 Canvas が必要です。</canvas>
<canvas width="640" height="480" id="stones">Simulator 0.5 には 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: 40px" type="button" value="プレイアウト Playout" onclick="onPlayout()">
<input id="play" style="margin-left: 40px" type="button" value="再生 Replay" onclick="onReplay()"><br>
<span style="margin-left: 10px">得点 Score</span> <span id="sw">0</span>
<span style="margin-left: 30px">得点 Score</span> <span id="sb">0</span>
<span style="margin-left: 40px">間隔 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 実行結果 -->

simulator05.js

simulator04.js をベースにコメントを英語にしました。多くのコードは viewer01.js から持ってきました。 [プレイアウト]ボタンを押したときに起動する関数 onPlayout() で棋譜を残すように変更しました。
/**
 * 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 {
        // 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();
    }
}
ソース全体はこちら

rec02.js

Entry 関数と Rec オブジェクトの toSGF メソッドのバグを修正しました。
/**
 * Record Entry
 * @example
 * var e1 = new Entry(3, 4, BLACK);             // col = 3, row = 4, turn = BLACK
 * var e2 = new Entry(PASS, BLACK);             // means pass for BLACK
 * var e3 = new Entry(new Move(1, 2), WHITE);   // col = 1, row = 2, turn = WHITE
 * @class Represents Game Record Entry
 * @this {Entry}
 * @property {Number} x column co-ordinate of move (1 origin)
 * @property {Number} y row co-ordinate of move (1 origin)
 * @property {Number} turn turn BLACK or WHITE
 * @since 0.1
 */
Entry = function() {
    if (arguments.length == 3) {
        this.mv = new Move(arguments[0], arguments[1]);
        this.turn = arguments[2];
    } else if (arguments.length == 2) {
        if (arguments[0] == PASS) {
            this.mv = new Move(PASS);
            this.turn = arguments[1];
        } else if (arguments[0] instanceof Object) {
            this.mv = arguments[0];
            this.turn = arguments[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().toString().length == 1)
            buf += "0";
        buf += d.getMonth().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 = 1; 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 == 0) {
                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.