読者です 読者をやめる 読者になる 読者になる

Valgrindのエラーメッセージだけを出力したい

最近、プライベートではなぜかCを書くことが多くて、その過程で今更ながらValgrindを使うようになった。

で、使っているうちにValgrindのエラーメッセージだけを表示したくなったので、そのやり方をメモ。 環境は以下のとおり。

一応明記しておくと、Valgrindのバージョンは3.10.0。 シェルはbashなので、それ以外のシェルの場合は適宜読み替えるように。

ネタバレ

--log-fdオプションとリダイレクトを組み合わせればいい。

Valgrindの使い方

例えば以下のCコードsample.cを考える。

#include <stdio.h>
#include <stdlib.h>

int main(void) {
  puts("hello");
  malloc(42); // 特に意味もなく malloc して……
  fputs("goodby\n", stderr);
  return 0;   // free せずに終了
}

もちろんこのコードはコンパイルして実行することができる。

$ cc -Wall -g sample.c && ./a.out
hello  # 標準出力
goodby # 標準エラー出力

しかし、sample.cは6行目で(無意味に)mallocした領域を解放せずにプログラムを終了している。

Valgrindを介して実行すると、このようなメモリリークを検出できる。 --leak-check=fullオプションを付けると、メモリリーク箇所の詳細な情報もわかる

$ valgrind --leak-check=full ./a.out
==6865== Memcheck, a memory error detector
==6865== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==6865== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==6865== Command: ./a.out
==6865==
hello
goodby
==6865==
==6865== HEAP SUMMARY:
==6865==     in use at exit: 42 bytes in 1 blocks
==6865==   total heap usage: 1 allocs, 0 frees, 42 bytes allocated
==6865==
==6865== 42 bytes in 1 blocks are definitely lost in loss record 1 of 1
==6865==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6865==    by 0x400614: main (sample.c:6)
==6865==
==6865== LEAK SUMMARY:
==6865==    definitely lost: 42 bytes in 1 blocks
==6865==    indirectly lost: 0 bytes in 0 blocks
==6865==      possibly lost: 0 bytes in 0 blocks
==6865==    still reachable: 0 bytes in 0 blocks
==6865==         suppressed: 0 bytes in 0 blocks
==6865==
==6865== For counts of detected and suppressed errors, rerun with: -v
==6865== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

definitely lost≒メモリリークしていると思えばいい。 今回はデバッグフラグを付けてコンパイルしているので、mallocした場所(sample.c:6)まで出力されている。

-qオプションをつけるとエラーメッセージのみが出力される。

$ valgrind -q --leak-check=full ./a.out
hello
goodby
==7135== 42 bytes in 1 blocks are definitely lost in loss record 1 of 1
==7135==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7135==    by 0x400614: main (sample.c:6)
==7135==

Valgrind自体は他にも色んな用途があるようだが、ここではとりあえずメモリリーク検出ツールとして扱う。

やりたいこと

makeスクリプトでまとめてチェックするような場合、「プログラム自体の出力を全て抑制して」「Valgrindの出すエラー報告だけを表示」したくなる。 つまり以下のsimple_leak_checkコマンドが欲しい。

$ simple_leak_check ./a.out # hello も goodby も出力しない
==7135== 42 bytes in 1 blocks are definitely lost in loss record 1 of 1
==7135==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7135==    by 0x400614: main (sample.c:6)
==7135==

「Valgrindのエラー報告だけ」という部分は、先述のValgrindの-qオプションで解決済みなので、問題は前者である。

試した方法

ダメな方法: 単純なリダイレクト

Valgrindのメッセージは標準エラー出力に出力されるので、標準出力を/dev/nullにリダイレクトすればいい……とはいかない。 これだとsample.cの7行目のような、プログラム中の標準エラー出力への出力が混じってしまう。

$ valgrind -q --leak-check=full ./a.out >/dev/null
goodby   # <- ./a.out 中の stderr への出力
==7613== 42 bytes in 1 blocks are definitely lost in loss record 1 of 1
==7613==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7613==    by 0x400614: main (sample.c:6)
==7613==

「メモリチェックしたいプログラムが出力するのがおかしい」と言いたくもなるが、この時チェックしていたのは自作のテストフレームワークという、本質的に出力も込みのプログラムだったので、なんとかしたいところ。

一応大丈夫な方法: --log-fileオプションの使用

Valgrindのメッセージをファイルに出す方法がある筈と思って調べたら、--log-fileオプションがあった。 標準出力と標準エラー出力を両方共/dev/nullへリダイレクトし、Valgrindのエラーメッセージは適当なファイルへリダイレクトしてから、後で表示すればよい。

$ valgrind -q --leak-check=full ./a.out \
> --log-file=/tmp/log.txt \ # Valgrind の出力をファイルに一時保存
> >/dev/null 2>/dev/nul     # プログラム自体の出力は投げ捨てる
$ cat /tmp/log.txt          # 終了後に、保存しておいた出力を表示
==8057== 42 bytes in 1 blocks are definitely lost in loss record 1 of 1
==8057==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8057==    by 0x400614: main (sample.c:6)
==8057==

一応できた。

でもこの方法の何がイケてないって、/tmp/log.txtを作ってるのがイケてない。 別にパフォーマンス云々やディスク云々を気にするわけではないが、なんか腑に落ちない。 もうちょっとスマートにできないか。

腑に落ちた方法: --log-fdオプションの使用

