yu-neのドミニオン検証ブログ

ドミニオン(ボードゲーム)に関することを書きます。主に自作シミュレータでの検証結果の記事が多めです。

宴会-Buried Treasure(埋められた財宝)

本記事はうりはりさん主催の『ドミニオンアドベントカレンダー2022』の20日目の記事となります。

adventar.org

※本戦術はPlunder(劫掠)のプレビュー2日目にBuried Treasure(埋められた財宝)が出た直後、Discordで海外プレイヤーのnasmith99さんがコメントしていた戦術です。

初手から宴会でBuried Treasureを獲得していくと、獲得時効果により4ターンでBuried Treasureを10枚すべて獲得することができます。その後5ターン目はおおよそ15金4購入ほどの出力となるため、ここから公領と屋敷を枯らすことでゲームを終わらせるというものです。 今回はこの戦術の速度を自作シミュレータで検証をしていきます。
※Buried Treasureのカード名、翻訳の内容は2022年12月時点の訳のものです。

検証概要

  • 「公領8枚、屋敷8枚購入(合計35点)の平均ターン数」をシミュレーションする
  • 初手は3-4固定
  • それぞれ5000回試行する
  • ついでに「属州4枚購入の平均ターン数」シミュレーションしてみる

購入条件(公領8枚、屋敷8枚)

1. (Buried Treasureが枯れるまで)3金以上の場合、宴会(Buried Treasure)を購入
2. 5金以上の場合、公領を購入
3. 2金以上の場合、屋敷を購入

購入条件(属州4枚)

1. (Buried Treasureが枯れるまで)3金以上の場合、宴会(Buried Treasure)を購入
2. 8金以上の場合、属州を購入
3. 5金以上の場合、公領を購入
4. 3金以上の場合、銀貨を購入

検証結果

公領8屋敷8ターン数 属4平均ターン数
12.8052 12.1868

考察

Buried Treasureが3金で購入できるのであれば、3金+1購入という出力はそのまま次ターンBuried Treasureの獲得券となるため獲得速度は速いです。
早ければ12ターン35点終了のため、かなりバカにできない戦術だと思っています。ただこれは片方のプレイヤーがBuried Treasureを10枚とった場合の話であり、双方が同じ戦術をとった場合Buried Treasureは先手6-後手4で分けることになります。銅貨まみれの状態から勝利点レースになるとすると後手の勝率は絶望的な気がします。

Buried Treasureは初見ではあまり強いと感じなかったカードですが、実際にやってみるとそれなりのゲームで獲得している感覚ですね。やはり購入権が強い。
獲得時プレイできるカードは実力差も出やすくなかなか良いカードだと思います。

宴会スーク

初手3-4で宴会(スーク(屋敷2廃棄))、宴会(スーク(銅貨屋敷廃棄))した場合のステロの速度検証です。 手札5枚からのスークプレイは+3コインであるため、 この初手で入ることで屋敷3枚がすべて銅貨となりスークが被らなければ実質金貨2枚が入ったデッキとなり、ステロとして優秀そうです。 今回はこのステロ戦術の速度を自作シミュレータで検証をしていきます。

※カード名、翻訳の内容は2022年8月のドミニオンオンラインのものです。

検証概要

  • 属州4枚、5枚購入の平均ターン数を比較する
  • 初手は3-4で宴会(スーク)、宴会(スーク)固定
  • 5000回試行する

購入条件

1. 8金以上の場合、属州を購入
2. 6金以上の場合、金貨を購入
3. 3金以上の場合、銀貨を購入

検証結果

属4平均ターン数 属5平均ターン数
12.294 14.240

考察

やはりデッキ2週目時点で屋敷がなくなるのは大きいようで、ステロとしては充分な速度が出ました。 初手での宴会(スーク)はステロに限らず、コンボでも2巡目以降それなりの出力を期待でき非常に強力であるため、見逃さないようにしましょう。

海賊ステロ

2022年5月に海辺2版の内容が明らかになりました。
その中でも個人的にはカードパワーが弱いと感じている海賊によるステロの速度を自作シミュレータで検証してみます。
イラストは個人的にとても好みです。(なぜ海賊なのにアタックカードではないのか。)

