Kurter's Workshop

かーたーによるドミニオンのシミュレーション

みんなー!あつまれー!

かーたーがあつまれって叫んでも、みんな避けんでもいいじゃない…仕方ないからかーたー裂けんででもそろえますね…

 

 

…今回は、3.5人ほどに増殖したかーたーがお送りします。

とりあえず、シミュレーターで使っているパブリック変数の参照先を作っておいた方がいいと思いました。

カードリストもいちおうパブリック変数である以上入れておきますね。 → 最初はそう思ったんですが、長くなってしまったので分割したいと思います。

 

 

厳密には、詰めていくと減らすことのできるパブリック変数はあるはずですが、とりあえずということで…

 

変数の説明をする前に、総論として。

シミュレーターから変数の定義部分を持ってきているので、識別子の「Dim(Dimensionから来ているらしい)」とか「As」とかがあります。

Asの後は変数のデータ型で、「Integer」は整数型(-32768~32767)、「Boolean」はブール型(TrueまたはFalse)、「String」は文字列型です。

変数名の後にある括弧()は配列であることを表しており、定義する際に括弧内に正の整数を書いておけば、0からその数字までの要素を持つ配列となります。結果として、書いた数プラス1の要素を持つことになるので、必要な数マイナス1で定義することになります。更に、コンマで区切って併記した場合は、配列の次元を増やしていくことができます。今回使用しているのは、最大で二次元配列までです。また、括弧だけを書いて、要素数を定義しないこともできます。

コメント部分のように説明を書いていますが、読みにくいかもしれないですね…

 

尚、以下の分類ですが、初期の大雑把に括ったものに追加していっているため、分かりにくいものになっていると思います…再編する必要がありますね…

 

 

 

 

試行全体の大きな流れや操作に関わる変数

 

このセクションの変数は、基本的には試行の開始時に入力されるかリセットされ、それ以降終了までリセットされません。

 

Dim gameNumberMax As Integer
 '1試行あたり何回ゲームを繰り返すか定義した最大回数。テスト試行では10-100回の少ない回数、本試行では10000回行うように入力するための変数。

Dim gameNumber As Integer
 '1試行中で何回目のゲームを行っているかを記録しておく変数。ゲームが終了する毎に1ずつカウントアップされていく。これに基づいて出力シートの出力セルが変わっていく。

Dim gameEnd As Boolean
 'ゲーム終了条件を満たしているかどうかを示す変数。ゲーム開始時にFalseへとリセットされ、属州枚数や点数等の終了条件を満たした場合にTrueへと変更される。ゲーム終了を判断する部分が、これがTrueになっている場合にターン進行のループ処理を打ち切る。

Dim opFld As Integer
 'シート1上における、対戦相手との行座標のズレを示す値。或いは、シート1に占める、1プレイヤー分の行数とも言える。opponentFieldControlとしていたが、セルの指定の度に出現する都合上、短い表示となるようにした。書いていて思ったが、将来的に変更する可能性はあるとはいえ、試行中で変化しないのだから、Const(定数)宣言でいい気がする。

Dim oppoOpCtrl As Integer
 'シート2上における、対戦相手との列座標のズレを示す値。或いは、シート2に占める、1プレイヤー分の列数とも言える。opponentOutputControlとしていたが、長いのでoとpばかり残って面白いかんじにした。上記同様にConstでいい気がする。

Dim firstPlayerNumber As Integer
 '先手であるプレイヤーがどちら(0か1)であるかを入力するための変数。

Dim totalBugFindNumber(1) As Integer
 '各プレイヤーの、バグ出力の積算回数を記録し、出力するための変数。

Dim runNumber As Integer
 '複数試行する場合に、試行に番号を付けるための変数。購入アルゴリズム等の引数にすることで、アクションの購入数を試行毎に操作したり、そもそも使用するアルゴリズムを試行毎に別の物にしたり、といった場合に利用する。

Dim winGameNumber(1) As Integer
 '対戦形式の試行の場合に、プレイヤー毎のトータルの勝敗数を記録する変数。

Dim tieGameNumber As Integer
 '引き分けである試合数を記録する変数。

Dim tieWinGameNumber(1) As Integer
 '点数は同じであるがターン数が異なる、同点勝利による後攻の勝利を記録する変数。