ヘルプを眺めてたら、--log-file オプションのすぐ近くに --log-fd オプションがあることに気づく。 以下、抜粋。

$ valgrind --help
  (中略)
    --log-fd=<number>         log messages to file descriptor [2=stderr]

--log-file がファイル名を指定するのに対して、--log-fd はファイルディスクリプタの番号を直接指定する。 最初は「なんだそりゃ」と思ったが、これとリダイレクトを組み合わせれば、中間ファイルを使わずに目的を達成できる。

$ valgrind --log-fd=3 \  # Valgrind の出力をファイルディスクリプタ3番に
> -q --leak-check=full ./a.out 3>&2 \
> 3>&2 \                 # 3番を標準エラー出力に向ける
> >/dev/null 2>/dev/null # プログラム自体の出力は投げ捨てる
==8729== 42 bytes in 1 blocks are definitely lost in loss record 1 of 1
==8729==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8729==    by 0x400614: main (sample.c:6)
==8729==

今度こそできた!

ここではファイルディスクリプタは3を使っているが、3以上ならなんでもいい(はず)。 1つ落とし穴があり、--log-fdは実行するプログラム(ここでは./a.out)よりも前に置かないと、何故か無視される。解せぬ。

オマケ: --error-exitcodeオプション

デフォルトではValgrindの終了ステータスはエラーの有無に関係なく0となっている。 これではスクリプトで処理するときに何かと不便だが、--error-exitcodeオプションで、メモリリークを1つ以上検出した際の終了ステータスを指定できる。

というわけで、目標だったsimple_leak_checkコマンドは次のようになる。

alias simple_leak_check=
'valgrind --log-fd=3 -q --leak-check=full\
3>&2 >/dev/null 2>/dev/null'

まとめ

Valgrindのエラーメッセージのみを出力する方法を述べた。

正直、--log-fileオプションで中間ファイルを生成する方法でもいい気がするが、一生使う機会が無いと思っていた「3以上のファイルディスクリプタを使ったリダイレクト」が役に立つ形で使えたので、つい記事にまでしてしまった。

というか--log-fdオプションのこれ以外の用途が思いつかないけど、何かあるのかしら。


ちなみに上のsample.cは、コンパイル時に-O2オプションを付けるとmalloc呼出し自体が最適化によって削除される可能性があるので注意(?)*1

*1:手元のClang 3.6では、最適化後のアセンブリを覗いたら無くなってた

【ドミニオン】Adventure初体験

知人がドミニオンAdventure(英語版)を入手したので遊んでみた。

うろ覚えな対戦ログ

イベントはとりあえず3枚入れてみた(あとで調べたら2枚が推奨だったらしい)。 使ったカードやイベントはうろ覚えなので覚えている分だけ。

あと1・2戦目がタイマンで、3・4戦目は3人戦。

1戦目

  • サプライ: Raze, Ranger, Miser, Magpie, Messanger, Duplicate, Wine Merchant, Relic, Tresure Trove, Artifacer
  • イベント: Plan, Seaway, Pathfinding

Magpie楽しい。 こちらのMagpieは運良く財宝カードばかりをめくってくれた上に、Pathfindingで+1 cardトークンを乗せたら更に加速した。 途中でArtifacerを入れ、最終的にはArtifacerで8枚捨てて属州を獲得した上で、8金で属州を購入できるデッキになり勝利。 相手はMessagerに廃棄トークンを載せた上で、Messangerで呪いを獲得してばら撒く手に出るが、そこまで強くは無さそうだった(一応、あまったMessangerはRazeの餌にはなっていたが……)。

枚数が多いという理由でMagpieに+1 cardトークンを付けたが、Artifacerの方がよかったかもしれない。 Relicさえ無ければ、ArtifacerはArtifacerを簡単に増やせるし、ドローし続ければ属州が確定で獲得できるし。

あとRelicがなかなかえげつない。 アクション回数を無視して2金出しつつ、相手を足止めをするアタック……って文面に起こすとかなり強いんじゃないですか。

2戦目

ここからサプライがうろ覚え。

  • サプライ: Page, Peasant, Gear, Amulet, Port, Giant
  • イベント: Training

PageやPersantの旅人カードがどの程度強いのかは気になるが、どう見てもGearステロが強すぎる……と思ったらGiantで出てきて完全に話が変わる。 PortはChampionを撃つまでのコンボパーツにもGiantに対する壁にもなるし、Amuletで軽圧縮も可能。 結局2人ともChampionを目指しつつ、Giantをできるだけたくさん撃つコースを狙う。

結果的には2人ともChampionまで育つが、TrainingされたGiantを2回毎ターンプレイできる体制を先に整えられて負け。 Championまで育つ前にGiantで3回くらいで呪いを撒かれたのが辛かったが、そもそもデッキ構築がダメダメだった気がする。

3戦目

  • サプライ: Guide, Magpie, Wine Merchant, Relic, Tresure Trove
  • イベント: Borrow, Inheritance

Magpie、再び。 相変わらず相性が良いRelicに加え、今回はInheritanceが強力なサポートになりそう。 1戦目に試せなかったTresure Troveとの相性も気になるところ。

初手は5金スタートだったのでWine Merchantを入れる。 Relicと悩んだが、銅貨2枚とWine Merchantが揃えば、Borrowを使ってInheritanceを発動できるため。 さっそく3Tに6金 + BorrowでMagpieに屋敷トークンを置くことに成功。 これで事実上、4T目から屋敷3枚を圧縮してMagpieに入れ替わる。

