Simulator 0.4
中国ルールでプレイアウトを繰り返し、勝敗の統計を取る予定ですが、今回はプレイアウトを1回ずつ行うようにしました。
石の数と活路の和を得点として表示しており、プレイアウト終局時には中国ルールでの得点(石と地の和)と等しくなります。
勝敗の記録は取れません。
実行結果
ソース
前回からソースへのリンク先には JsDoc Toolkit で作成したものを利用しています。
simulator04.html
スタイルシートの部分です。変更はありません。
<style>
hr.colored {
border-color: goldenrod
}
#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: 48px;
width: 630px;
background-color: #26130D;
padding: 5px;
border-spacing: 0;
margin: 0;
position: absolute;
left: 0px;
top: 480px
}
.list {
border: 1px solid lightgray;
max-height: 300px
}
</style>
実行結果を表示する部分です。バージョン番号を変更し、[プレイアウト]ボタンを実装しました。
<h2>実行結果</h2>
<div style="height: 540px; width: 640; position: relative">
<canvas width="640" height="480" id="table">Simulator 0.4 には HTML5 Canvas が必要です。</canvas>
<canvas width="640" height="480" id="shadow">Simulator 0.4 には HTML5 Canvas が必要です。</canvas>
<canvas width="640" height="480" id="stones">Simulator 0.4 には 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="pass()">
<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="pass()">
<span id="pb">0</span>
<input style="margin-left: 40px" type="button" value="プレイアウト Playout" onclick="playout()"><br>
得点 Score <span id="sw">0</span>
得点 Score <span id="sb">0</span>
</div><!-- end of control -->
</div><!-- end of 実行結果 -->
simulator04.js
[プレイアウト]ボタンを押したときに起動する関数 playout() を新設しました。window.setInterval() を使って300ミリ秒毎に次の手を打つようにしました。これ以上速いと石を打った音が飛んでしまいます。
/**
* [プレイアウト]ボタンの処理
* @since 0.4
*/
function playout() {
// ボタンの音を鳴らす。
auSwitch.play();
// 碁石と影のレイヤーをクリア
context3.clearRect(0, 0, context3.canvas.width, context3.canvas.height);
context2.clearRect(0, 0, context2.canvas.width, context2.canvas.height);
// アゲハマのクリア
showPrisoner(BLACK, 0);
showPrisoner(WHITE, 0);
// 得点のクリア
showScore(BLACK, 0);
showScore(WHITE, 0);
// 黒番から
brd.clear();
passButton[BLACK].disabled = false;
passButton[WHITE].disabled = true;
// プレイアウト
var lastPass = false;
var timer = window.setInterval(function() {
if (0 < brd.p.c.abs()) {
// 着手可能な手があればその中からランダムに1手選んで打つ
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.col, mv.row, context3, context2);
lastPass = false;
} else {
// なければパス
auSwitch.play();
brd.move(PASS(brd.p.ro), PASS(brd.p.ro), context3, context2);
// 両者パスならば終局
if (lastPass)
window.clearInterval(timer);
lastPass = true;
}
}, 300); // 300ms間隔で次の手を打つ
}
ソース全体はこちら。
リンク先をご覧下さい。
board05.js
変更はありません。
リンク先をご覧下さい。
pos08.js
ブール変数 playout の名前を isPlayoutRule に変更しました。着手可能点をプロパティ Pos.c (candidateの頭文字) として保持するようにしました。
これに伴い空点 l、アタリ h、コウ k は着手後のベクトルを保持するようにしました。
/**
* BWモデルに関連するベクトルと行列を計算します。計算の対象は以下のとおり。
* a - 着手iによって形成される連を表すベクトル
* d - 着手iによって削除される石を表すベクトル
* A - 着手iによって追加される連接点を表す行列
* D - 着手iによってリセットされる連接点を表す行列
* b - 着手後の黒石∨空点を表すベクトル
* w - 着手後の白石∨空点を表すベクトル
* l - 着手後の空点を表すベクトル
* F - 着手後の連接点を表す行列
* k - 着手後のコウを表すベクトル
* h - 着手後のアタリの石の集合を表すベクトル
* c - 着手後の着手可能点を表すベクトル
* ib - 着手後の黒石の活路を表すベクトル
* iw - 着手後の白石の活路を表すベクトル
* @param col 着手する点iの横座標
* @param row 着手する点iの縦座標
* @since 0.3
*/
calcVectors : function(col, row) {
if (row == 0 && col == 0)
return;
var z = new BVector(this.order); // all 0 (zero)
var mv = new Move(col, row);
if (!mv.isPass(this.ro)) {
var i = this.toIndex(col, row); // 着点
var ei = new BVector(this.order);
ei.setValue(i, 1);
var Fei = this.F.mul(ei); // 着点を連接点とする交点
var F0ei = this.F0.mul(ei); // 着点の隣接点
if (this.turn == BLACK) {
this.a = (Fei.diff(this.w)).or(ei); // 着点を連接点とする黒石と着点
this.d = (Fei.and(this.h)).diff(this.b); // 着点を連接点とする白石のアタリの連
if (F0ei.diff(ei).and(this.b).abs() == 0 && this.d.abs() == 1)
this.k = this.d;
else
this.k = z;
this.b = this.b.or(this.d);
this.w = this.w.diff(ei);
this.prisoner[P_BLACK] += this.d.abs();
} else if (this.turn == WHITE) {
this.a = (Fei.diff(this.b)).or(ei); // 着点を連接点とする白石と着点
this.d = (Fei.and(this.h)).diff(this.w); // 着点を連接点とする黒石のアタリの連
if (F0ei.diff(ei).and(this.w).abs() == 0 && this.d.abs() == 1)
this.k = this.d;
else
this.k = z;
this.b = this.b.diff(ei);
this.w = this.w.or(this.d);
this.prisoner[P_WHITE] += this.d.abs();
}
var tF = this.F.tran(); // Fの転置(着手前)
this.A = this.a.cross(tF.mul(this.a));
var o = new BVector(this.order, 1); // all 1 (one)
this.D = this.F0.or((this.d.inv()).cross(o));
this.F = (this.F.or(this.A)).and(this.D);
this.l = this.b.and(this.w);
this.ib = (tF.mul((this.w).inv())).and(this.l); // 黒石の活路
this.liberty[P_BLACK] = this.ib.abs(); // 黒石の活路の数
this.iw = (tF.mul((this.b).inv())).and(this.l); // 白石の活路
this.liberty[P_WHITE] = this.iw.abs(); // 白石の活路の数
} else {
this.k = z;
}
tF = this.F.tran(); // Fの転置(着手後)
for (var i = 1; i <= this.order; i++) {
var ei = new BVector(this.order);
ei.setValue(i, 1);
var tFei = tF.mul(ei);
if ((tFei.and(this.l)).abs() == 1)
this.h.setValue(i, 1);
else
this.h.setValue(i, 0);
}
if (isPlayoutRule) {
var rb = new BVector(this.order); // プレイアウトでの黒石の着手禁止点を表すベクトル
var rw = new BVector(this.order); // プレイアウトでの白石の着手禁止点を表すベクトル
var z = new BVector(this.order); // all 0 (zero)
for (var i = 1; i <= this.order; i++) {
var ei = new BVector(this.order);
ei.setValue(i, 1);
var F0ei_ei = this.F0.mul(ei).diff(ei);
if (F0ei_ei.diff(this.w.inv().diff(this.h)).equals(z))
rb.setValue(i, 1);
if (F0ei_ei.diff(this.b.inv().diff(this.h)).equals(z))
rw.setValue(i, 1);
}
if (this.turn == BLACK)
this.c = this.F.mul(this.w.xor(this.h)).and(this.l).diff(this.k).diff(rw);
else if (this.turn == WHITE)
this.c = this.F.mul(this.b.xor(this.h)).and(this.l).diff(this.k).diff(rb);
else
return false;
} else {
if (this.turn == BLACK)
this.c = this.F.mul(this.w.xor(this.h)).and(this.l).diff(this.k);
else if (this.turn == WHITE)
this.c = this.F.mul(this.b.xor(this.h)).and(this.l).diff(this.k);
else
return false;
}
},
ソース全体はこちら。
リンク先をご覧下さい。
move03.js
変更はありません。
リンク先をご覧下さい。
bvector07.js
変更はありません。
リンク先をご覧下さい。
bmatrix05.js
変更はありません。
リンク先をご覧下さい。
ドキュメント
JsDoc Toolkit で作成したドキュメントは
こちら。
Copyright © 2012-2017 たかはしのんき. All rights reserved.