Dim singlePlProvNumCtrl As Integer
 '属州の初期枚数に作用する変数。基本的には、一人回しの属州は4枚用意されて、対戦では8枚用意される。しかし、一人回しでも属州8枚獲得したい場合(4)や、疑似対戦(対戦相手は別のサプライの属州を4枚取る)で属州が4枚しかいらない場合(-4)もある。そのような場合は、括弧内の値に指定することで、適切な測定ができるようにする。

 

 

ゲームの流れや操作に関する変数

 

これらの変数は、基本的には毎ゲームの開始時にリセットされます。

 

Dim turnNumber As Integer
 '1ゲーム中で何ターン目であるか表す変数。属州がなくならなかった場合のゲーム打ち切り条件や、ターン毎の出力エリアの決定、そして各種アルゴリズムにおける意思決定の条件等に利用される。

Dim trnP As Integer
 '現在のターンプレイヤーを表す変数。基本的に、各プレイヤー分の要素数を与えられた配列変数を利用する際や、シート1に格納された情報にアクセスする際には、直接プレイヤーを指定することはせず、この変数を介して指定する。また、カードを引いたり、獲得したりという動作は、基本的にはターンプレイヤーにしか作用しないが、対戦相手へのアタックや利敵効果が発生する場合もある。その場合は、 trnP = 1 - trnP としてInverseを取り、一時的に対戦相手をターンプレイヤー扱いとすることで、操作を行っている。操作が終わったら同じようにInverseを取ってターンプレイヤーに操作を返す。3人以上に対応する構築にする場合、ここの作りを根本的に修正する必要がある。

Dim deckNumber(1) As Integer
 '各プレイヤーのデッキ枚数を表す変数。条件分岐や操作を記述する際に、デッキが0枚である場合を見落としていないか、注意する必要がある。セルを参照する操作で、その座標にデッキ枚数を引いていた場合、エラーとなる。本来なら順方向に進んでほしい操作が1→0と逆方向に進むことで、意図せずカードを消滅させてしまうこともあり得る。

Dim handNumber(1) As Integer
 '各プレイヤーの手札枚数を表す変数。

Dim playAreaNumber(1) As Integer
 '各プレイヤーのプレイエリアのカード枚数を表す変数。

Dim discardNumber(1) As Integer
 '各プレイヤーの捨て札の枚数を表す変数。

Dim durationAreaNumber(1) As Integer
 '各プレイヤーの持続エリアの枚数を表す変数。本来のドミニオンには持続エリアは存在しないが、個別のカードトークンの管理情報が存在しない以上、ある持続カードが持続するのか持続しないのかの区別は、存在するエリアで以って行うのが一番簡単であると考えたため、導入した。

Dim revealAreaNumber(1) As Integer
 '各プレイヤーの公開エリアの枚数を表す変数。現状は単に見るだけの場合も、このエリアを使用する。

Dim tavernMatNumber(1) As Integer
 '各プレイヤーの酒場マットのカード枚数を表す変数。

Dim setAsideAreaNumber(1) As Integer
 '各プレイヤーの脇に避けるエリアの枚数を表す変数。

Dim victoryPointNumber(1) As Integer
 '各プレイヤーの勝利点の値を表す変数。属州を4枚獲得することだけを目的にするならば必要ないが、屋敷廃棄系の屋敷廃棄効率を間接的に表現できる点や、公領獲得が絡む検証でのサブ的な終了条件の設定等で利用できる。また、対戦検証では対戦相手の勝利点 victoryPointNumber(1 - trnP) と自身の勝利点 victoryPointNumber(trnP) の比較が、意思決定の上で重要な要素となってくる。

Dim cofferNumber(1) As Integer
 '各プレイヤーのコイントークンの数を表す変数。終了時のコイントークン残り枚数が、デフォルトで出力される設定にしている関係上、デバッグ用に全く関係のない出力に使うこともある。

Dim bugFindNumber(1) As Integer
 '各プレイヤーの1ゲームにおけるバグ数を記録する変数。バグ出力用のセルの座標を操作するために使う。

 

 

ターンの流れや操作に関する変数

 

基本的に、ターンの開始時にリセットされます。

 

Dim actionNumber As Integer
 'ターンプレイヤーのアクション数を管理する変数。

Dim buyNumber As Integer
 'ターンプレイヤーの購入数を管理する変数。