※カード名、翻訳の内容は2022年5月のドミニオンオンラインのものです。

検証概要

  • 属州4枚購入の平均ターン数を比較する
  • 海賊は1枚と2枚のパターンで検証する
  • 初手3-4と2-5でそれぞれ検証する
  • リアクションした場合としない場合それぞれ検証する
  • 各パターンで5000回ずつ試行する

購入条件(海賊1枚パターン)

1. 8金以上、かつデッキ内の金貨が1枚以上の場合、属州を購入
2. 5金以上、かつデッキ内の海賊が0枚以下※の場合、海賊を購入
3. 6金以上の場合、金貨を購入
4. 3金以上の場合、銀貨を購入

※海賊2枚パターンはここが「1枚以下」となります。

検証結果

海賊枚数 初手 リアクション(※) 属4平均ターン数
1 3-4 15.413
1 3-4 14.5104
1 2-5 14.5116
1 2-5 13.3634
2 3-4 14.9578
2 3-4 13.7624
2 2-5 14.2706
2 2-5 12.3756

※〇の場合、手札にある海賊を相手ターンで必ずリアクションできた場合を示す。✕は必ず自分のターンに通常プレイした場合を示す。

考察

リアクションできない場合、およそ鍛冶屋ステロと同等でした。強くはないですね。
ただしリアクションできるなら平均14ターンを切るパターンもありました。2人戦だと海賊ステロが最善となるサプライは少なく、またこちらが海賊を手札に持つ可能性が高いならば相手は財宝を獲得することを避けるかもしれないため、海賊ステロで勝つゲームにはなかなか遭遇しないかもしれません。
しかし、4人戦ならばリアクションできる可能性は上がるので上記速度に近い数値が出せるかもしれません。
また、本検証は自分で財宝を獲得したときのリアクションプレイは未検証であり、当然他のカード次第で速度は変わるため、個人的には非常に使いがいのあるカードだとは思っています。
2人戦ではあまり購入機会は少ないカードかもしれませんが、繁栄2版で新規財宝カードも追加されると思うのでそのへんも期待しましょう。

タブレット端末でのDominion Online

自分は出先ではタブレットを用いてDominion Onlineをプレイすることが多いです。 ここではタブレットでのプレイの所感やTIPSを記載したいと思います。

出先でのプレイのため、通信はスマホテザリングで行っています。

試したことのあるタブレット

1. amazonのFire HD 10 タブレット(当時購入した世代の画面サイズ:10インチ)

※最近(2021/12/30)のは画面サイズが10.1インチっぽいです。

昔、安いのでドミニオン用に購入したことがあります。
ブラウザはSilk。プレイ感は基本的に問題なし。
ただし、「カードリスト」タブからのカード選択などは画面からはみ出てしまうのでその辺は難あり。
また画面によってはチャット欄が隠れてしまい、チャット入力が不可となった記憶があります。
とりあえず最低10インチあれば通常プレイで大きく困ることはないと感じました。

2. iPad Air4(画面サイズ:10.9インチ)

ブラウザはChrome。プレイ感は問題なし。
基本的にはFire HD 10と一緒。
「カードリスト」は帝国までぎり選択できます。それより下は隠れて選択できないです。
ただチャット欄が隠れて入力不可といった事象にはまだあったことがないです。

3. Surface Pro 7(画面サイズ:12.3インチ)

2021/12/30現在のメインPC。
ブラウザはChrome。プレイ感は問題なし。
このサイズになると「カードリスト」タブからのカード選択も問題なし。
ただ移動動物園(拡張)がぎりぎりなのでAlliesが出ると怪しいかもしれない。

TIPS(主にiPadの話)

〇受信箱やチャットのメッセージが文字化けするときの対処法

Chromeのメニュー(「・・・」のボタン)→「PC版サイトを見る」を押下で解決します。

〇チャットを送ったあと、フォーカスがチャット欄から外れないときの対処法

