第24回世界コンピュータ将棋選手権出場記

zu

■はじまりから直前まで プログラムの話

 去年はどえらいバグを抱え込んでしまっていて散々な成績に終わった。
 一番ひどかったのは、「反復深化をするとき、前回の最善手を一番最初に呼ばない」バグ(?)。これのせいで、いったん自玉の詰みを見つけてその手がダメだと判っても、次の反復深化に入るとそれを忘れて1から読み直してしまうのだ。で、白砂将棋(というか元のれさぴょん)は深さ2以上では詰ルーチンを呼ばないので、深さが3以上になると自玉の詰みに気づかなくなり、のんきに駒得に走ってトン死してしまう、というもの。去年の初戦(第1図)がまさにこれだった。痛かった。
 あと、地味ながらキツかったのが、Evalからちゃんと評価値が返ってこない問題。
 そのままだとちゃんと評価値が返って来ないのに、maxを使っている部分を2行に分けるとなぜかうまくいく、という不思議な状況だった。Evalは頻繁に呼ばれる関数でもあるため、ちょっとしたことのようだが、結構速度低下を招いていたのだ。
 ところがあるとき、これについて、GA将!!!!!!!さんからこんなメールをいただきました。
白砂様の以前の選手権出場記を読み返していて、ふと気になった事がありましたので
メールさせていただきました。

http://www.hakusa.net/shogi/computer/wcsc22_1.html の4月30日のバグなのですが、
ひょっとしたらマクロがらみの現象の可能性があるのではないかと。

もともとのコードは下記のようになっているとの事でした。

> return max(v,
>         EvalMin(AtackS+1,NumAtackS-1,AtackE,NumAtackE));

ここで、仮に「maxがマクロ定義されている」かつ「EvalMinの呼び出しが副作用を伴う」
場合は上手く動かない(バグが発生する)のではないかと。

たとえばmaxが下記のようになっていれば、EvalMinが2回呼び出されてしまう事があり、
バグの原因になるかと思います。

#define max(X,Y) (((X) > (Y)) ? (X) : (Y))

外している可能性もありますが、何かの参考になれば幸いです。
 なるほど。状況はピッタリ当てはまるし、これかもしんない。
 で、ぐぐってみると、確かにそういう情報が出てくる。例えばここ。
error C3861: 'min'識別子が見つかりませんでした
  • 'max'も同じく
  • Visual Studio 2005からVisual Studio 2008に変更したら起きた
  • どうやら,min,maxは非標準のマクロだったらしい.
  • std::min, std::maxでリプレースするのが妥当かと
http://tessy.org/wiki/index.php?C%2FC%2B%2B%A4%CE%A5%C8%A5%E9%A5%D6%A5%EB%BD%B8#ua5dc299
 まさにこれか。
 これを修正したらちゃんとEvalが正しい値を返すようになった。
 こんな感じで今年もスタート。
 こんなところでウロウロしてたら、そりゃあ強いソフトなんか作れるわけないよなorz。

 次に不思議だったのが成と不成の問題。
 例えば、▲1三歩成と▲1三歩不成という候補手があったとすると、白砂将棋(れさびょん)は何故か▲1三歩不成と指す。

 調べてみたところ、原因は2つあった。

 1つは、深さ1のときに起きる問題。
 とある局面で、▲1三歩成と▲1三歩不成の評価値の詳細を見てみたところ、こんな風になっていた。
                                                         SemegomaValueS                          KomagumiBonus       SemegomaBonus       MamorigomaBonus
 末端 13歩(14) v: -1414 value: -1225 E: -1209 B:  -205 SS:    -2 SE:   -49 MS:    49 ME:    10 K0:     9 K1:     7 S0:  -200 S1:   145 M0:   125 M1:   -92 終▲:-2 終△:-2 
 末端 13歩成(14)v: -1429 value:  -125 E:  -124 B: -1305 SS:    -2 SE:   -49 MS:    49 ME:    10 K0:    -6 K1:     7 S0:  -202 S1:   145 M0:    76 M1:   -92 終▲:-2 終△: 0 
 KomagumiBonusのところで出入り15点分違っている。ちなみに、SemegomaBonus、MamorigomaBonusもポイントが違っているが、実はこの局面の終盤度が0であり、評価値には反映されないので、ここではとりあえず関係がない。

 じゃあKomagumiBonusがどのように計算されているか……と調べてみると、こんな風になっていた。ちなみにこれはSenkeiInit()の一部