Dim coinNumber As Integer
 'ターンプレイヤーのコイン数を管理する変数。

Dim journeyToken(1) As Boolean
 '各プレイヤーの旅人トークンの裏表を管理する変数。表がTrueで裏がFalse。裏返す操作は journeyToken(trnP) = Not journeyToken(trnP) となる。なかなか哲学的な気がする…

 

 

試行の取り決めや特殊な出力に関する(ブール)変数

 

Dim firstHandSpecial As Boolean
 '特殊な初手(デッキ2周目、3-4Tのデッキを想定する等)を使うかどうかの判断を入力する変数。これを設けなくても、特殊初手生成アルゴリズム指定関数を空にするかどうかで決められる気もするが…

Dim firstHandRandom(1) As Boolean
 '各プレイヤーについて、初手がランダムかどうかを入力する変数。下の初手パターンに4番目として組み入れればいいのでは…という気も。

Dim firstHandPattern(1) As Integer
 '各プレイヤーについて、初手のパターンを番号として入力する変数。0が4-3、1が3-4、2が5-2、3が2-5を表す。(最初は4-3かどうかを管理するだけだったのでブール変数だった。)

Dim thisRunIsActionBM(1) As Boolean
 '各プレイヤーについて、この試行がアクションステロであるかどうかを入力する変数。特に操作には影響しないが、アクション使用の有無の出力時に、アクション数のみをキーとして行うことができるので、それをする/しないを切り替えるために使う。コンボだとアクション使用が基本と思われるし、アクションを使い切るとも限らないため、実質的に残りアクション数0を出力することの意味はほぼないと思われる。

Dim opponentPresence As Boolean
 '対戦相手が存在するかどうかを入力する変数。

Dim actionCardNotPlayed As Boolean
 '手札にあるアクションカードを敢えて使わなかったことを記録する変数。基本的にはそれを出力するために参照する。

Dim buyProvinceEnabled As Boolean
 '購入アルゴリズムにおいて、属州を買ってもよいという判断を記録する変数。アクションカードの意思決定を行う際、そのターンに属州を買えるものの、購入条件を満たしていなかったとして、次のターンに条件を満たす可能性が非常に高い等の場合に、購入アルゴリズムにおいて改めて調べることがないよう、この変数を利用する場合がある。

 

 

カード番号から派生した変数

 

2次元の配列は、プレイヤー番号、カード番号の順番で定義しています。カード番号はコピーしてきた現在のものであり、今後変化する可能性があります。そもそもサプライに存在しない種類のカードや、分割山札のもの等(山札に戻す操作が働くことも考えると、山札内の順番を管理する必要がある)、これまでの枠組みで扱えないものもあり、それらのカードのためには更に広い定義が必要であると思われるが、現状は対応していません。

 

Dim cardName(89) As String
 '各カード番号に対応する、カードの名前を格納するための変数。例えば、0 に対しては "Copper" が対応する。現状はあまり利用していないが、カード使用時のプロシージャを playSmithy や playCopper のように作っているため、直接の名前指定で Call Application.Run("play" & cardName(番号)) と記述する際等に用いる。

Dim cardDisplayName(89) As String
 '各カード番号に対応する、カードの出力時の表示名を格納する変数。例えば、0 に対しては "銅" が対応する。表示上の都合で、全角1文字で統一しているが、多くのカードに共通する文字の場合等、分かりにくいことがある。交易所や交易人、交易路、(イベントだが購入で表示するので)交易等はどうすればいいのか…香辛料と香辛料商人も困る…商船のせいで商人ギルドは "ギ" にされてしまった…内部では違う番号なので、表示名が同じ値を持っていても、同じ試行で使用しないのならいいといえばいいのだが…

Dim cardCost(89) As Integer
 '各カード番号に対応する、カードのコストを格納するための変数。コストの変更を行う操作も存在するが、これに対応するためにコストリセット変数を作るべきなのかの判断を保留しているため、導入していない。

