はじめに
こんにちは。
ETA環境が始まって、OTKドラゴンが猛威を振るっているように見えます。直近の大会として、Tempostorm主催大会やJCGでも優勝しております。
そんなOTKドラゴンですが、なにかOTKを防ぐ手段はないだろうか?と考えたことはないでしょうか。
ぱっと思いつくもので、《招来の大天使》で体力の最大値を上げる、《眠れる輝竜・アーサー》でバリアをはる、などなど、20点疾走を防ぐ手段は結構あります。
しかし、その先に壁にぶち当たります。
「2枚のディズレスタンに疾走されたら終わりじゃん!!」
と。
2枚を防ぐためには、先ほど挙げた対策を2重に講じる必要があり、対策コストもかかるし、理想的な状態を挙げれば決して完ぺきではないということでどんどんしんどくなります。
ここまで考えると、次に思い浮かべるのが
「そもそもディズレスタン2枚走るのってどれくらいの頻度で発生しうるの?そんなに発生しないなら切ってもよくね?」
です。
超ざっくり考えると、「欲しいカードのうち少なくとも2枚引ける確率」という形で計算できるのですが、《神魚・ディズレスタン》素引きで達成できないパターンもあり得るので、そこってどうなんだろう?となります。
(《追憶の大天使》で戻せばいいじゃん!と言われればそうですが…)
なので、とりあえずその肌感覚を得るためにもざっくり計算してみました。ついでなので3枚疾走のパターンも計算しました。
計算条件
計算の条件を下記としました。
- 先攻を想定し、初期手札3枚で1ターン目から1枚ずつドローする
- 3ターン目以降は手札に《深海の接近》があればプレイする
- 《深海の接近》と《神魚・ディズレスタン》は3枚投入
- ターン終了時に手札に疾走を持った《神魚・ディズレスタン》が何枚あるかで計算する
- マリガン、追憶の大天使進化で戻すなどは考慮しない
マリガンを考慮しないのは、どういうマリガンするのかよくわかっておらず、問題がとても複雑になりそうだったからです。「とりあえず《深海の接近》を全力ねらい!」とかなら簡単なんですが、託宣はキープするよね、3枚《深海の接近》きたら流石に返すよね、とかキリがないなと思ったからです。
計算方法は、シミュレーションを用います。上記条件で計算を行い、とりあえず試行回数100万回やってみて、疾走を持った《神魚・ディズレスタン》を抱える割合を算出します。
具体的なソースコードはこの記事の最後に貼っておきます。(変なところに気づいたら教えてください)
計算結果
計算結果を下記に示します。
1ターンに1枚ドローの前提ですが、実際はたくさんドローすると思います。なので、これくらいドローするかな?という枚数分ターン数に加算して値を読み取ってください。
例えば、
- 7ターン目に2枚以上疾走を持つ《神魚・ディズレスタン》を抱える確率を知りたい
- 飛翔1回、卵2個分、ゼルガネイア1回、6枚余分に引く程度を想定しよう
という場合について解説します。
7ターン目+6枚余分にドローしているといことで、7+6=13のターン数のところと「疾走魚2枚以上」という欄の交差するところの値を読み取ります。読み取ると31.34%となっており、それが2枚抱えられる確率となります。
マリガンで引き直したり、《追憶の大天使》でシャカシャカしたりとあるので、確率はもっと上がると思います。
なので、ざっくり30%~40%くらいは2枚走られるのかなーくらいの肌感覚を持っていればいいのかなと思います。
ターン30を見ると60%くらいで収束している感じがするので、「どんなにドローされてもそんなもんなのか!」って思っちゃうかもしれませんが、実戦では《追憶の大天使》の進化効果があるので、そんなにドローするものだったら、この結果よりもだいぶ高くなりそうな気がしますね。
これくらいの事象に対して対策するかどうか……そこから先の戦略は考えるのが難しそうですね。
計算の考察と補足
計算結果について補足します。
上の表の「疾走魚1枚以上」の欄は、「3枚投入しているカードのうち、少なくとも1枚引ける確率」と近い値になります。しかしながら、《神魚・ディズレスタン》をすべて素引きしてしまう可能性がある分、それよりもやや低い値になります。(この確認をしたことでプログラムにバグがあるのを見つけられました……)
「疾走魚3枚以上」の欄が異様に低いのも、「《深海の接近》を3枚引き、かつ、《神魚・ディズレスタン》すべてがデッキ内にいる」というものなので、相当厳しいものとなっています。
おわりに
今期はアグロ~コントロール、OTKと色々なデッキがいて面白いなと思っています。来週のRAGEが楽しみです。
ソースコード
pythonで書いています。100行くらいで本記事の計算はできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
import random class Card: def __init__(self): self.name = 'カード' self.keyword = '' def play(self, hand, deck): return 0 class Fish(Card): def __init__(self): self.name = 'ディズレスタン' self.keyword = '' class EncounterFromDeep(Card): def __init__(self): self.name = '深海の接近' self.keyword = '' def play(self, hand, deck): tmp_list = [] for i in range(len(deck)): if deck[i].name == 'ディズレスタン': tmp_list.append(i) if not(tmp_list): return 0 tmp_num = random.choice(tmp_list) hand.append(deck.pop(tmp_num)) hand[-1].keyword = '疾走' return 0 class Simulator: def __init__(self, total_turn): self.hand = [] self.deck = [] self.total_turn = total_turn self.result1 = [0]*(total_turn + 1) self.result2 = [0]*(total_turn + 1) self.result3 = [0]*(total_turn + 1) def draw(self): tmp_num = random.randint(0, len(self.deck) - 1) self.hand.append(self.deck.pop(tmp_num)) def make_deck(self): self.deck=[None]*40 for i in range(40): if i < 3: self.deck[i] = Fish() elif i < 6: self.deck[i] = EncounterFromDeep() else: self.deck[i] = Card() def reset(self): self.hand = [] self.make_deck() self.draw() self.draw() self.draw() def check(self, turn): counter = 0 for i in range(len(self.hand)): if self.hand[i].name == 'ディズレスタン' and self.hand[i].keyword == '疾走': counter += 1 if counter >= 1: self.result1[turn] += 1 if counter >= 2: self.result2[turn] += 1 if counter >= 3: self.result3[turn] += 1 def run(self, N): for loop in range(N): self.reset() for turn in range(1, self.total_turn): self.draw() deep_idx = [] for i in range(len(self.hand)): if turn >= 3 and self.hand[i].name == '深海の接近': deep_idx.append(i) break if deep_idx: self.hand.pop(deep_idx[0]).play(self.hand, self.deck) self.check(turn) CALC_TURN = 31 TRIAL = 1000000 sim = Simulator(CALC_TURN) sim.run(TRIAL) for i in range(CALC_TURN): print(i, sim.result1[i]) for i in range(CALC_TURN): print(i, sim.result2[i]) for i in range(CALC_TURN): print(i, sim.result3[i]) |