for(suji=0x10;suji<=0x90;suji+=0x10) {
	for(dan=1;dan<=9;dan++) {
		value-=KomagumiValue[ban[suji+dan]][suji+dan];
		for(koma=SFU;koma<=ERY;koma++) {
			if (koma==SGI) {
				JosekiKomagumi[Senkei][koma][suji+dan]=JosekiKomagumiSGI[Senkei][dan-1][9-(suji/0x10)];
			} else if (koma==EGI) {
				JosekiKomagumi[Senkei][koma][suji+dan]=-JosekiKomagumiSGI[GyakuSenkei][9-dan][suji/0x10-1];
			} else if (koma==SKI) {
				JosekiKomagumi[Senkei][koma][suji+dan]=JosekiKomagumiSKI[Senkei][dan-1][9-(suji/0x10)];
			} else if (koma==EKI) {
				JosekiKomagumi[Senkei][koma][suji+dan]=-JosekiKomagumiSKI[GyakuSenkei][9-dan][suji/0x10-1];
			} else if (koma==SOU) {
				JosekiKomagumi[Senkei][koma][suji+dan]=JosekiKomagumiSOU[Senkei][dan-1][9-(suji/0x10)];
			} else if (koma==EOU) {
				JosekiKomagumi[Senkei][koma][suji+dan]=-JosekiKomagumiSOU[GyakuSenkei][9-dan][suji/0x10-1];
			} else {
				JosekiKomagumi[Senkei][koma][suji+dan]=DanValue[koma][dan];←←←←←←←←←←←←その他の駒はここでカウント
			}
			KomagumiValue[koma][suji+dan]=JosekiKomagumi[Senkei][koma][suji+dan];
		}
		if (ban[suji+dan] & SELF) {
			KomagumiBonus[0]+=KomagumiValue[ban[suji+dan]][suji+dan];←←←←←←←←←←←←←←←←←先手の駒の時はここに入る。
		} else if (ban[suji+dan] & ENEMY) {
			KomagumiBonus[1]+=KomagumiValue[ban[suji+dan]][suji+dan];
		}
	}
}
 玉金銀についてはJosekiKomagumiXXXから、それ以外の駒はDanValueから持ってきている。
 で、DanValueがこれ。
//歩      1  2  3  4 5 6  7  8  9
	{ 0,  0,15,15,15,3,1, 0, 0, 0},
//と     1  2  3  4  5  6  7  8  9
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 歩は3段目にあると+15点されるのに、と金の場合は加算はない。なので、と金を作るより歩がある方が高く評価されてしまう。この不整合(?)が原因の1つ目である。

「いやいや、と金を作った方がいい局面に決まってんでしよ」
 という反論が聞こえてきそうだが、そこで出てくるのが原因の2つ目。
 例えば、▲1三歩成とと金を作る。
 そのとき、白砂将棋(れさびょん)は「▲1三歩成の局面」の評価を返して終わり、としない。「▲1三歩成の局面で、相手が一番価値の高い駒を取り返した局面」の評価を返してくるのだ。れさびょんのソースでいうと、Evalute()+BestEval(SorE)の「+BestEval(SorE)」の部分である。
 これがあるので、今回の例でいうと1三に作ったと金よりも得点の高い駒が落ちていない(取り返せない)場合、▲1三歩成だろうと▲1三歩不成だろうと、後手が△1三同角と指したことにしてその局面の評価値を返してくる。要するに成ろうが成るまいが同一局面になる。そうすると、最初に評価した局面が(たぶん)残り、最初に評価した▲1三歩不成が最善手となってしまうのだ。
 原因1のDanvalueを正した後、指し手の生成順を成からやる、とかすればうまくいくのかもしれないが、のちのち指し手の逐次生成なんかをやった時にややこしいことになってしまうかもしれない。そう考えて、これを正面から直すのはやめにして(<をい)、飛角歩は必ず成るという指し手生成関数を作ることでムリヤリ解決することにした。

zu  また、「直前の手の取り返し」と「タダの駒を取る手」なども入れてみることにした。
「直前の手の取り返し」は「さっきの指し手のtoに動く手を生成」だし、「タダの駒を取る手」は、盤面をサーチして「浮き駒の場所(to)に動く手を生成」だから、どっちもMoveToを使えばいいか、とか簡単に考えていたがそんなに甘くなかった。
 例えば第2図。この局面で、MoveToは▲6八玉を生成しない。

 うそ一ん、と思ってソースを見たら、こうなっていた。