Dim cardType(89) As Integer
 '各カード番号に対応する、カードのタイプを格納するための変数。複数のタイプを格納するために、現状導入されているカードの範囲で言うと、財宝を 1 、勝利点を 2 、アクションを 4 、持続を 8 、夜行を 16 、リザーヴを 32 、リアクションを 64 、アタックを 128 として、複数のタイプを持つ場合、その合計値で以ってカードのタイプを表現する。特定のタイプに属するか調べるときは、調べたいタイプの数値の倍の数字で割り、その余りが調べたいタイプの数値以上か、数値未満か、で判断することができる。例えばハーレムはタイプ 3 であり、財宝属性を持つことは Mod 2 が 1 (>= 1)であることから判断でき、勝利点属性を持つことは Mod 4 が 3 (>= 2)であることから判断でき、アクション属性を持たないことは Mod 8 が 3 (<= 4)であることから判断できる。

Dim cardInSupply(89) As Integer
 '各カード番号に対応する、カードがサプライに残っている枚数を格納するための変数。カードが獲得される度に減っていき、ゲーム開始時にリセット配列を参照し、値がリセットされる。現状は3山枯れのゲーム終了条件を導入していないが、導入する場合は、空になったサプライ数を記録するパブリック変数を新たに作り、サプライが空になる度にカウントアップする必要がある。

Dim cardInSupplyReset(89) As Integer
 '各カード番号に対応する、カードがサプライに用意される枚数を格納するための変数。試行の開始時に各カード毎に条件に基づいて決定され、各ゲームの開始時に cardInSupply に代入される。…cardInSupply をリセットするプロシージャを作ってもよいが、それだと毎ゲーム(都合10000回)全カードを呼び出さなくてはならないので、サプライ定義関数を使って、必要なサプライ配列とサプライリセット配列のみを呼び出すことで、繰り返し回数を減らしている。その分、余計な変数が増えていることになるので、どちらの方が重いのかは分かりにくいところだが…

Dim cardInHand(1, 89) As Integer
 '各プレイヤー毎の、各カード番号に対応する、カードが手札にある枚数を管理する変数。カードの動きを管理するだけでなく、アクションの使用や、時にはカードの購入に影響を与える変数でもある。

Dim cardInPlay(1, 89) As Integer
 '各プレイヤー毎の、各カード番号に対応する、カードがプレイエリアにある枚数を管理する変数。基本的にはカードの動きを管理するのに使う。持続カードはこのターンに持続するものが持続エリアにあり、ターン開始時に効果を発揮した後プレイエリアに移動するため、持続した枚数を知るために参照されることがある。

Dim cardOwned(1, 89) As Integer
 '各プレイヤー毎の、各カード番号に対応する、カードを所持している枚数を管理する変数。基本的には、カードの獲得で増加し、カードの廃棄で減少する。金貨所持枚数や屋敷廃棄系を使うときの屋敷所持枚数等、カードの購入に影響を与える変数になることが多い。

 

 

イベント番号から派生した変数と各イベントにまつわる変数

 

イベント番号自体はカード番号と重複するものだが、大きい値を与えるのは、配列変数の大きさが無駄に大きくなるため、あまり好ましくない。そのため、購入時に1000番台の修飾をすることで区別することにしている。また、購入決定時とイベントの購入時効果処理時の2回、同じチェックを行わないために、例えば交易で廃棄する屋敷等の枚数を副次的な修飾として、100番台に行うなどしている。

 

Dim eventName(19) As String
 '各イベント番号に対応する、イベントの表示名を管理する変数。

Dim eventCost(19) As Integer
 '各イベント番号に対応する、イベントのコストを管理する変数。

Dim borrowed As Boolean
 '1ターンに1回しか購入のできない借入を、既に購入したかどうかを管理する変数。

Dim trashingToken(1) As Integer
 '各プレイヤー毎の、廃棄トークンの置かれたサプライ番号を管理する変数。

Dim eventExpedition As Integer
 '探検の購入回数を管理する変数。

Dim saved As Boolean
 '1ターンに1回しか購入のできない保存を、既に購入したかどうかを管理する変数。

 

 

プロジェクト番号から派生した変数と各プロジェクトにまつわる変数

 

イベント番号と同様の理由で、購入時には2000番台の修飾をしている。

 

Dim projectName(9) As String
 '各プロジェクト番号に対応する、プロジェクトの表示名を管理する変数。

Dim projectCost(9) As Integer
 '各プロジェクト番号に対応する、プロジェクトのコストを管理する変数。

Dim projectStarChart(1) As Boolean
 '各プレイヤ―毎に、StarCart を購入したかどうかを管理する変数。