「投了ボタン」を押下→「投了しますか?」ダイアログにて「キャンセル」を押下することで、 チャット欄からフォーカスが外れて元に戻ります。
※私はこれで押し間違えて1敗しました。
端末によっては、カード長押しでのカード画像の表示でも外れるかもしれません。

何かほかにTIPSみたいの発見したら適宜追記していきます。

ドミニオンシミュレータについて

本ブログでは検証ツールとして自作のドミニオンシミュレータを使用しています。 ここではツールの簡単な説明をします。

動作環境

OS:Windows
標準でインストールされているWSHというソフトウェア上で動作します。

ソースコード

ソースコードGitHubで公開しています。
書きっぷりはイマイチな部分も多いですが、まだまだ発展途上なので、ちまちま機能を追加していくつもりです。
ファイル拡張子は.jsとなっていますが、JavaScriptではなくJScriptというスクリプト言語です。
Windows上でソースだけあれば動作可能ということでこの言語を選択しました。

github.com

ダウンロード方法

  • ブラウザで上記GitHubにアクセスする。

  • 下記画像右上の「Code」ボタン(緑のボタン)を押下し、その後「Download ZIP」をクリック。

f:id:yune_dominion:20211206123740p:plain

  • ファイルエクスプローラからダウンロードしたzipファイルを解凍し、出力されたフォルダ(DomSim-main)を任意のフォルダに配置する。
    ※解凍はzipファイルを右クリック→「すべて展開」を押下など実施してください。

実行方法

  • ファイルエクスプローラから「DomSim-main」内に移動。
  • 「domsim.bat」をダブルクリック。 (完了まではしばらく時間がかかります。)
    Windows Defenderなどにより、信頼されないアプリうんぬんのダイアログが出る可能性がありますが、その場合は、「続行」をクリックして進めてください。

実行すると、以下のようなコンソール画面が出力されます。

f:id:yune_dominion:20211206130220p:plain

ダウンロード直後の状態だと、鍛冶屋1枚ステロのシミュレート結果が表示されます。 属州4の平均ターン数として、おそらく14.8~15.0あたりの数値が出るかと思います。

  • Enterキーを押すことでコンソール画面が閉じます。

AIの設定方法

setting.jsをテキストエディタ(メモ帳など)で開いて編集します。 今回は簡単な箇所だけ説明します。 そのうちもう少し詳細な説明を書きたいところ。。

購入手順の変更方法

購入手順はprocessBuyPhaseという関数内に設定します。

  /**
   * 購入フェーズでの処理を設定する。
   *
   * 本メソッドがコールされたときの購入カードは1枚のみとすること。
   * 1ターンの間でも、購入権が存在する間、本メソッドがコールされ続けるため、
   * 1ターン内に複数枚カードを購入したい場合は、この仕組みを利用すること。
   *
   * カードを購入した場合は戻り値としてtrueを返却してください。
   * 購入しなかった場合はfalseを返却してください。
   *
   * @param {!Player} player プレイヤー
   * @returns カードを購入した場合true、そうでない場合false
   */
  this.processBuyPhase = function(player) {

    // 財宝カードをすべてプレイ
    player.playAllTreasure();

    // ① 8金以上、かつデッキ内の金貨が1枚以上の場合、属州を購入
    if(player.coinNum >= 8 && player.countByCardNameInDeck(Card.NAME.GOLD) >= 1) {
      // 属州が購入を試みる。(サプライに存在しなかったなどの理由で購入できなかった場合は、②移行のロジックに移る)
      if(player.tryBuy(Card.NAME.PROVINCE) === true) {
        return true;
      }
    }

    // ② 6金以上の場合、金貨を購入
    if(player.coinNum >= 6) {
      if(player.tryBuy(Card.NAME.GOLD) === true) {
        return true;
      }
    }

    // ③ 4金以上かつ、デッキの鍛冶屋が1枚未満の場合は鍛冶屋を購入
    if(player.coinNum >= 4 && player.countByCardNameInDeck(Card.NAME.SMITHY) < 1) {
      if(player.tryBuy(Card.NAME.SMITHY) === true) {
        return true;
      }
    }

    // ④ 3金以上の場合、銀貨を購入
    if(player.coinNum >= 3) {
      if(player.tryBuy(Card.NAME.SILVER) === true) {
        return true;
      }
    }

    // 何も購入しない
    return false;
  }