void Kyokumen::MoveTo(int SorE,int &teNum,Te *teTop,int to,int* pin)
{
	int p;
	KomaInf koma;

	for(int i=0;i<12;i++) {
		if ((koma=ban[to-Direct[i]]) == EMPTY) {
			p=search(to,-Direct[i]);
			if ((ban[p]&SorE) && CanJump[i][ban[p]]) {
				AddMove(SorE,teNum,teTop,p,to-p,pin[p]);
			}
		} else {    ↓↓↓↓↓↓↓↓…………………………………ここが問題?
			if ((koma&~SorE)!=OU && (koma&SorE) && (CanMove[i][koma]||CanJump[i][koma])) {
				AddMove(SorE,teNum,teTop,to-Direct[i],Direct[i],pin[to-Direct[i]]);
			}
		}
	}
}
 なんと、 MoveToでは玉が動くことを想定していないのだ。
 実は、玉の場合はMoveKing関数を使う必要があった。王手とかpinがらみが少し複雑なので、分けているのである。

 これ以外にも、pinを考慮し忘れていたりとか、王手がかかっている時はどうするかとか、細々としたエラーが続き、結局かなり時間がかかってしまった。
 また、探索局面で王手がかかっている場合、王手の応手を生成すべきなので、MakeMoveFirstに入らずにすぐにM(の中のAntiCheck)を呼ぶようにした。

 さきほどBestEvalの話をしたが、末端の処理をもっとちゃんとした(?)のにしようと思い、駒を取る手や歩が成る手だけを読む静止探索を導入しようとしてみた。
 ところがこれがまた大変で、というか自分がよく理解していないからなのだが、符号の+-を間違えたりとか、後手番の反転を忘れたりとか、上でも出た王手がかかった時の対応とか、まあつまづくつまづく。一時はどうなるかと思った。
 大体が、一番最初にやっちゃったのがこれ。