Dim starChartPickCard(1) As Integer
 '各プレイヤー毎に、StarCart で優先的にデッキトッウに置きたいカードを管理する変数。現状はアクションカード1種類との併用までしか考えられていないため、この変数を使ってそのカードを管理する。空(-1)の場合は金貨を最優先に置く。

Dim projectCropRotation(1) As Boolean
 '各プレイヤ―毎に、CropRotation を購入したかどうかを管理する変数。

Dim cropRotated As Boolean
 'CropRotation の効果を既に使用したかどうかを管理する変数。現状だとアクションカード1種類との併用までしか行っておらず、無駄なチェックになっているが、ターン開始時の処理が増えてきた場合、この変数が必要になる可能性がある。

Dim projectPageant(1) As Boolean
 '各プレイヤー毎に、Rageant を購入したかどうかを管理する変数。

Dim projectGuildHall(1) As Boolean
 '各プレイヤー毎に、GuildHall を購入したかどうかを管理する変数。

Dim projectCityGate(1) As Boolean
 '各プレイヤー毎に、CityGate を購入したかどうかを管理する変数。

Dim cityGateBMCard(1) As Integer
 '各プレイヤー毎に、CityGate と併用するアクションカードを管理するための変数。現状はアクションカード1種類との併用までしかできず、そのカードが何であるかを管理するためにこれを使う。空(-1)の場合は CityGate お金プレイということになる。

Dim cityGated As Boolean
 'CityGate の効果を既に使用したかどうかを管理する変数。現状は無駄なチェックになっている。

Dim projectSilos(1) As Boolean
 '各プレイヤー毎に、Silos を購入したかどうかを管理する変数。

Dim siloed As Boolean
 'Silos の効果を既に使用したかどうかを管理する変数。現状は無駄なチェックになっている。

 

 

サプライ定義用の変数

 

Dim supplyCardNumber() As Integer
 'サプライに存在するカードの番号を格納するための変数。配列だが、定義された時点では要素数が確定していない。要素数は、サプライ定義関数において、まず supplyMaxNumber を入力し、それを用いて ReDim supplyCardNumber(supplyMaxNumber) As Integer として定義される。ゲーム開始時のカード番号に関連した各変数のリセットをする場合や、それぞれのアルゴリズムの処理に伴って、各カード毎に条件を調べる必要がある場合に、全てのカード番号に関して操作を行うことは、大抵の場合ほぼ無駄である。そこで、その試行において使用するカード番号が何であるかを予め定義しこの配列に格納しておくことで、一旦この配列を噛ませれば、全てのカード番号を調べなくても、試行中に必要なすべての変数にアクセスできる。

Dim supplyMaxNumber As Integer
 'サプライに存在するカードの種類を格納するための変数。上記の supplyCardNumber() の要素数を再定義する際に使用し、また、実際に1要素ずつ呼び出す際の繰り返しの上限としての役割を持っている。

 

 

その他の特殊な変数

 

Dim cardNumberTemporary As Integer
 '何らかの理由で他の処理部分にカード番号を受け渡す必要があるが、引数のリレーを設ける程には一般的な事情でないような時、一時的にその値をパブリック変数として格納しておくためのもの。保存を購入して脇に避けるカードのように、購入アルゴリズムの段階で決まっているが、その後実際の購入や購入物の出力の表記にまで必要となる情報を記録しておく。

Dim parameterDebugBool(1) As Boolean
 '入力値を切り替えることで、一部の操作に細かい違いを持たせるためのパラメーター変数。検証の内容次第では、本来のドミニオンにおける動作とは異なる動きをさせることが、より都合がよいこともある。例えば、見張り(1枚)ステロを検証したい場合、見張りを使用した際の効果処理を行う playLookout において、本来の見張りの効果に付随して、パラメーターを切り替えていた場合に限り、アクションを消費することにする。すると、一般的なステロにおけるアクション使用の判断条件が、アクションの消費に基づいているため、本来であるならばアクションを消費しない見張りにおいても、通常のステロと同様の枠組みでアクション使用を出力できるようになる。

Dim startTime As Date
 '試行開始時刻を記録する日付型の変数。必ずしも必要なものではないが、その検証にかかった時間をメモとして出力しておく。

Dim finishTime As Date
 '試行終了時刻を記録する日付型の変数。

 

 

 

…わりと見づらいですが…全てのパブリック変数についての解説は以上です。