その後は、RelicとTresure Troveを追加し、Magpieを増殖させながら屋敷を購入していく。 特にWine Merchantは+1 buyが屋敷増量に役立った(屋敷追加くらいなら大体2コインは余るので、酒場マットに送らずにすむ)。

そのまま順調に属州と屋敷を買うプレイで圧勝。 効果が公開された時からやばいやばいと思っていたInheritanceだったが、今回のような環境では案の定のぶっ壊れだった。

あとこのゲームは3人中Relicに行かなかった1人が完全に死んでいたのが印象深かった。 4枚にされた手札をGuideで復帰させようとしていたが、Guideを使うタイミングでは大抵-1 cardトークンが乗っているという。

4戦目

  • サプライ: Coin of the Realm, Gear, Lost City, Swamp Hag
  • イベント: Trade, Pathfinding

1番手3-4なので、今度こそGear-Gearスタートでステロへ。 ただでさえ早いGearステロがTradeによってさらに強化され、Gearに行かなかった2人とは頭2つくらい抜けてリード。 早々に属州を買い始め、そのまま圧勝……かと思ったら甘かった。

2番手がCoin of the RealmとLost CityでSwamp Hagを並べるコンボを着々と組み立て、呪いを受け取らざるを得なくなる。 Swamp Hagを2枚並べられたターンにTradeで呪いを銀に換えたり、PathfindingでGearを強化したりでお茶を濁してみたが、最終的には毎ターンSwamp Hagが3枚持続する体制を整えられ、1点差で捲くられる。

Gearをもう1枚入れてもよかったのかもしれないが、そもそもSwamp Hagコンボを舐めすぎていた。 これがAdventureの世界か。

感想

プレイ中は終始こんな感じだった。

TLでよく見かける「Adventureはパーティゲーだ」というは、なんとなく理解できた。 でも個人的には面白かったのでこれはこれでいいかな、と。

ただ「ルールを順守したプレイ」はこれまでよりも明らかに難しい。 もし来年日本選手権があってレギュレーションに冒険があったら、イベントとトークンの誤処理が大量発生してジャッジが過労死するんじゃないかなって。

【Ruby】OS XでDigest::MD5を使おうとすると「Symbol not found: _rb_Digest_MD5_Finish (LoadError)」なるエラーが出る問題

週末に久々に会った友人から「お前アナログゲーム以外のこともブログに書けよ」って言われたので、メモ代わりに最近が自分が嵌った落とし穴について。 YosemiteRuby 2.2を入れたところ、MD5を扱う標準ライブラリのDigest::MD5が使えなくて困った。

発生した問題

例えばこんな感じでRubyをインストールする。

$ rbenv install 2.2.1 # rbenvでCRuby 2.2.1をインストール
$ rbenv local 2.2.1   # 現在のディレクトリで2.2.1を使用

で、digest/md5requireすると……