//生成した指し手について処理する
for(i=0;i<teNum;i++) {
	KyokumenKomagumi kk(k);
	Stack[depth]=teBuf[i];
	kk.Move(SorE,teBuf[i]);
	int v=-qsearch(SorE==SELF?ENEMY:SELF,k,-beta,-max(retval,alpha),depth+1,depthMax);	//1手深く読む

局面kを渡したって元の局面だろうがそれはよー。
 どうりで同じ値しか返って来ないはずだorz。

 そんなこんなでエラい苦労をしたのだが、静止探索を導入した効果は結構高く、まあ静止探索は候捕手がそもそも少ないから当たり前ではあるんだけど、相当深く読んでくれる。いっそのこと打ち切り手数をなくすか、とまで考えてしまったが(笑)、さすがにそれはやりすぎだろうと考えて8手で打ち切ることとした。
 その他、静止探索にハッジュ表を導入したり、けど時間がかかったり不安定になるのでやめたりとか(笑)、いろいろやっていた。

 これに関連して、というかあんまりミスばっかするのでEvaluteTe(SorE)を確認することが多くなって、せっかくなんてソースをちゃんと読んでみよう、と思って読んでみたら、なんかおかしいぞ、と思う部分かあった。
 それがこの部分。脅威の計算。コメントは白砂がつけたものなので、間違ってるかもしれない。
// 移動したことで、別の駒の飛び利きを通す(かも知れない)
if (te[i].from>OU) {	//駒移動なら、
	for(dir=0;dir<8;dir++) {									//周囲8方向を調べる(飛駒があるかどうかを調べたいので)
		if ((_nowControlS[te[i].from]& (1<<(dir+16))) !=0) {	//移動前の駒位置にdir方向からの自分の駒の利きがあったら
			int p=_new.search(te[i].from,Direct[dir]);			//現在の駒がなくなったものとして、利きの先を調べる
			if (_new.ban[p]!=WALL) {							//その場所pの駒が壁ではない
				// 飛び利きの通った先での交換値の再計算
				if (IsEnemy(SorE,_new.ban[p])) {				//その場所pの駒が相手の駒であるなら
					LossE+=_new.Eval(p);							//その場所pの交換値を相手の失点とする
				} else if (IsSelf(SorE,_new.ban[p])) {			//その場所pの駒が自分の駒であるなら
					GainS+=Eval(p)-_new.Eval(p);					//その場所pの、手を指す前と指した後の交換値の差分を自分の得点とする
				}
			}
		}
	}
}
 ここでなにがやりたいかというと、コメントの通り、ある手を指して駒が移動したことで、その駒がさえぎっていた飛駒の利きが通り、利きの先の状況が変わるかもしれない。その可能性を調べている。
 具体的には、こういう感じにしたいものと推察される。  しかし、上記のソースでは、自分の駒の利きが通った場合については計算しているものの、相手の駒の利きが通った場合については計算していないのではないか。
 というわけで、こういう風にするのが正しいのではないだろうか。
// 移動したことで、別の駒の飛び利きを通す(かも知れない)
if (te[i].from>OU) {
	for(dir=0;dir<8;dir++) {
		//自分の駒の利きが通った場合
		if ((_nowControlS[te[i].from]& (1<<(dir+16))) !=0) {
			int p=_new.search(te[i].from,Direct[dir]);
			if (_new.ban[p]!=WALL) {
				// 飛び利きの通った先での交換値の再計算
				if (IsEnemy(SorE,_new.ban[p])) {
					LossE+=_new.Eval(p);
				} else if (IsSelf(SorE,_new.ban[p])) {
					GainS+=Eval(p)-_new.Eval(p);
				}
			}
		}
		//相手の駒の利きが通った場合
		if ((_nowControlE[te[i].from]& (1<<(dir+16))) !=0) {
			int p=_new.search(te[i].from,Direct[dir]);
			if (_new.ban[p]!=WALL) {
				// 飛び利きの通った先での交換値の再計算
				if (IsEnemy(SorE,_new.ban[p])) {
					GainE-=Eval(p)-_new.Eval(p);
				} else if (IsSelf(SorE,_new.ban[p])) {
					LossS-=Eval(p);
				}
			}
		}
	}
}
 ちゃんと相手の駒の利きが通った場合についても考慮する必要がある。
 で、こんな局面(第3図)を調べてみると……
zu
45金(55)  v:-166
  d 0: 
  d 1: 
  d 2: 
  d 3: 
  d 4: 
  d 5: CE:2097152 from:55 dir: 15 p:73 k:v銀 GainE v:-2135←←←←←ちゃんと後手の銀を救済している。
  d 6: CS:12582912 from:55 dir: -1 p:53 k: 桂 GainS v: 1435 
  d 7: CS:12582912 from:55 dir:-17 p:33 k:v飛 LossE v: 3070 
45金(55) val: 1726 LossS:    0 LossE: 3070 GainS: 1435 GainE:-2135

 また、少し変えてこんな局面(第4図)でも、
zu
45金(55)  v:-186
  d 0: 
  d 1: 
  d 2: 
  d 3: 
  d 4: 
  d 5: CE:2097152 from:55 dir: 15 p:73 k: 銀 LossS v: -115←←←←←ちゃんと先手の銀取りを評価している。
  d 6: CS:12582912 from:55 dir: -1 p:53 k: 桂 GainS v: 1435 
  d 7: CS:12582912 from:55 dir:-17 p:33 k:v飛 LossE v: 3070 
45金(55) val: 1839 LossS: -115 LossE: 3070 GainS: 1435 GainE:    0

 やっぱりちゃんと評価している。
 このほうがいいんじゃないだろうか。
 というわけで、この部分はれさぴょんを離れて白砂独自のものを使っている。
 ……合ってるよなあこの考え方で……。
 その他、いろんな情報、例えばNPSなんかも表示できるようにしてみたり(←エラーがあまりにも多いんでねorz)、いろいろやっていた。

■はじまりから直前まで プログラム以外の話

 さて、去年まではというノートパソコンで参加していたのだが、まあせっかくここまで頑張っていろいろ開発バグ生成とマッチポンプ(泣)をやっていたことだし……という言い訳の元、ノートパソコンを新しくすることにした。なんだか「買い物症候群」患者の言い訳のようだ(笑)
 とはいっても、いくら速くてもあんまりクソ重いPCだと車で現地に行くのが大変だし、かといってCPUがしょぽいと新調する意味がない。画面もできれば現在の13.3インチより大きい方がいい。
 てことでいろいろ調べるうち、これだ! と思ったのがSONY VA10 Type S。15インチの画面に、Core i7-3632QM(2.20GHz。最大3.20GHz)という4コアCPU、メモリも最大で12G積めて、それで重量がたったの2.0kgしかない。薄くて軽くて、でも速くて画面も大きい。まさにうってつけのPCだ。
 狙いは決まったし、とはいえ別に新品を買う必要もないし……ということでのんぴりヤフオクを漁っていたところ、うまい具合にSVS1512AJという機種が7万円で落札できた。
 これでかなり読む速度はアップできるはずだ。

 こっちでお金を使ってしまったので、宿の方は節約して、グランパークホテルエクセル木更津にした。白砂は神奈川県から車なので頑張ればその日のうちに来たり帰れたりするんだけど、前日まで仕事だし、さすがにムチヤができる年齢でもないので、少しぜいたくに前泊後泊することにした。

 また、食事についてもWebでいろいろと調査して、いくつかうまそうな店の目星をつけておいた。

 PCも買ったし(白砂はVA10信者ではないけれど、このTypeSの白はかなりお気に入りになった)、宿も決めたし、ということで、頑張って開発バグ生成とマッチポンプ(泣)に勤しむことにした。
 そんな4/29。

モーニング娘。’14 道重さゆみに関するお知らせ

私、道重さゆみは、
今年2014年のモーニング娘。'14の秋ツアーの最終日をもって、モーニング娘。を卒業します。

私は、約二年前にリーダーになった時から「モーニング娘。に恩返しがしたい」と言ってきました。

そんな中、私の力だけではないですが、シングルで5作連続1位をいただけたり、
いろんな活動を通して、少しずつ、少しずつ、恩返しができたかな、と感じています。

そこで、つんく♂さんや事務所の方と相談して、今年の秋ツアーのタイミングで卒業という事にさせていただきました。

ですが、まだまだ時間はあるし、もっともっと後輩たちに伝えたい事や、
みせたいと思っている事もあります。
ファンのみなさまとも、たくさんの思い出を作りたいと思っています。

そして、ここからが本当の「恩返し」だと思っています。
超超超いい感じのモーニング娘。に仕上げてから卒業し、
次の世代にバトンタッチしたいと思っています。

秋までよろしくお願い致します。
2014年4月29日
モーニング娘。'14リーダー
道重さゆみ
http://www.helloproject.com/news/1657/

ちゃ、ちゃゆうううううううううううううううっっっっっっっ!!!!!!!!!!!

■はじまりから直前まで ふたたびプログラムの話

 もう、なんかどうでもいいや……。
 そんな虚無感に襲われつつ、それでも開発という名のマッチポンプが続く。その一端がこれ。
 静止探索を導入していろいろやっている頃、そろそろ本番の環境で動かした方がいいんじゃなかろうか、ということで、今で開発していたデスクトップ(自作。CPU:Q6600/メモリ:12G)ではなく、ノートPCで実行してみた。

……オチた。

 ソースは一緒だし、ということは環境かなあ……ということで将棋所の動作要件を見てみたけど、NET Framework 4.0が必要、くらいしか思いつかない。あと違う所と言えば、デスクトップはWindows7でVAIOがWindows8なことくらいか。
 なんだろうなあもうorz。
 で、しばらくいじったりエラー箇所を突き止めたりしているうちに、原因が判った。
↓これ。
その他、いろんな情報、例えばNPSなんかも表示できるようにしてみたり(←エラーがあまりにも多いんでねorz)、いろいろやっていた。
 NPSの表示なんて、消費時間で割り算をしているんだけど、VA10のCPUが早すぎて1秒を切って処理できている局面があって、その時にO除算で落ちていたらしい。なんてこった。
 けどまあ、新調したPCの性能がいいということがわかっただけでもよしとするか(<よくない)。
 その他、れさぴょんが遅いので自前で作っていた王手生成ルーチンにまだバグが潜んでいたり(香の王手生成に不備があった←今更かよ)、定跡ファイルを先手後手で別に読めるようにしたり、細々とした修正をしているうち、5/2になってしまった。

 ちなみに、ここには書いていないものの、探索部分も大幅にいじって、NullMove枝刈りなども導入してみたのだが、また今年も失敗した(泣)。今こうやって振り返ってみると、そもそも静止探索レベルでこんだけミスっているわけで、そりゃあムリだよなあorz

■はじまりから直前まで ふたたびプログラム以外の話

 行動プランとしては、5/2の午後に休みをもらって(職場から直接車で)木更津まで行き、可能であれば接続テスト。ただ、上記までで判る通り、テストよりまだまだやらないといけないことがたくさんあるので、接続テストは諦めてホテルで開発を続けることにした。
 幸い道路は空いていて、混んでいたのはトイレ休憩に寄った海ほたるくらい。14:30くらいにはホテルの駐車場に車を入れることができた。
 チェックインは15:00からなので、フロントで「昼食を喰ってくるから停めさせてほしい」と頼んで、車を置いて徒歩で駅前へ。
 少し遅い昼食だが、「ラビン」という喫茶店で、しょうが焼き定食(ご飯大盛り)を食べた。
zu

■はじまりから直前まで 三たびプログラムの話

 チェックインしてからすぐPCを立ち上げ、とはいえ運転の疲れもあるので、将棋所で連続対戦をさせながら少し仮眠を取った。
 その中の一場面が第5図。

 ここから、▲6三歩成△同金▲6四歩△5三金▲9六角△1九金▲6三歩成△同銀▲同角成として敵陣突破。

 ちゃんと「数の攻め」を読んでくれるようになっている。静止探索で駒の取り合い読むということは、こういう数の攻めの局面を狭く深く読むということだから、なり効果が大きいんだな。少し嬉しくなった。
zu  で、調子に乗って、floodgateで対戦してみた。その1局面がこれ(第6図)。
 この局面で▲4六角という手が最善手に出てこない。わざわざ▲3七銀と上がり、飛角交換後△6九飛と打たれて死んでいる。
 これもかなり長いこと考えてしまった(おかげて夕飯は予定を変更して立ち食いソバになってしまった)が原因は↓これだった。
 また、探索局面で王手がかかっている場合、王手の応手を生成すべきなので、
MakeMoveFirst に入らずにすぐにM(の中のAntiCheck)を呼ぶようにした。
(少し上の文章ですorz)
 MakeMoveFirstは「前回の最善手」その他を生成しているが、それは王手の応手を考慮していないものの、王手の応手を生成しないというわけではない。前回の最善手が王手の応手ということだったあるわけだ。なので、確かに王手がかかっている局面ではMakeMoveFirstはムダになるかもしれないが、それでも王手か否かにかかわらず、やっぱりMakeMoveFirstはちゃんと呼ばないといけないのだ。
 ここを修正したらちゃんと▲4六角を生成するようになった。

 とりあえず開発はここで打ち止め、floodgateにブチ込んで寝ることにした。
 しかし、12時過ぎにはベッドに潜ったのだが、なかなか寝付けない。寝床が変わると寝られない質だというのもあるし、明日の緊張もある。
 そして2時過ぎだろうか、VAIOがなんかエラー音を発した。
 電気をつけて起き上がり、PCを開いて見ると、floodgate対局中に落ちている。
 連続対戦のためのエラーか、それとも白砂将棋のバグか。
 とはいえ、この時間からバグ取りというのはムリがありそうなので、諦めて再びベッドに潜った。
 結局眠れたのは5時くらいだろうか。

■はじまりから直前まで 三たびプログラム以外の話

 朝は7:45に起きてホテルの朝食バイキングに行った。
 ほとんど眠れずに食欲はなかったが、さすがになんか体に入れとかないとまずいよな……と考え、おかゆやフルーツジュースなどを中心にムリヤリ詰め込んだ。
 8:40にホテルを出発。会場のかずさアークに向かった。
 ほとんど渋滞もなく、というか車がそもそもなく(笑)、途中のコンビニで昼食を調達したりしたのに9時くらいには到着していたと思う。
 受付を済ませてセッティング。
 偶然、Evalの件でメールをいただいたGA将!!!!!!!さんが隣だったので、メールのお礼かたがたなり金将棋さんを交えて雑談をしていた。
 その後、なのはの筐体を見たり(笑)、会場をグルグル回っていたりしているうちに開会時間となった。なんか開会式がいつも以上にぐたぐだと始まりダラダラ終わった気がするのは気のせいだろうか。

そうか、黒い人がいないからか(<違う)

 開会式後は、対局に向けてネットワークの設定をしてサーバに接続。
 毎回「あれ、どこに何入れんだっけ?」と不安になるので、今年設定した内容をここに貼っておこう。来年の自分、ここを見なさい(爆)。
zu
 ……そういえば、今年はネットワーク障害でなかなか開始しなかったり落ちたりしてたなぁ……。

この設定が原因だったらごめんなさい。

 そんなこんなで、1回戦が始まった。

 


初版公開:2014年5月17日
copyright © S.Hakusa