ダウンロード直後のsetting.jsは①~④で示した手順で購入対象を決定しています。
例として以下のように編集すれば購入手順を変更できます。

  • 8金出た場合、金貨がデッキになくても属州を買いたい
    if(player.coinNum >= 8 && player.countByCardNameInDeck(Card.NAME.GOLD) >= 1) {
    を以下に修正する。
    if(player.coinNum >= 8 && player.countByCardNameInDeck(Card.NAME.GOLD) >= 0) {

  • 鍛冶屋を2枚デッキにいれたい
    if(player.coinNum >= 4 && player.countByCardNameInDeck(Card.NAME.SMITHY) < 1) {
    を以下に修正する。
    if(player.coinNum >= 4 && player.countByCardNameInDeck(Card.NAME.SMITHY) < 2) {

  • 鍛冶屋ではなく学者を買いたい(後述の学者をプレイするための設定も必要)
    if(player.coinNum >= 4 && player.countByCardNameInDeck(Card.NAME.SMITHY) < 1) {
    を以下に修正する。
    if(player.coinNum >= 5 && player.countByCardNameInDeck(Card.NAME.SCHOLAR) < 1) {

  • 公領を買いたい
    ②と③の間に以下を記載する。

    //  5金以上の場合、公領を購入
    if(player.coinNum >= 5) {
      if(player.tryBuy(Card.NAME.DUCHY) === true) {
        return true;
      }
    }    

アクションカードプレイ手順の設定方法

アクションカードプレイ手順はprocessBuyPhaseという関数内に設定します。

  /**
   * アクションフェーズでの処理を設定する。
   *
   * 本メソッドがコールされたときのアクションカードのプレイは1枚のみとすること。
   * 1ターンの間でも、手札にアクションカードがありアクション権が存在する間、本メソッドがコールされ続けるため、
   * 1ターン内に複数枚アクションカードをプレイしたい場合は、この仕組みを利用すること。
   *
   * アクションカードをプレイした場合は戻り値としてtrueを返却してください。
   * プレイしなかった場合はfalseを返却してください。
   *
   * @param {!Player} player プレイヤー
   * @returns アクションをプレイした場合true、そうでない場合false
   */
  this.processActionPhase = function(player) {

    // 鍛冶屋のプレイを試みる。(手札に鍛冶屋があればプレイされる)
    if(player.tryPlayCard(Card.NAME.SMITHY) === true) {
      return true;
    }

    return false;
  }

ダウンロード直後のsetting.jsはアクションカードは鍛冶屋のみプレイします。 例として以下のように編集すればアクションカードのプレイ手順を変更できます。

  • 学者をプレイしたい(上述の学者を購入する手順を記載も必要) if(player.tryPlayCard(Card.NAME.SMITHY) === true) {
    を以下に修正する。
    if(player.tryPlayCard(Card.NAME.SCHOLAR) === true) {

ゲーム終了条件の設定方法

ゲーム終了条件はisGameEndという関数内に設定します。

/**
 * ゲーム終了条件を設定する。
 * 各プレイヤーのターン終了時にコールされる。
 * ゲーム終了条件を満たしている場合はtrueを返却すること。
 * @returns {boolean} ゲーム終了条件を満たしている場合true、そうでない場合false
 */
Setting.isGameEnd = function() {

  // プレイヤー1のデッキ内の属州枚数が4枚になったらゲーム終了
  if(board.players[0].countByCardNameInDeck(Card.NAME.PROVINCE) >= 4) {
    return true;
  }

  return false;
}

ダウンロード直後のsetting.jsは属州4枚購入したタイミングでゲームが終了します。 例として以下のように編集すればゲーム終了手順を変更できます。

  • 属州5枚購入したらゲーム終了としたい
    if(board.players[0].countByCardNameInDeck(Card.NAME.PROVINCE) >= 4) {
    を以下に修正する。
    if(board.players[0].countByCardNameInDeck(Card.NAME.PROVINCE) >= 5) {

  • 属州4、または属州3公領2でゲーム終了としたい if(board.players[0].countByCardNameInDeck(Card.NAME.PROVINCE) >= 4) {
    を以下に修正する。

  if((board.players[0].countByCardNameInDeck(Card.NAME.PROVINCE) >= 4)
    || 
    (board.players[0].countByCardNameInDeck(Card.NAME.PROVINCE) >= 3
      && board.players[0].countByCardNameInDeck(Card.NAME.DUCHY) >= 2)) {

最後に

(いるとは思えませんが)もし本シミュレータについて質問などがある場合、TwitterやDiscordでDMいただければと思います。 ソースに対するツッコミなども歓迎です。

他にもドミニオンオンラインのゲームログと観戦チャットを時系列で横に並べて取得するGoogle Chrome拡張機能なんかも作ったりしてます。以下みたいなイメージです。

f:id:yune_dominion:20211206222655p:plain

有名人同士の試合だと観戦者も多くチャット欄が盛り上がるので記録のために使っています。 こちらについてもそのうちGitHubで公開できたらいいなと思っています。

サウナ・アヴァントデッキはどこまでキャントリップを許容できるか

皆大好きサウナ・アヴァントについてシミュレータで検証してみます。
キャントリップ(+1アクション、+1カードを引く、の効果を持つカード)はデッキにとって基本邪魔にはならないカードですが、
サウナ・アヴァントデッキにキャントリップを入れると、 サウナ・アヴァントがチェーンしなくなる確率が高くなります。
そこで今回は、キャントリップがどれくらいサウナ・アヴァントのチェーンに影響あるのかを検証してみます。
※以降、サウナをS、アヴァントをA、キャントリップをCと表記します。

検証概要

  • (S, A) の枚数は(2, 2) (2, 3) (3, 2) (3, 3) でそれぞれ検証する
  • Cは0、3、6、9枚のパターンを検証する
  • ドローソースはS、A、Cのみ
  • デッキ枚数は3枚の過剰引き切り枚数とする※(Sが2、Aが2、Cが0の場合、デッキ枚数は10枚で検証)
  • S、A、C以外のカードはすべて銅貨で固定
  • 各パターン5000回ずつ試行する

※デッキ枚数は適当に決めています。この辺はもっと良い条件があるかもしれません。 読者の方の中で良案があれば教えていただけると幸いです。

プレイの優先順位

手札にアクションカードが存在する場合のプレイ優先順は以下とする。

1. キャントリップをプレイ
2. デッキの(S, A)の枚数が(2, 3)の場合は先にAをプレイ
    デッキの(S, A)の枚数が(3, 2)の場合は先にSをプレイ
    デッキの(S, A)の枚数が同一の場合は手札に多い方からプレイ

上記条件にて、引き切れたときについて残アクション数の分布をまとめる

検証結果

引き切り率と引き切った場合の残アクション数の分布は以下の通りです。
※例として、S2、A2、C0のデッキ構成の場合、引き切ってかつアクションが2残る確率が73.26%ということになります。

S, A, C枚数 引き切った回数(引き切り率) 引き切ったときの残アクション数の分布
残アクション数-回数(割合)
2, 2, 0 4373(87.46%) 0-172(3.44%)
1-538(10.76%)
2-3663(73.26%)
2, 2, 3 4184(83.68%) 0-246(4.92%)
1-1337(26.74%)
2-2601(52.02%)
2, 2, 6 3956(79.12%) 0-275(5.5%)
1-1771(35.42%)
2-1910(38.2%)
2, 2, 9 3836(76.72%) 0-284(5.68%)
1-2033(40.66%)
2-1519(30.38%)
2, 3, 0 3388(67.76%) 0--221(4.42%)
1-551(11.02%)
2-2616(52.32%)
2, 3, 3 3068(61.36%) 0-278(5.56%)
1-1345(26.90%)
2-1445(28.9%)
2, 3, 6 2905(58.10%) 0-302(6.04%)
1-1700(34%)
2-903(18.06%)
2, 3, 9 2734(54.68%) 0-319(6.38%)
1-1741(34.82%)
2-674(13.48%)
3, 2, 0 4445(88.9%) 0-113(2.26%)
1-249(4.98%)
2-1192(23.84%)
3-2891(57.82%)
3, 2, 3 4364(87.28%) 0-155(3.1%)
1-510(10.2%)
2-1552(31.04%)
3-2147(42.94%)
3, 2, 6 4297(85.94%) 0-185(3.70%)
1-611(12.22%)
2-2027(40.54%)
3-1474(29.48%)
3, 2, 9 4159(83.18%) 0-189(3.78%)
1-753(15.06%)
2-2223(44.46%)
3-994(19.88%)
3, 3, 0 3691(73.82%) 0-61(1.22%)
1-350(7.00%)
2-646(12.92%)
3-2634(52.68%)
3, 3, 3 3497(69.94%) 0-88(1.76%)
1-568(11.36%)
2-1389(27.78%)
3-1452(29.04%)
3, 3, 6 3347(66.94%) 0-137(2.74%)
1-712(14.24%)
2-1652(33.04%)
3-846(16.92%)
3, 3, 9 3127(62.54%) 0-161(3.22%)
1-813(16.26%)
2-1636(32.72%)
3-517(10.34%)

考察

3枚の過剰ドロー状態ですが、S・A・Cのみだとそもそもの引き切り率が思ったより低いですね。
Cを1枚入れると約1%ほど引き切り率が減っています。(手札がAのみで、Aプレイ時にサウナを引けない確率が上がる)
引き切りたいだけならばそれほど気にせずCは入れてもいいかもしれません。

ただサウナで出るアクションを大事にしたいならば、Cは入れても2~3枚に抑えたほうがよさそうです。 3枚入れるだけでもすべてのSでアクション出る確率ががくっと落ちます。 デッキに入れるかの判断はもちろんCの性能次第ですが、真珠採りといった弱いCカードは金量余っていたとしても入れるべきではないでしょう。

また、あくまでS・A・Cのみがドローソースの場合の検証結果です。
他に村があるだけで結果は変わるので、参考程度にとどめてもらえればと思います。

鍛冶屋ステロで5金出た場合、ほんとに銀貨を購入するのが良いのか

鍛冶屋ステロする場合、5金出たときは銀貨を買うのがベターという情報をよく見かける気がするので、
実際のところどうなのか自作ドミニオンシミュレータで検証してみました。

検証概要

  • 属州4枚購入の平均ターン数を比較する
  • 5コスカードは実装が簡単な市場、祝祭、研究所で検証する
  • 鍛冶屋は1枚と2枚のパターンで検証する
  • 初手3-4か2-5かはランダム
  • 各パターンで5000回ずつ試行する

購入条件(鍛冶屋1枚パターン)

鍛冶屋ステロ
1. 8金以上、かつデッキ内の金貨が1枚以上の場合、属州を購入
2. 6金以上の場合、金貨を購入
3. 4金以上、かつデッキ内の鍛冶屋が0枚の場合、鍛冶屋を購入
4. 3金以上の場合、銀貨を購入
鍛冶屋ステロ + 5コスカード
1. 8金以上、かつデッキ内の金貨が1枚以上の場合、属州を購入
2. 6金以上の場合、金貨を購入
3. 5金以上の場合、5コスカードを購入
4. 4金以上、かつデッキ内の鍛冶屋が0枚の場合、鍛冶屋を購入
5. 3金以上の場合、銀貨を購入

検証結果

鍛冶屋枚数 5金カード 属4平均ターン数
1 なし 14.915
2 なし 14.897
1 市場 15.0166
2 市場 15.123
1 祝祭 15.3692
2 祝祭 15.1598
1 研究所 14.5396
2 研究所 14.7734

考察

シミュレータがまだ最低限の実装なので平均ターン数のみの比較ですが、 鍛冶屋1枚 + 研究所ステロが早いみたいです。 鍛冶屋で研究所引く事故よりも、研究所プレイによる2ドローが偉いということですかね。
逆に市場は事故のダメージの方が大きいと(もしくは単純に銀貨より弱い)。
わかってはいましたが、祝祭は銀貨未満ですね。