$ ruby -e 'require "digest/md5"'
/Users/autopp/.rbenv/versions/2.2.1/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in
`require': dlopen(/Users/autopp/.rbenv/versions/2.2.1/lib/ruby/2.2.0/x86_64-darwin14/digest/md5.bundle,
9): Symbol not found: _rb_Digest_MD5_Finish (LoadError)
  Referenced from:
/Users/autopp/.rbenv/versions/2.2.1/lib/ruby/2.2.0/x86_64-darwin14/digest/md5.bundle
  Expected in: flat namespace
 in /Users/autopp/.rbenv/versions/2.2.1/lib/ruby/2.2.0/x86_64-darwin14/digest/md5.bundle
- /Users/autopp/.rbenv/versions/2.2.1/lib/ruby/2.2.0/x86_64-darwin14/digest/md5.bundle
from /Users/autopp/.rbenv/versions/2.2.1/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in
`require'
from -e:1:in `<main>'

あまり目にしない例外を吐いて死ぬ。 ここではrbenvを使っているが、恐らく他のツール野良ビルドでも発生する。 またRubyのバージョンは2.1でも発生することを確認している。

Digest::MD5はまあ色んな所で使われていて、例えばbundler/setupなんかも使えなくなってしまうため、これは無視できない問題である。

解決策

先ほどのエラーログではCのdlopenのエラー出力らしきものが含まれていることから「たぶんRuby自体のインストールに問題があったんだろうな」というところまでは検討が付くが、思い当たる節は特に無い。

ひたすらクエスチョンマークを頭から垂れ流しながらググっていてたら、次のstackoverflowの質問に行き着いた。

Mountain Lion - Rails - Symbol not found: _rb_Digest_MD5_Finish (LoadError)

これのアンサーによると、Mac OSRubyをインストールする時に環境変数C_INCLUDE_PATHが設定されているとマズイらしい。 なんじゃそりゃと思うような、まあそんなこともあるかと思うような……

手元の環境で確認してみると確かに定義されている。

$ if [[ $C_INCLUDE_PATH ]]; then echo yes; fi
yes

Rubyのインストール時にこの環境変数がセットされてさえいなければいいらしいので、以下の手順で再インストールすればよい。

$ rbenv uninstall 2.2.1 # 一度アンインストールして
$ unset C_INCLUDE_PATH  # 環境変数を一時的に削除して
$ rbenv install 2.2.1   # 再インストール

改めてdigest/md5requireしてみる。

$ rbenv local 2.2.1
$ ruby -e 'require "digest/md5"; puts "OK"'
OK

OK。

この問題、踏むと致命的なわりにはあまり情報が出てこなかった。 そもそもC_INCLUDE_PATHは普通はセットしないので、踏んだ人も少ないのだろうと推測(gccclangなら-Iオプションで十分なはず)。 正直なところ自分もいつC_INCLUDE_PATHなんかを設定したのか覚えが無いが、たぶん昔何かの都合で.bashrcに書いたのがずっと残っていたのだろう。


なんにせよアナログゲーム以外の記事も書いたので、友人(非エンジニア)の不満も解消できただろう。 これで次はアナログゲームの記事が書ける。

第5回ドミニオン日本選手権に参加しました(後編)

前回のあらすじ:ドミニオンのプレイ回数が4回ふえるよ! やったねたえちゃん!

ということで前編の続き。

決勝が始まるまで考えてた/やっていたこと

正直、前日の予選を突破できる思っていなかったので、2日目は強い人と戦って勉強するくらいのつもりだった。 ただ、それだけだと流石に張り合いが無いので、4戦中1勝することを目標にした。

ちなみに「試験の日の朝に教科書を読んでる学生」の如く、試合直前までドミニオンラーニングを読んでいたが、大沖イラストのパン屋や行商人ちゃんがかわいいせいであまり頭に入らなかった。 きっとこうなることを考えて大沖イラストを採用している木ドミこわい。

試合備忘録

サプライはそれぞれの対戦毎にエクスパンションを固定した上で、スタッフが(たぶんその場で適当に)考えた組み合わせを発表するという形式だった。

スタッフ「サプライは事前に決めてると言いましたが、あれは嘘です
参加者「えー(爆笑)

1回戦

  • サプライ(基本・海辺): 玉座の間 魔女 木こり 工房 冒険者 巾着切り 真珠採り 宝物庫 灯台 引揚水夫
  • 2番手
  • 初手: 灯台-巾着切り

サプライがホワイトボードに書かれていく時の様子。

スタッフ「魔女」
参加者「ああああぁ……」
スタッフ「巾着切り」
参加者「うわああああぁ……」
スタッフ「灯台」
参加者「うおおおおおおお!!!!!!

いきなり荒れ場。 灯台が出てきた時の会場の盛り上がりがすごかった。

幸い初手は全員3-4だったので、みんななかよく灯台-巾着切りスタート。 巾着切りが横行し、全員なかなか5金が出ず、3・4Tは引揚水夫と灯台を補充。 (たしか)デッキ3巡目で出た5金は魔女にするか少し迷ったが、既にみんな灯台を構えている状態なのと、巾着切りのガードになるのを期待して宝物庫を購入。 その後も玉座や引揚水夫がいるので、アクション過剰でもなんとなると信じ、その後も巾着切り・宝物庫・引揚水夫・玉座の間を積んでいった。

転機が訪れたのは自分と似たようなデッキにしていた4番手が途中で魔女を挿してきた場面。 1枚ならと思い無視していたが、玉座魔女を撃ち始め、更に魔女をもう1枚入れてきた時点で「もう無視できない」とこちらも魔女を1枚購入。 今思うと「後追いは正しいのか?」と思わないでもないが、幸いこちらは玉座を多めに入れていたので、玉座魔女や玉座宝物庫からの魔女でなんとか4番手の呪い撒きに追いつく。

その後は巾着焼いて4金出したり、玉座引揚で呪い2枚を焼いたりしながら属州や公領を買い、(たしか)属州切れでゲームエンド。 結果は1点差でなんとか1位。 得点計算するまで誰が勝つのかわからなかった激戦だったのと、本戦1勝という目標を早くも達成できたので無駄にテンションが上ってしまった。 荒れ場で勝利点レースが始まるまでの宝物庫の強さを信じたのと「アクション被っても玉座と引揚水夫でなんとかする」という方針が上手くハマってなんとか回し切れた。

勝ったからというわけではないが、大会通して1番おもしろい試合だった。 初手以外の明確なルートが見えず*1、その場その場の判断でデッキを構築しないといけない展開が好きなのかもしれない。 そういうゲームは得てして荒れ場だけど……


最大の反省点は4人揃ってスタッフの試合開始の合図を聞き逃したところ。 4人で談笑していたらスタッフに怪訝な顔で「なにやってるんですか?」と言われて(ごめんなさい、なにもしてませんでした)、慌ててゲームを始めた始末。 人の話はちゃんと聞きましょう。

2回戦

  • サプライ(陰謀・繁栄): 中庭 執事 望楼 交易路 共謀者 改良 公爵 保管庫 鍛造 行商人ちゃん
  • 植民地・白金貨あり
  • 3番手
  • 初手: 保管庫-中庭

行商人ちゃんかわいい。

自分含めて1・2・3番手が5-2スタート。前2人は改良-中庭スタートで、恐らく行商人ちゃんを売り飛ばして白金貨にするルートを狙ってる様子。 自分も行商人ちゃんを白金貨に改良するのを見ていたが、少し捻って、保管庫で6金を出して6金で行商人を確保する方向にしてみた(まずこの選択がアレな気がする)。 中庭が3Tに来れば3・4Tに確実に行商人ちゃんが手に入るという目論見。

一応、行商人ちゃんも改良も早く用意はできたが、3人揃って行商人ちゃんと改良が一向に揃わない。 「それ(行商人ちゃん)をすてるなんてとんでもない!」と言わんばかりに揃わない。 結局、執事から入った4番手も含め、みんなで普通に9金で白金貨を買う展開に。

自分は中盤でかなり致命的なプレイミスを犯したせいで、白金貨を手に入れるのが大幅に遅れる。 このミスで完全に取り乱し、結局植民地もほとんど買えずに4位転落。 外野で見ていた知り合いにも指摘されたが、鍛造入れればもっとマシだったかもしれないのに入れてないし、属州を入れるべきところで入れてないしで、本当にダメ。


そもそも行商人ちゃんを白金貨に改良しようとしていた3人が全員間違ってるんじゃね? という*2。 これたぶん執事 or 改良で軽圧縮しつつ、中庭 or 保管庫だけで財宝を買っていく方が速いんじゃね? という。

3回戦

  • サプライ(錬金術・収穫祭・ギルド): 村落 蝋燭職人 大学 賢者の石 収税吏 伝令官 再建 豊穣の角笛 弟子 肉屋
  • 4番手
  • 初手: 銀-収税吏

錬金・収穫祭が含まれている時点で「使い魔か!? 馬上荒れ試合か!?」と神経を尖らせていたが、意外と丸い。 というか肉屋が無難に強い。 そして無難に強いカードがある場で4番手という辛み。

1番手が再建-銀、2・3番手がどちらも銀-銀と来て考える。 少なくとも2・3番手は手堅い肉屋ステロにしか見えず、「もはや1位になるためには曲芸しかない」という思考で2Tに収税吏を選択。 一応考えていたのは、3Tに収税吏と銀を揃えて他人の銀を落とせば、金貨を獲得しつつ他家の4T肉屋購入を潰せるというロマン。 夢を見るのも大概だし、できたところでその先のビジョンも深く考えていなかった辺り悪手だったと思う*3

その後は肉屋の流れに乗っかるも、間に合わず3番手の方と3位タイ。 ざんねん! わたしのぼうけんはここでおわってしまった!

ちなみに1位のFerryさんは銀-銀から入って3・4Tの両方で肉屋を購入。 徳が高い。


2戦目後の取り乱しを引きずったまま収税吏スタートとかいうよくわからないことをしてしまったけど、15ptを準決勝進出ラインとみなすなら「2位以上を狙う手」でよかった気がしないでもない(1-4-2-1で15ptを狙う)*4。 そう考えると、後手番とは言えやっぱり銀-銀でよかった気がする。 それこそ3T・4T両方で肉屋を買える方が、収税吏で銀を指すよりもまだマシな気がする。

あるいは伝令官と角笛でアレな方向に行く手も考えられるが、ただでさえコンボ構築力が低い上に肉屋3人のスピードに追いつける気もしない(属州を肉屋で焼かれる未来が視える……)。 というか、伝令官と角笛で悪いことをして勝った人はどれくらい居たのかな。

4回戦

  • サプライ(異郷・暗黒時代): 救貧院 岐路 物置 城塞 ゴミあさり 武器庫 官吏 大使館 厩舎 農地
  • 避難所あり
  • 2番手
  • 初手: 武器庫-物置

全員が勝っても準決勝に進めない卓なので、開始前に「最後なのでまったりやりましょうw」と意気投合。 サプライを見る限りゴミあさり-銀からの大使館ステロが無難に強そう。 しかし、ここで疲れきった脳内に悪魔が囁く。

「デッキ引ききってから物置で捨てて、更に救貧院並べたら強いんじゃね?」

……まあ冷静に考えれば大使館相手に間に合うはずも無く、例え理論上できるとしてもコンボデッキ構築力皆無の自分には到底無理なのだが、大会の熱気にやられきっていた頭では「武器庫でワンチャン!」とか考えてた。 3金で物置を買ってるのは更に意味がわからない。 たぶん「被らなければ武器庫を使える回数増えるよ! やったねたえちゃん!」とか考えていた自分の頭をひっぱたきたい。

無難にゴミあさり-銀で入った3人が意外と遅かったため、それっぽいデッキを作るには作ったが、結局不発に終わって4位。 ところで1番手と4番手がゴミあさり-銀からの厩舎ステロに行ったけど、大使館と比べるとどうなんだろう?(というか他人の大使館で降ってくる銀貨を期待してたのに……)


更に余談。 終わったあとの r_kuzumi との会話。

AuTo「ゴミあさり-銀から大使館は、大使館2枚要るのかな? ゴミあさりで大使館を置くし……」
r_kuzumi「そもそもゴミあさりは邪魔だから農地で焼いて金貨にするもんでしょ」
AuTo「なるほど?」

完全に盲点だった。 状況に依るとは思うけど、結局このサプライの4-3スタートはどう展開するのが正しいのか?

結果

というわけで1-4-3タイ-4の大会勝利点6.5点で敗退。 こうやって見ると1回戦の勝利で燃え尽きてた感がある。 2戦目以降の結果は自分の弱さが露呈しただけなので、ある意味納得の結果?

感想

ドミニオンに限らずゲームの大会的なのに参加したのは今回が初めてだったが、ポイントが付くと張り合いがあっておもしろい。 2日目のサプライ公開時の会場の盛り上がりとかの、普段は味わえないお祭り感覚も存分に楽しめた。 あとネットやなんとかマニアックスとかいう本でしか見ることが出来ない人達と戦ったり、生で試合を見たりできたのもよかった。 特に準決勝・決勝はゲーム自体はもちろんだが、サプライ決めの苦悩や駆け引きも見てて楽しかったし、とても勉強になった。

ところで大会終わった後は「楽しかったけど、練習も含めて散々ドミニオンをやったし、しばらくはいいかな」とか考えていた。 それなのにこの1週間は今まで以上にgokoにログインしたり、大会サプライで反省会をしたりと、ますますドミニオン漬けになってるのがおもしろい。 というかもっとこの記事早く書くつもりだったのに、書いてる途中でドミニオンやりたくなってgokoに行ったりしてたせいで、こんなに遅くなった。 いい意味で刺激になってる……のかな?

なんか「楽しかった」と「おもしろかった」しか書いてなくて頭悪い感想になってるけど、本当にその二言に尽きる濃厚な2日間だった。 今回は「予選突破 + 全体で2勝」という結果だったので、もし来年もあるとしたら「予選突破 + 全体で3勝」あたりが目標にしたい。

*1:見えてた人いたら教えてほしい。

*2:これのせいで同卓だったみなせさんはこの時点ではコンボの人なのかと思ってました

*3:結局、収税吏は4Tに来たのでアウト。

*4:結果的には15pt準決勝進出は確か0人か1人だったが

第5回ドミニオン日本選手権に参加しました(前編)

改めましてホビージャパン・ゲームフェスティバル2015にて開催された第5回ドミニオン日本選手権に参加してきた。 長いので一言でまとめるドミニオン楽しかったです。

前日まで考えていたこと

ドミニオン歴は先輩に嵌められて教えてもらってから始めて3年間くらい。 基本、身内同士かオンライン(iso, goko)でまったりプレイしていただけなので、経験も知識も理論も穴だらけなのは自覚済み。 大会経験などもこれといって特になし。 そんなのがガチ勢が集う大会に行ってもいいのかとも思ったが、自分の中では以下の目標と方針を立てて挑んだ。

  • 1回くらいは1位を取りたい
  • 予選突破できれば御の字
  • コンボ構築では熟練者に勝てないので強い自制心を持つ

まあ「決勝に進めたら遊べる回数が増えるよ! やったねたえちゃん!」くらいのつもりで、普段は会えない色んな方と楽しもうと思っていました。

試合備忘録

自分の初手や方針、試合中に悩んだところとかについて。 初手の順番はもしかしたら間違えているかも。

1回戦

  • サプライ: 工房 鍛冶屋 玉座の間 祝祭 書庫 愚者の黄金 画策 香辛料商人 街道 農地
  • 4番手
  • 初手: 銀-鍛冶屋

見渡すと色々なルートがありそうだが4番手。 そして2番手が書庫-愚者、3番手が香辛料商人-愚者と来たので、愚者おっかけは厳しい。 なので、ここは4位を避ける手として鍛冶屋ステロを選択。

結果としては、銅貨を焼きつつ愚者の黄金を集めた3番手が属州をしっかり集めて終了。 自分は3位。 4位は避けたけど、幸先は悪い。


悩んだのは鍛冶屋を撃って手札が6金 + 屋敷になった時。 まだ中盤に入りかけくらいなので何も考えなければ金貨だが、農地を入れて屋敷を鍛冶屋の2枚目にすれば、実質1ターンで鍛冶屋と銀貨を購入したとも言える。 ここでは後者を選択したが、どっちがよかったのかまだわからない。 なお2枚の鍛冶屋はいつも手札5枚の中でイチャついてました。 爆発しろ。

そしてミスだったのは属州を買い始めた局面で、リシャッフル前に3金で屋敷を購入したところ。 その次のリシャッフルが入るまで、手札が4金-4金-1金となってしまい、恐らく3点以上は失った。 ゲームの進行具合の把握やステロの刻み感覚がまだまだ未熟なのが露呈してしまった。

ところでこのサプライ、いくつかの卓では街道・市場による瞬獄殺が決まったらしい。 まあできる人はできるよね……

2回戦

  • サプライ: 礼拝堂 村 木こり 密偵 金貸し 研究所 義賊 シルクロード 辺境伯 大使館
  • 1番手
  • 初手: 銀-銀

これまた色々なルートがあるサプライだが、まだ自制心が働く。 辺境伯ステロか大使館ステロか、いずれにしても初手は銀-銀。 義賊がチラッと見えたが「まあ大丈夫やろw」くらいの気持ちでいたら、3番手が2ターン目4金で義賊購入。 そしてめくられる銀貨と銅貨。*1

3・4Tはどちらも銀貨購入、なんとかデッキ3巡目で5金に届く。 正直かなり遅れているが、直前の一人回し練習を信じて大使館ステロをすることに。

辺境伯を撃たれながらも何とか8金を届かせていくが、最後は村・辺境伯をしていた4番手がシルクロードで稼いで追いつかれる。 最終的には同点手番差で2位に。 シルクロードを舐めてはいけないのは大会直前ミニトーナメントでも学んだはずなのに、カットしきれず無念。

3回戦

  • サプライ: 泥棒 庭園 議事堂 岐路 坑道 開発 遊牧民の野営地 地図職人 国境の村
  • 2番手
  • 初手: 議事堂-岐路

自制心終了のお知らせ。

方針としては地図職人で坑道を落としつつ、掘り当てた金貨を改築で属州にするプラン。 (1番手も似たような感じ) 改築と国境の村があるので、点数が上回るいい感じなタイミングで強引に3山切れで終わらせるのをゴールに見据える。 自制心とはなんだったのか。

そして4番手が属州1枚、1番手が属州3枚、自分が属州2枚の状態で迎えた運命のターン。 4番手と1番手の議事堂サポートで増えた手札を、地図職人でデッキを操作しながら国境の村と議事堂で更に増やして引き切り。 ここで改築を使えば、金貨を焼いて属州2枚 + αの点数を獲得できるが、ふと疑問に思う。 「本当に次のターンを回していいのか?」と。

1番手と自分が議事堂乱舞しているせいで、3番手と4番手は手札10枚、リードしている1番手も8枚という状況。 そしてサプライは国境の村が1枚、議事堂が2枚、坑道が2枚という、いつ終わってもおかしくない状態。

ここで獲得する属州を1枚に留めて自分が無理やり終わらせると、1番手と主に坑道の刻みで1位を競うことになる。 一方、属州2枚 + αを獲得してゲームを続行させると次のような状態になると考えられる。

  • 3番手はかき集めた坑道で上手く金貨を掘り当てているので、次ターンは大きく点数を伸ばしてくる。 ただしまだ属州0なので終わらせてくるかは怪しい。
  • 4番手は既に属州を1枚持っている + 手札10枚なので、捲ってきた上で終わらせる可能性がある。
  • それでも終わらず1番手にまで回ってくると、間違いなく捲くられた上で、ゲームが終わる。

ということで続行した場合、自分が1位になる可能性は極めて低いと判断し、確実に2位以上が取れるこのタイミングで強引にゲームを終了させる。 結果はやっぱり刻みで1番手に負けて2位。


ここまでで3-2-2位で7pt。 最後に1位を取ればギリギリ予選通過ラインなので、首の皮一枚繋がる。 さらに自分が終わらせたために4位になった3番手の方がドロップ欄に丸を付けながら「これで1位取らなきゃわかってるよね?」と言って会場を去ったので、色んな意味で負けられない状態に……

4回戦

  • サプライ: 地下貯蔵庫 祝宴 役人 魔女 市場 神託 交易人 厩舎 値切り屋 不正利得
  • 2番手
  • 初手: 銀-交易人

とうとうやってきた荒れ場サプライ。 更に1番手と3番手がどちらも魔女-地下貯蔵庫でスタートして辛い気持ちになる。 交易人は大会前の練習ではリアクション全く活かせなかったので信用していなかったが、だからと言って入れないわけにもいかず銀-交易人でスタート。 この時点では「公領・屋敷・呪いの3山エンドかなぁ」とか考えていた。 しかしここから奇跡的なデッキ回転が始まる。

まず3T目の手札に「銅 銅 銀 屋敷 交易人」が来て、更に1番手の魔女をリアクション。 自分のターンでは屋敷を銀2枚に換えつつ、2枚目の交易人を購入。 4T目に神託を購入後、リシャッフルした手札で3番手の魔女も交易人でリアクション。 この辺りで場が「え、なにこれ、交易人ってこんな使える子だったの?」みたいな空気になる。 (そして他の人も目を丸くしながら交易人を積み始める)

その後、神託をもう1枚入れたあとは、ひたすらリアクションしながら財宝を買い続け、なぜか荒れ場なのに8金が安定して出るデッキになる。 神託はデッキに下の方に沈みがちで中々撃てなかったが、魔女をめくって落とすというファインプレイを見せる。 結局、他の人が公領を買い始める中、自分はそのまま属州を買い続ける。

最終的に公領と銀貨が切れ、なぜか残り1枚になっていた交易人を自分で切らして終了。 属州7・公領2・屋敷1・呪い1の48点(!)で圧勝。 3回戦3番手の方にもなんとか顔向けできる結果。 魔女はかれこれ10回以上撃たれていたが、獲得した呪いはわずか3枚(内2枚は交易人で廃棄)。 ちなみに銀貨は確か16枚。

結論: 交易人は偉大、交易人は神。


悩んだのは中盤で手札が「銅 銅 銀 銀 交易人」と来た時。 大人しく金貨を購入するか、銀を焼きつつ銀を購入して、デッキを中和するか。 ここでは中和するほど呪いを受けていなかったし、「デッキ厚くなったら魔女リアクションしにくくなるだろ」という思考で金貨を購入。

そして何よりも疑問なのは、初手で1・3番手の方が不正利得を入れなかったところ。 地下所蔵庫で回してたくさん撃つ方針だったみたいだけど、たぶん不正利得で2巡目のデッキを汚されたら、こうはならなかったんじゃないかな……

予選結果

最終的な大会勝利点は13pt。 順位表に予選通過ラインを跨いで13ptのプレイヤーが並ぶ中、総獲得勝利点数で予選通過。 どう考えても4戦目の48点のお陰です。

ドミニオンできる回数が4回増えるよ! やったねたえちゃん!」

予選が終わって考えていたこと

ドミニオン楽しい。

という当たり前なことは置いておいて、正直自分の実力で予選通過できるとは思っていなかった。 そして通過したのは明らかに4回戦の交易神のお陰なので、こんな実力で2日目に行っていいのかとも少し思った。 しかし直前の練習ではひたすらに不運(例: 初手の大使館がボトムに沈む, オアシス-オアシスで入って5金が出ない)に頭を抱えたことを思い返し、 「あそこで不運を削ぎ落したご褒美で今日勝ち上がれた」と考え、前向きに2日目に臨むことにした。

サプライに関してだと、基本・異郷というレギュレーションの中で予想以上にコンボできるサプライが来たのビックリだった。 あと大正義よろずやが午前・午後通して出なかったのは、対抗できるルートのあるサプライが作れなかったからかな?


というわけで後編へ続く。 autopp.hatenablog.com

*1:せめて銀貨屋敷なら……

第5回ドミニオン日本選手権 予選

おかげさまで13点で予選突破しました。 後日、各試合についてコメント書くはず。

→書きました autopp.hatenablog.com autopp.hatenablog.com

ドミニオン日本選手権直前ミニトーナメントに参加しました

何かと噂に聞くゲームスペース柏木で執り行われたドミニオン日本選手権直前ミニトーナメントなるものにノリと勢いで参加してみました。

選手権の練習らしく、基本的には来週の大会ルールを踏襲。 サプライはトーナメント企画者と入穂さんとれとれとさんによるもの。

各対戦について

ゲーム全体の動きというよりは、自分のプレイの雑な備忘録。 結果だけ言うと残念でした。 初手の順序はうろ覚えです。

1戦目

交易人-オアシスが有効そうに見えたが、5金はかなり遠くなりそう。 絶対にデッキ2順目に5金を出すという固い決意と、不正利得でデッキが腐っても掘り進められるのを理由に、オアシス-オアシスでスタート。 が、開幕不正利得が居なかったにも関わらずデッキ2順目はどちらも4金……

結局半分やけくそ気味でオアシスを補充したり書庫を入れたりした結果、3位で終了。

あまりにも辛かったので、さっきオアシス-オアシスでデッキ2順目に5金が出ない確率を計算したら、約7.6%という低確率だったので、もうこれは運のせいにしたい*1。 まあ大人しく交易人-オアシスで良かったんだろうけどね……

2戦目

  • 礼拝堂 宰相 オアシス よろずや 交易人 市場 議事堂 街道 厩舎 国境の村
  • 1番手 よろずや-オアシス (4-3)

goko2人戦なら間違いなくコンボに走りたくなるが、ここは歴戦の猛者が集う4人場なので大人しく馬鹿でも使えるよろずやでスタート。 議事堂撃たれた時にもよろずやに仕事させることを期待 + デッキ2順目でのよろずや沈みを回避するためにオアシスを選択。 そしてデッキ2順目でボトムに沈むよろず屋(確率1/12 = 約8.3%)。

それでもめげずに3-4ターン目に1枚ずつ補充したよろず屋とオアシスで頑張って2位(1位とは同点手番差)。 特に、議事堂撃たれたターンにオアシスとよろずやがセットで来てくれたので、2枚刺したオアシスは十分仕事したようと思う。

3戦目

  • サプライ: 公爵夫人 開発 神託 役人 泥棒 庭園 香辛料商人 埋蔵金 不正利得 官吏
  • 3番手 銀-泥棒 (3-4)

THE クソゲー。でも一番楽しかった。 1番手と2番手が不正利得スタートとかいう暴力を振るってきたので、3-4ターン目で泥棒2枚目を購入。

泥棒はほぼ被らずに銀貨を盗んだり、不正利得*2を盗んだりと大活躍。 最終的にはデッキ38枚まで来て「次のターンが回ってきたら公領 + 公爵夫人で40枚になるし勝てるかも!?」と思ったが、回ってこないで3位。

この試合のデッキの回りは全体的に良かったが、一応何箇所か不運な場所があったので、それさえなければ多分1位だったかな。 まあ運の話をしてもしょうがないけど……

個人的には1番手の方が5-2スタートで素直に不正利得-公爵夫人に行ったのが意外だった。 たぶん官吏(銅貨5枚戻し)-不正利得-公爵夫人の方がよかったのでは?

4戦目

  • サプライ: 岐路 木こり 密偵 よろずや 義賊 シルクロード 市場 大使館 値切り屋 農地
  • 1番手 大使館-なし (5-2)

初手番 + 3順目に大使館で金貨購入するというラッキーに恵まれる。 これは勝たないとマズいんじゃないかなぁと思ったけど2位。とてもマズい。

大使館2枚目を入れるタイミングがわからかったのがたぶん敗因。 一度中盤で5金が出たが、周りも自分も属州を買い始めていたので、焦って公領を入れてしまった。 あそこで大使館を入れていたら、また違った展開になっていたはず?

大使館ステロは個人的に経験不足なので、大会までに少し1人回しした方がいいかも。

感想

読み返したら、なんかデッキの回りを嘆いているように見えなくもないが、それ以前にプレイミスが敗因だとは思う。 4戦中3戦が1番手にも関わらず1回も1位が取れてないあたり、やっぱり自分はドミニオンが弱い。 こんなレベルの奴が日本選手権に申し込んでよかったのかな、と思わなくもない。 まあでも久々にしっかりドミニオンが出来たし、色々と勉強になったのでとても楽しかった。

ミニトーナメントを企画・運営してくれた入穂さんとれとれとさん、ありがとうございました。 入穂さんが各対戦後に入れてくれたサプライの解説は勉強になったし、サプライだけツイートして黙々と別卓でポーカーしていたれとれとさんの背中もなんかカッコ良かったです。 終了後にれとれとさんが言い放った「3戦目で初手5金出せないようじゃダメ」というセリフは忘れずに日本選手権に臨みます。

*1:銀-銀は約8.8%、銀-オアシスが約8.2%

*2:盗んだ瞬間に呪いがばら撒かれる。楽しい。