机上のkuwa論

デュエルマスターズ考察 / 間違いがあればコメントでご指摘お願いします

ディールシャッフルの規則性


はじめに

8山切りのあとに、5山切りをするとデッキのカードの並びがもとに戻る”事実をご存じでしょうか?

wikiによると”1回目の山の数と2回目の山の数の積がデッキの枚数になるようにディールシャッフルを行う”と山がもとの順番になるそうです。例えば、dmでは4山切りした後に10山切りをしたら元に戻ります。

では、40の約数の2,4,5,8,10,20での組み合わせで他に元に戻る切り方があるのでしょうか?
それは何通りでしょうか?

そこで今回の記事は
「8切り後に5切りする他に山の順番がもとに戻る組み合わせの検証」
「8切りのあとに5切りをすると元に戻ることを数学的に説明」

の2つのテーマを扱います。

索引

ディールシャッフル

みなさまは普段どんなシャッフルをしているでしょうか? 
ディールシャッフルは通称~山切りなどと呼ばれ、8山切りであれば、8つの山にそれぞれデッキのカードを分配したあとに、その山を戻すシャッフルです。

ディールシャッフルはデッキの枚数確認にも利用されたり(これはイカサマ防止としても有用な手段です。)4積みのカードが固まっている状態を分散させるためにします。ただし、ディールシャッフルは無作為化には適していません。どうしても規則性が生まれてしまいます。

MTGのイベント規定では 引用: ディール・シャッフル(Pile Shuffle、俗に○山切りとも呼ばれる)は、ゲーム開始時にそれぞれ1回カードを数える目的で行われることを除いて認められない。 ようです。今回の記事の主張とずれますが、複数の種類のシャッフルを行うことが推奨されています。

山の順番がもとに戻る組み合わせ

今回は8山切りを1回したあとに、2山切り、4山切り、5山切り、8山切り、10山切り、20山切りのいずれかを複数選択した組み合わせをシミュレーションしました。
そして、回数が多いシャッフルをしても現実のケースと乖離するため6回までのシャッフルで検証します。
「8 -> 5」という表記は8山切りのあと、5山切りをすることを表しています。
以下に結果を折りたたんでいます。

結果の考察

415通りありました。
「8 -> 5 -> 8 -> 5」など、1回もとに戻る場合は除去したつもりです。
「8 -> 10 -> 20」と「8 -> 20 -> 10」は行っていることは同じなので、消せるかもしれません。
ぜひお手元のデッキで山順が元に戻るか確認してみてください。

8切り後、5切りをすると元に戻ることを数学的に説明

デッキをシャッフルする行為は線形代数の行列っぽい見た目な置換で表せます。
簡単に述べると、置換は1行目であるカードの並びをどの位置に移動するかを2行目に対応させる形式です。詳しいことは参考文献を読んでください。

8山切りのシャッフル行為を置換  \sigma
5山切りのシャッフル行為を置換  \tau  とすると、

8山切りのあと、5山切りをすることは置換の積  \sigma \tau をとることと同値です。



  \sigma = \left(
    \begin{array}{ccc}
      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      \\
      1 & 6 & 11 & 16 & 21 &26 & 31 &36 & 2 & 7 & 12 & 17 &22 & 27 & 32 & 37 & 3 & 8 & 13 &18 &23 & 28 &33 &38 &4 & 9& 14 & 19 & 24 & 29 & 34 & 39 &5 & 10& 15&20 &25 &30&35&40 
    \end{array}
  \right)



  \tau = \left(
    \begin{array}{ccc}
            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      \\
      1 & 9 & 17 & 25 & 33 & 2 & 10 & 18 &26 & 34 & 3 & 11 & 19 & 27 &35 & 4 & 12 & 20 & 28 & 36& 5 & 13 & 21 & 29 & 37 & 6 & 14 & 22 & 30 & 38 & 7 & 15 & 23 &31 & 39 & 8 & 16 & 24 & 32 & 40 
    \end{array}
  \right)



  \sigma \tau = \left(
    \begin{array}{ccc}
      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      \\
      1 & 6 & 11 & 16 & 21 &26 & 31 &36 & 2 & 7 & 12 & 17 &22 & 27 & 32 & 37 & 3 & 8 & 13 &18 &23 & 28 &33 &38 &4 & 9& 14 & 19 & 24 & 29 & 34 & 39 &5 & 10& 15&20 &25 &30&35& 40 
    \end{array}
  \right)
 \left(
    \begin{array}{ccc}
            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      \\
      1 & 9 & 17 & 25 & 33 & 2 & 10 & 18 &26 & 34 & 3 & 11 & 19 & 27 &35 & 4 & 12 & 20 & 28 & 36& 5 & 13 & 21 & 29 & 37 & 6 & 14 & 22 & 30 & 38 & 7 & 15 & 23 &31 & 39 & 8 & 16 & 24 & 32 & 40 
    \end{array}
  \right)

ここで置換の相等より置換  \tau の上段の並びを,置換  \sigma の下段の並びに合わせると



  \sigma \tau = \left(
    \begin{array}{ccc}
      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  \\
      1 & 6 & 11 & 16 & 21 &26 & 31 &36 & 2 & 7 & 12 & 17 &22 & 27 & 32 & 37 & 3 & 8 & 13 &18 &23 & 28 &33 &38 &4 & 9& 14 & 19 & 24 & 29 & 34 & 39 &5 & 10& 15&20 &25 &30&35 & 40 
    \end{array}
  \right)
 \left(
    \begin{array}{cc}
           1 & 6 & 11 & 16 & 21 &26 & 31 &36 & 2 & 7 & 12 & 17 &22 & 27 & 32 & 37 & 3 & 8 & 13 &18 &23 & 28 &33 &38 &4 & 9& 14 & 19 & 24 & 29 & 34 & 39 &5 & 10& 15&20 &25 &30&35&40 \\
           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      
       
\end{array}
  \right)



   = \left(
    \begin{array}{ccc}
            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      \\
     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      
    \end{array}
  \right)

となります。この置換の積  \sigma \tau の結果は、
上段を下段の位置に移動するという意味なので、
これはつまり、そのまま元の山順に戻るということです。

こうして、他のディールシャッフルに関しても置換の積を使って説明できます。

あとがき

今回は40の約数のみの切り方で検証しましたが、7山切りや9山切りなどの奇数切りも競技シーンで行われるため、40の約数以外の切り方でもシミュレーションしても面白いかもしれません。また、パケット(分配後の山)の重ね方がパケット数をdとすると d! 通りあるので、さらに組み合わせが多くなります。

組み合わせの検証には過去に作成したディールシャッフルプログラムを再利用しました。今後、行列の置換で作り直していこうと思います。そうすればどんなシャッフルでも楽に実装できそうです。そして実行速度が早い。

ファローシャッフルとディールシャッフルの組み合わせでデッキが元に戻る検証も一応行ったのですが、文献を読んでいるとファローシャッフルは確率的にカードが重なりあい、それはGilbert–Shannon–Reeds modelに沿うようです。過去に作成したファローはいわゆるパーフェクトシャッフルと呼ばれるもので、確率的にはシャッフルしていません。一意に決まります。というかパーフェクトシャッフルも、ディールシャッフルと同じように規則性が生まれるためシャッフルとしては適していないし、繰り返すと確実にもとに戻ることが予測できます。

ディールシャッフルの複数の山切りで元に戻る厳密な証明や、感覚的な説明は他の方に任せたいと(ぜひご自身のブログで)思います。

参考文献:トランプのシャッフルにおける可視化と最適な組み合わせに関する検討 "井手 広康 奥田 隆史 "
URL : https://www.ipsj.or.jp/award/9faeag0000004f1r-att/CF-011.pdf

シールド・トリガーとモンティ・ホール問題

 むかしむかし、あるところにカミ神王子とコロコロカーくんがデュエルマスターズで遊んでいました。

f:id:kuWaan:20201104205240p:plain

カミ神王子は何らかの方法を使って、3枚残っているシールドのうち2枚がシールド・トリガー(以降S・トリガー)であり、残りの1枚がS・トリガーではないことを知っていました。
f:id:kuWaan:20201104203907p:plain
カミ神王子は3枚のシールドのうち、1枚をブレイクしようとしました。
f:id:kuWaan:20201104203933p:plain

しかし、コロコロカーくんは、カミ神王子が選択したシールドではない1枚をめくってしまいました。
(コロコロカーくんは、シールドゾーンのシールド・トリガーの位置を知っていて、故意にシールド・トリガーをめくりました)

コロコロカーくん「シールドトリガー発動!デーモンハンド!」

カミ神王子「ちょっと待った。」

f:id:kuWaan:20201104204841p:plain

コロコロカーくんはS・トリガーを使おうとしましたが

カミ神王子が指摘し、コロコロカーくんはめくったS・トリガーをシールドゾーンに戻すことになりました。

f:id:kuWaan:20201104205358p:plain

カミ神王子はコロコロカーくんがめくってしまったシールド以外の残り2枚のシールドからシールドを再選択するか悩みました。

f:id:kuWaan:20201104205459p:plain

Q. このとき、一番初めにカミ神王子が選択していたシールドをブレイクするか、

それとも選び直して別のシールドを直すかどちらが良いでしょうか?


王子「3枚中、1枚だけS・トリガーじゃないことがわかっているね〜。」

カーくん「僕がS・トリガーのシールドを1枚間違えて開いちゃった・・・。」
f:id:kuWaan:20201104204951p:plain
王子「じゃあ、残り2枚はS・トリガーが1枚、S・トリガーではないのがそれぞれ1枚だから、」

カーくん「うん。うん。」

王子「僕が初めにブレイクしようとしたシールドをブレイクしても、選びなおして残り1枚をブレイクしても同じ確率じゃない?」

カーくん「・・・。(考え込む)」

f:id:kuWaan:20201104205647p:plain

王子「どちらかがトリガーで、どちらかがトリガーじゃないから確率はどちらも同じ1/2で50%だ!」

デュエマの達人D「それは違うよ!」

王子&カーくん「え!?」

デュエマ達人D「選びなおしたほうが、はじめに選択したシールドをブレイクするよりも安全だよ!」

カーくん「じゃあ、どれくらい確率は変わるの?」

達人D「 選びなおしたら、S・トリガーである確率が半分になるんだ!!

カーくん「具体的にはどんな確率になるの?計算手順も教えて。」

達人D「よかろうに。

ブレイクするシールドを変えなければS・トリガーではない確率が1/3 (約33%)

ブレイクするシールドを変えればS・トリガーではない確率は2/3(約67%)になるよ。」

王子「えー!?1/2じゃないの?」

達人D「解説するよ。便宜的にS・トリガーじゃないことを"not・Sトリガー"と呼んで、」

f:id:kuWaan:20201104211114p:plain

達人D「こんな感じで左からシールドをA、B、Cと名付けるよ。」

f:id:kuWaan:20201104211201p:plain

達人D「そして、AとCにS・トリガー、Bにnot S・トリガーが埋まっていることを考えるよ。まずは、カミ神王子が初めにブレイクしようとしたシールドを変えない場合、not・Sトリガーである確率を求めるよ。」

f:id:kuWaan:20201104211300p:plain

達人D「カミ神王子が初めにBのシールドをブレイクしようとすると、その後シールドを変えないからnot・Sトリガーだよね。

3枚のうちnot・Sトリガーが1枚だから、確率は1/3となるよ。

そして、今回はブレイクするシールドを変えないからnot・Sトリガーであるのはこの1パターンだけだよ。

よって、カミ神王子が初めにブレイクしようとしたシールドを変えない場合、not・Sトリガーである確率は1/3だよ。

次に、カミ神王子が初めにブレイクしようとしたシールドを変える場合、not・Sトリガーである確率を求めるよ。

次の2つのパターンがあるよ。

f:id:kuWaan:20201104211440p:plain
( i )カミ神王子が初めにAをブレイクしようとする。
f:id:kuWaan:20201104211731p:plain
( ii )カミ神王子が初めにCをブレイクしようとする。」

f:id:kuWaan:20201104211812p:plain

達人D「( i )のとき、コロコロカーくんはS・トリガーであるCを必ずめくってしまうので、」

f:id:kuWaan:20201104211852p:plain

達人D「王子がブレイクするシールドを変えれば、

not・SトリガーであるBをブレイクするよ。

シールド3枚のうちnot・Sトリガーが1枚だから、確率は1/3となるよ。」

f:id:kuWaan:20201104211941p:plain

達人D「( ii )のとき、コロコロカーくんはS・トリガーであるAを必ずめくってしまうので、」
f:id:kuWaan:20201104212013p:plain
達人D「王子がブレイクするシールドを変えれば、not・SトリガーであるBをブレイクするよ。

シールド3枚のうちnot・Sトリガーが1枚だから、確率は1/3となるよ。

よって、( i ), ( ii )の2パターンがあるから、

カミ神王子が初めにブレイクしようとしたシールドを変える場合、not・Sトリガーである確率は

1/3+1/3=2/3となるよ。」

カミ神王子「なるほど!シールドを変えるか変えないかの単純な二択問題と思い込んでいたから確率を1/2と間違えたんだ。」

コロコロカーくん「でもさ、カミ神王子は、どうやって3枚中2枚がS・トリガーって分かっていたの?」

達人&筆者「」







*この物語はフィクションです。
*彼らはカジュアルに遊んでいます。

あとがき

なんとも直感とズレてしまう問題でした。

http://dmpfpark.seesaa.net/category/22343372-1.html

書き上げた後ググったら、先人たちによってdmブログの記事がありました。つまり、二番煎じです。
ハンデスのほうが一応、現実にあり得るケースかもしれません。

また、コロコロカーくんが故意に選択されたシールドではない、Sトリガーであるシールドを選ぶ行為は完全にOUTです。
カミ神王子が初めにブレイク選択したシールドを変えちゃうあたりもルール的にまずいですね。

実は、必ずコロコロカーくんがS・トリガーのシールドをめくってしまうという前提条件がこのモンティホール問題のポイントです。

参考

モンティ・ホール問題参考:
analytics-notty.tech
ほぼここの記事の解説を引用し(パクリ)ました。

モンティ・ホール問題は有名なのでググればいろんな解説が読めます。面白いのでぜひぜひ。
条件付き確率で考えると計算がわかりやすいです。
直観的にはシールドの枚数を増やすとわかりやすいみたいです。

シールド・トリガー確率をはじめからていねいに〜後編〜

f:id:kuWaan:20190811134754p:plain

つづき

前編を読んだ方は、シールド・トリガーの確率と期待値計算が、どう計算されているか理解してくれたと思います。

前編読んでない方は先にこちらをお読みください。

なお、今回の内容は、前編よりも数式多めかつ小難しい内容で、オリジナルの視点から考察していきます。ちょっとしんどいかもしれません。

そこで、「確率 ? は ? そんなん手を2回叩いて盾にお祈りしたらええやん。」って人に期待値が身近であると知ってもらいたいので、コーヒーブレイクとして少し雑談をします。興味ない方は飛ばして下さい。

索引

(雑談) DMGPで入賞して、やきにく代が稼げるのか簡単に計算してみた。

デュエル・マスターズプレイヤーは、よく「優勝して焼肉おごる」宣言をします。
界隈には、大型大会でプロモやゲーム機を獲得し、売却し、プレイヤーはよく一緒に調整する仲間、いわゆる身内とともに焼肉に行く風潮が存在します。

というわけでトーナメントガチ勢DMPはGPで稼いで焼肉をおごれるのか、はたまた、 そもそも参加費と交通費で焼肉にいったらいいのか知りたいので計算してみましょう。

今年の4月13日と4月14日に開催されたDMGP8thを例にあげましょう。DMGP8thは予選がスイスドロー式で9回戦、決勝トーナメントが勝ち抜け方式で7回戦で行われました。

つまり、予選+決勝で16回戦ありますが、決勝トーナメントで勝ち、ベスト8に入れば《超戦龍覇 モルトNEXT》 GP限定Verと《奇石 ミクセル/ジャミング・チャフ》GP限定Verを獲得することができます。

よって、予選+決勝で13回戦勝ち続ければ、そのGPプロモを獲得できるというわけです。

あるAさんとBさんが1回対戦すると、それぞれ勝つ確率が \displaystyle \frac{1}{2}、負ける確率が \displaystyle \frac{1}{2}です。

よって、予選+決勝で13回戦勝ち続ける確率は

 \displaystyle({\frac{1}{2} })^{13} = \frac{1}{8192} = 1.220703125 \times 10^{-4}



《奇石 ミクセル/ジャミング・チャフ》は、メルカリで約7万弱で取引されていました。

《超戦龍覇 モルトNEXT》 は、メルカリで約70万弱で取引されていました。

よって、

 \displaystyle({\frac{1}{2} })^{13} \cdot 770000 = 93.99414063・・・

結論:DMPがGP8thに出場し、ベスト8まで勝ち続けると、93円稼ぐことが期待されます。

93円では焼肉にいけないので、交通費と宿泊費で身内と焼肉にいきましょう。




すいません。 ↑の計算は実は真っ赤な嘘が入ってます。
対戦にはいろんな要素があるので、確率 \frac{1}{2}は厳密ではありません。当たり前ですけど、dm上手い人は勝つ確率が高いですから。また、予選のスイスドロー式はOMWが関わってくるので、予選を勝ち抜く確率が複雑です。今回の思考実験では「全て全勝する」と簡単化しています。
単純に勝率は求まらないんで、期待値計算できません。残念。もしもコイントス大会だった場合とかですかね。まあ、あんま意味ないですね。期待値に興味持ってくれれば幸いですというお話でしたー。


「初手シールドにおけるS・トリガー率、および期待値」を求める一般式

前編では、具体例で確率計算をしました。その計算を一般化(どの枚数であっても、当てはめて確率を求めることができる式に)しましょう。

前編の最後に、一般化しました。これですね。
期待値: E(x) = 1 \cdot p_1 +2 \cdot p_2+3 \cdot p_3 +4 \cdot p_4+5 \cdot p_5  \cdot \cdot \cdot (A)
この p_iについても一般化できることに気づいたので、示します。

デッキに、シールドトリガーを x枚採用したとき、


 p_1 p_1 =  \displaystyle \frac{x}{40}  \cdot \frac{40-x}{39}  \displaystyle \cdot \frac{39-x}{38} \cdot \frac{38-x}{37} \cdot \frac{37-x}{36} \cdot {}_5C_1  = {}_5C_1 \cdot \displaystyle \frac{x(40-x)(39-x)(38-x)(37-x)}{{} _{40}P_5}
 = {}_5C_1 \cdot \displaystyle \frac{{}_{x}P_1  \cdot  {}_{40-x}P_4}{{} _{40}P_5}


 p_2 p_2 =  \displaystyle \frac{x}{40}  \cdot \frac{x-1}{39}  \displaystyle \cdot \frac{40-x}{38} \cdot \frac{39-x}{37} \cdot \frac{38-x}{36} \cdot {}_5C_2  = {}_5C_2 \cdot \displaystyle \frac{x(x-1)(40-x)(39-x)(38-x)}{{} _{40}P_5}
 = {}_5C_2 \cdot \displaystyle \frac{{}_{x}P_2  \cdot  {}_{40-x}P_3}{{} _{40}P_5}


 p_3 p_3 =  \displaystyle \frac{x}{40}  \cdot \frac{x-1}{39}  \displaystyle \cdot \frac{x-2}{38} \cdot \frac{40-x}{37} \cdot \frac{39-x}{36} \cdot {}_5C_3 =  {}_5C_3 \cdot \displaystyle \frac{x(x-1)(x-2)(40-x)(39-x)}{{} _{40}P_5}
 = {}_5C_3 \cdot \displaystyle \frac{{}_{x}P_3  \cdot  {}_{40-x}P_2}{{} _{40}P_5}


 p_4 p_4 =  \displaystyle \frac{x}{40}  \cdot \frac{x-1}{39}  \displaystyle \cdot \frac{x-2}{38} \cdot \frac{x-3}{37} \cdot \frac{40-x}{36} \cdot {}_5C_4 =  {}_5C_4 \cdot \displaystyle \frac{x(x-1)(x-2)(x-3)(40-x)}{{} _{40}P_5}
 = {}_5C_4 \cdot \displaystyle \frac{{}_{x}P_4  \cdot  {}_{40-x}P_1}{{} _{40}P_5}


 p_5 p_5 =  \displaystyle \frac{x}{40}  \cdot \frac{x-1}{39}  \displaystyle \cdot \frac{x-2}{38} \cdot \frac{x-3}{37} \cdot \frac{x-4}{36} \cdot {}_5C_5 =  {}_5C_5 \cdot \displaystyle \frac{x(x-1)(x-2)(x-3)(x-4)}{{} _{40}P_5}
 = \displaystyle {}_5C_5 \cdot \frac{{}_{x}P_5 }{{} _{40}P_5}



(A)に上記 p_iを代入して、式を整えると、
期待値:

 E(x) =  \displaystyle  \frac{5}{{}_{40}P_5}( {}_{x}P_1 \cdot {}_{40-x}P_4 + 4 \cdot {}_{x}P_2 \cdot {}_{40-x}P_3 + 6 \cdot {}_{x}P_3 \cdot {}_{40-x}P_2 + 4 \cdot {}_{x}P_4 \cdot {}_{40-x}P_1+{}_{x}P_5 \cdot {}_{40-x}P_0 )


さらにΣで書くと、

「初手シールドにおけるS・トリガー率、および期待値」を求める一般式は、

デッキに、シールドトリガーを x枚採用したとき、



期待値: E(x) = \displaystyle \sum_{k=1}^5 \frac{k \cdot {}_{5}C_k \cdot {}_{x}P_k \cdot {}_{40-x}P_{5-k}}{{}_{40}P_5}


ときれいに整えることができました。
数学得意な人、数式チェックお願いします。もっときれいにできるかもしれません。リプorコメント待ってます。

「なぜ、計算式の一般化にこだわるのか?」という人がいるかもしれません。それは、式の抽象度をあげると、プログラムで期待値計算をコンピュータに任せることができるからです。上で定義した式をPythonプログラムで書いてみました。参考程度にどうぞ。

import math
print('シールド・トリガー期待値計算プログラムを起動しました.')
print('何枚デッキにシールド・トリガーを入れますか?、入力してください.')
x = input('シールド・トリガーの枚数: ') #任意の枚数を入力 
x = int(x)

def permutations_count(n, r): #順列計算用
	if n -r <= 0 or n <= 0: 
		return 1
	else:
		return math.factorial(n) // math.factorial(n - r)
    
def combinations_count(n, r): #組み合わせ計算用
	if n - r  <= 0  or n <= 0:
		return 1
	else:
		return math.factorial(n) // (math.factorial(n - r) * math.factorial(r))

def func1(k): #k
	return k

def func2(k): # 5Ck
	return combinations_count(5,k)

def func3(x, k): #xPk
	return permutations_count(x,k)

def func4(x,k): #40-xP5-k
	return permutations_count(40-x,5-k)

def func5(): #40P5
	return permutations_count(40,5)

def sigma(func1,func2,func3,func4,func5): 
    result = 0
    for k in range(1, 6):
        result += (func1(k)*func2(k)*func3(x,k)*func4(x,k))/func5() 
        if k == 1:
        	p1 =  (func1(k)*func2(k)*func3(x,k)*func4(x,k))/func5()
        elif k == 2:
        	p2 =  (func1(k)*func2(k)*func3(x,k)*func4(x,k))/func5()
        elif k == 3:
        	p3 =  (func1(k)*func2(k)*func3(x,k)*func4(x,k))/func5()
        elif k ==4:
        	p4 =  (func1(k)*func2(k)*func3(x,k)*func4(x,k))/func5()
        elif k == 5:
        	p5 = (func1(k)*func2(k)*func3(x,k)*func4(x,k))/func5()    
        	
    print()
    print('シールド・トリガーがシールドに1枚入っている確率は{}%です.'.format(round(p1*100,2)))
    print('シールド・トリガーがシールドに2枚入っている確率は{}%です.'.format(round(p2*100/2,3)))
    print('シールド・トリガーがシールドに3枚入っている確率は{}%です.'.format(round(p3*100/3,3)))
    print('シールド・トリガーがシールドに4枚入っている確率は{}%です.'.format(round(p4*100/4,3)))
    print('シールド・トリガーがシールドに5枚入っている確率は{}%です.'.format(round(p5*100/5,3)))
    print()
    print('シールドに{}枚入っていると期待されます.'.format(round(result,2)))

sigma(func1,func2,func3,func4,func5) 


実行結果はこんな感じです。



f:id:kuWaan:20190816005410p:plain

デッキに積むシールド・トリガーの枚数を1~40で入力すると、期待値を自動的にプログラム通り計算機が計算してくれます。Python3.x系がある読者の方は、コピペして、動かしてみてくださいね。

この期待値はゲームで本当に役に立つのか? 実際に検証してみた。

ここまでは、先人たちが計算してきたことでした。ここからは私のオリジナルの視点から
期待値計算について考察していこうと思います。

果たしてこの期待値はデュエルマスターズ の試合で役に立つのでしょうか?
つまり、「期待値は理論値で一応出てるけど、本当にその枚数積めば安心なの?」「期待値なんてただの数字で、実際のDMの試合に何にも関係ないでしょ」「実際のゲームじゃ、計算値のズレがあるのでは?」という議題を検証、証明しようということです。

では検証しましょう。検証方法として、カードを40枚用意して、シールドトリガーを入れて、シャッフルして、机の上に並べて、実際に何枚シールドトリガーが入っているか人力でデータをとるという手段が考えられます。それを何百回、何千回、何万回と繰り返せば、確率(期待値)がいい感じに収束しそうです。

しかし、私はそれはめんどくさいのでPythonプログラムで上記の手法を仮想上で再現しました。コンピュータ(計算機)は、何百回、何千回、何万回のシャッフル処理やシールド・トリガーの確認処理も電気信号が伝わる速度、クロックが立ち上がる時間で、計算が可能です。便利で、楽ですよね。

さあ、デッキにシールド・トリガーを8枚積んだとき、実際に何枚ほど入っているのかを見てみましょう。

試行「 デッキは40枚で構成し、シールド・トリガーを8枚デッキに積んでいるとする。このとき、シャッフルして完全にデッキがランダムになっている状態で、
デッキの上から5枚を確認し、シールド・トリガーが入っている枚数のデータをとる。確認し終わったら、再びシャッフルする。」

上記の試行を1千万回繰り返して、データをとって期待値を計算してみます。さて、これまで理論的に求めていた期待値は、どれくらい信用ができる、つまり実際に試行して得た値と近い値が出るか、外れた値が出るのでしょうか ?


結果



f:id:kuWaan:20190817001106p:plain:w1000

なんと、ほぼほぼ理論値と一致しました ! つまり、期待値は信用できるということです !
面白いですね。桁数のオーダーによりますが、四捨五入すると理論値と一致すると
結論づけて問題ないでしょう。以上の結果より、デュエル・マスターズ公式が推すように、
デッキにシールド・トリガーを最低8枚は積みたいですね。
そうすれば、シールドにシールド・トリガーが1枚入っていることが期待できます。

プログラム解説

そんなに長いコードじゃないので、あんまり解説することないのですが、せっかくなので乗っけておきます。
Python 3.x系の環境があれば、ぜひご自身のマシンで試してみてください。「シャッフルするランダム関数は本当にランダムシャッフルになっているかい?、所詮計算機の乱数はランダムでないでしょ?」という疑問が湧いて当然だと思います。実はPythonにおけるrandom関数の乱数発生はメルセンヌ・ツイスタというアルゴリズムが用いられていて、かなり精度の高い、独立な乱数を発生させます。この2つの文献がとても勉強になりました。詳しくはここを読んでみてください。
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/TEACH/ichimura-sho-koen.pdf
random --- 擬似乱数を生成する — Python 3.7.4 ドキュメント

n =10000000 #何回、試してみるか 
import random
deck = []
c1 = 0 #トリガーが盾に1枚のときのカウンタc1 
c2 = 0 #トリガーが盾に2枚のときのカウンタc2
c3 = 0 #トリガーが盾に3枚のときのカウンタc3
c4 = 0 #トリガーが盾に4枚のときのカウンタc4
c5 = 0 #トリガーが盾に5枚のときのカウンタc5

for i in range(32):  #デッキに32枚入れる
	deck.append('N')
for i in range(8): #デッキに8枚シールド・トリガーを入れる
	deck.append('ST')

for i in range(n): #n回繰り返して、データをとる
	random.shuffle(deck) #シャッフル
	indexD = deck[0:5] #デッキから上5枚とる
	STnum = indexD.count('ST') #STの枚数をカウント
	
	#期待値計算のために各事象をカウント
	if STnum == 1:
		c1+=1
	elif STnum ==2 :
		c2+=1
	elif STnum ==3 :
		c3+=1
	elif STnum ==4 :
		c4+=1
	elif STnum == 5:
		c5+=1

EV = (1*c1+2*c2+3*c3+4*c4+5*c5)/n #期待値計算

print()
print('シールド・トリガーがシールドに1枚入っている確率は{}%です.'.format(c1/n*100))
print('シールド・トリガーがシールドに2枚入っている確率は{}%です.'.format(c2/n*100))
print('シールド・トリガーがシールドに3枚入っている確率は{}%です.'.format(c3/n*100))
print('シールド・トリガーがシールドに4枚入っている確率は{}%です.'.format(c4/n*100))
print('シールド・トリガーがシールドに5枚入っている確率は{}%です.'.format(c5/n*100))
print()
print('シールドに{}枚入っていると期待されます.'.format(EV))

デッキをリストで管理して、
1番目のfor文で、シールド・トリガーでない任意のカードを'N'として、リストに追加します。
2番目のfor文で、シールド・トリガーであるカードを'ST'として、リストに追加します。
3番目のfor文でシールドチェックとその都度ランダムシャッフルを1千万回繰り返しています。

最後に、各事象でのカウントした値をnで割ることで、確率を求めることができ、それぞれ1,2,3,4,5を掛けて足すと期待値が計算できます。

プログラムを立ちあげるごとに、乱数によって、若干、期待値や確率が異なりますが、ほぼ同じ値に収束します。

あとがき

この内容についてご意見がある方は、コメントで書いてもらうか、リプをTwitterにください。(見てないことがあるかもしれないけど、
厳密性にかけている場合があるかもしれないので、今後の考察に活かしたいです! )。またこの記事の内容をもとに自身のブログ記事で発展されることや、批判されることを大いに期待しています 。数学得意な読者のかた、一般式を整えてください。DMブログ大好き人間なので、他の人の意見を聞いてみたいです。
当ブログの全記事は完全にリンクフリーで、かつ内容も全て勝手に引用しても構わないです。何も声かけずやっちゃってください。ブログ名とURL貼ってくれると、主はとても喜びます。

シールド・トリガー確率をはじめからていねいに〜前編〜

f:id:kuWaan:20190807045653j:plain:w300
シールド・トリガーで相手の切り札を倒せ!! デッキに合計8枚以上入れると、グンっと防御力が上がるぞ!

あらすじ

デュエル・マスターズはシールド・トリガーという逆転の要素をもっています。
今日、「トリガーが盾に0で負けた〜」などの声をしばしば耳にし、このことから、DMブロガーやTwitterユーザーなどを中心に
「デッキに入れるべきシールド・トリガーの枚数」が議論され、結論が出されています。もちろん、数字だけがゲームの全てではないと思います。天才的なDMプレイヤーはデッキに必要なカードを何枚入れれば良いか、経験則的に体で覚えているからです。しかし、私はそういった感覚がないため、数字の側面からアプローチしてみることにします。

新DMwikiにてシールド・トリガー確率が計算され、表が掲載されています。
確率表 - デュエルマスターズ Wiki

また、最近であればガチまとめ様の西川航平氏によってシールドトリガーの確率について記事をあげられています。

上記がどう計算されているか、詳細に書かれていないため、
そこらへんをゆっくり丁寧にこの記事で掘り下げていきましょう。

期待値とは、どのような尺度に成りうるか?

上記で取り上げたシールド・トリガーの議論は、期待値を計算しています。
確率は一般的に離散型確率分布と連続型確率分布に分類できます。
離散型確率変数はとびとびの値が取られる事象で隣りあう数字間に値は取らないと定義されています。
DMにおいてデッキはカード40枚で構成されています。例えば、ドローするとき1.4枚引くなどの操作ができないです。
よって、DMというカードゲームは離散型確率分布に分類されると考えます。

離散型確率分布における期待値は以下のように定義されます。

期待値 :  \displaystyle E(x)=  \displaystyle \sum_{i=0}^n x_i p_i

x_iは実際に取る値です。例えば、シールドゾーンにトリガーが"3"枚入っている事象とすれば、x_iは3となります。
p_iは事象が起こる確率です。デッキ40枚中にAというカードが1枚入っていたら, そこから一枚デッキをめくったときAがでる確率p_i \displaystyle \frac{1}{40}となります。

期待値とは、ある試行を行ったとき,その結果として得られる数値の平均値のことです。例えば"ギャンブルや宝くじなら、平均してどれぐらい儲かるか。 サイコロの目の数値なら、平均していくつの目が出るか。"(参考http://wakarimath.net/explanation/q.php?pID=E00079)を理解する尺度になります。
期待値自体は中学校や高校で習う数学の概念です。「え、期待値と平均って計算値が異なるよね?期待値と平均って何が違うの?」と思った読者のみなさん、正解です。

大学レベルでの確率論の期待値は平均を指します。これを少しだけ、かいつまんで説明します。
平均を \overline{x} 、期待値を E(x)とします。
 \overline{x}= \displaystyle \sum_{i=0}^n  \frac{x_iN_i}N
 \displaystyle E(x)=  \displaystyle \sum_{i=0}^n x_i p_iと定義されます。
ここで大数の法則より, 標本サイズ Nが∞に大きくなるとき、確率p_ip_i=\frac{N_i}{N}に収束します。
よって、確率分布の期待値は母集団の平均と一致するのです!面白いですよね。

詳しく知りたい人は以下のURLから飛んで読んでみてください。
参考:「期待値と平均の違いについて」https://to-kei.net/basic/glossary/expected-value/

さあ、皆も一緒に期待値を計算してみよう。

長々と、説明してきましたが実際に計算をしてみましょう。

例えば、シールドトリガーをデッキに8枚入れているとき 、シールドゾーン5枚の中にシールド・トリガーが埋まっている」期待値を求めてみよう。
「シールドゾーンに1枚シールドトリガーが埋まっている」確率  p_1 p_1= \frac{8}{40}  \cdot \frac{32}{39}  \cdot \frac{31}{38} \cdot \frac{30}{37} \cdot \frac{29}{36} \cdot _5C_1 = 0.43719833319・・・・・
「シールドゾーンに2枚シールドトリガーが埋まっている」確率 p_2 p_2= \frac{8}{40}  \cdot \frac{7}{39}  \cdot \frac{32}{38} \cdot \frac{31}{37} \cdot \frac{30}{36} \cdot  _5 C_2 = 0.2110612637・・・・・
「シールドゾーンに3枚シールドトリガーが埋まっている」確率 p_3 p_3= \frac{8}{40}  \cdot \frac{7}{39}  \cdot \frac{6}{38} \cdot \frac{32}{37} \cdot \frac{31}{36} \cdot  _5 C_3 = 0.0422122527385・・・・・
「シールドゾーンに4枚シールドトリガーが埋まっている」確率 p_4 p_4= \frac{8}{40}  \cdot \frac{7}{39}  \cdot \frac{6}{38} \cdot \frac{5}{37} \cdot \frac{32}{36} \cdot  _5 C_4 = 0.0034042139305・・・・・
「シールドゾーンに5枚シールドトリガーが埋まっている」確率 p_5 p_5= \frac{8}{40}  \cdot \frac{7}{39}  \cdot \frac{6}{38} \cdot \frac{5}{37} \cdot \frac{4}{36} \cdot  _5 C_5 = 0.0000851053482・・・・・・


今回の例では求める期待値は
 E(x) = 1 \cdot p_1 +2 \cdot p_2+3 \cdot p_3 +4 \cdot p_4+5 \cdot p_5 =  1.0・・・ つまり、シールド・トリガーをデッキに8枚入れているとき、「シールドゾーン5枚の中にシールド・トリガーが埋まっている」期待値は 1枚と計算できます。以上よりデッキに8枚シールド・トリガーを積めば、シールド・ゾーンにシールド・トリガーが1枚入っていることが期待されます。

ちなみに前述してますが、ここまでの議論で、シールドゾーン5枚の中にシールド・トリガーが埋まっている期待値は
 E(x) = 1 \cdot p_1 +2 \cdot p_2+3 \cdot p_3 +4 \cdot p_4+5 \cdot p_5と一般化できます。( p_1, p_2,p_3,p_4,p_5は、シールドゾーンに同時にシールドトリガーがそれぞれ1, 2, 3, 4, 5枚埋まっている確率。)

後編へつづく

ここまでは期待値とは何か、そしてその計算について、かなり丁寧、詳細にみてきました。
後編では本当に実際のデュエル・マスターズ の試合で理論値(計算した期待値)が有効なのか、プログラムの力を借りて検証、証明してみます。

CS 1回戦で相手のデッキを事故らせるシャッフル論 


f:id:kuWaan:20181126194954j:plain

結論だけ知りたい人は下記から飛んでください。

問題提起

CSの対戦では一般的に, 自分のデッキを相手にシャッフルしてもらう。逆に, 相手のデッキは自分がシャッフルをする。このとき, 相手のデッキを事故らせる(同一カードの偏りが大きい)シャッフルの組み合わせはあるだろうか ?
また, あれば, どのような組み合わせか ? Pythonプログラムを利用して検証する。

初期条件

・デッキの中身は同名カードが4枚ずつ10組みで40枚とする。いわゆる, 4×10構築とする。
また, カードを A, B, C ,D, E, F, G, H, I Jで表す。

・相手は同名カードを並べた状態で, ディールシャッフルを1回, ヒンドゥーシャッフルを2回したとする。

シャッフルについて

今回は, ヒンドゥーシャッフル, ディールシャッフル, ファローシャッフルの組み合わせを考える。つまり3通りある。
例えば , 3回シャッフルを上記から選択するとすると, \begin{eqnarray*}
&& 3^3 = 27 \\
\end{eqnarray*}
通りある。

デッキの事故率 カードの偏りについて

・デッキの事故率は同名カードがどれくらい偏っているかで判断する。
・デッキのカードの並びを, 同名カードにおけるそれぞれの文字列の平均の和で評価し, 値を与えるとする。
・評価値は大きいほどがデッキがよく混ざっていて, 小さいほど事故が発生しているとみなす。

プログラム実行結果

簡単化のために, hをヒンドゥーシャッフル, dをディールシャッフル, fをファローシャッフルとする。
例えば, 'dhh'だったら, ディールシャッフルを1回した後に, ヒンドゥーシャッフルを2回したことを表す。


2回シャッフルするとき

シャッフル: 評価値
{'dhh': 40.0, 'dhhh': 40.0, 'dhhd': 84.66666666666667, 'dhhf': 90.0, 'dhhhh': 40.0, 'dhhhd': 84.66666666666667, 'dhhhf': 90.0, 'dhhdh': 86.66666666666667, 'dhhdd': 84.0, 'dhhdf': 90.00000000000001, 'dhhfh': 90.0, 'dhhfd': 90.00000000000001, 'dhhff': 60.0}

最も事故るシャッフル:評価値
[('dhh', 40.0), ('dhhh', 40.0), ('dhhhh', 40.0)]
最も混ざるシャッフル:評価値
[('dhhdf', 90.00000000000001), ('dhhfd', 90.00000000000001)]

3回シャッフルするとき

シャッフル: 評価値
{'dhh': 40.0, 'dhhh': 40.0, 'dhhd': 84.66666666666667, 'dhhf': 90.0, 'dhhhh': 40.0, 'dhhhd': 84.66666666666667, 'dhhhf': 90.0, 'dhhdh': 86.66666666666667, 'dhhdd': 84.0, 'dhhdf': 90.00000000000001, 'dhhfh': 90.0, 'dhhfd': 90.00000000000001, 'dhhff': 60.0, 'dhhhhh': 40.0, 'dhhhhd': 84.66666666666667, 'dhhhhf': 90.0, 'dhhhdh': 86.66666666666667, 'dhhhdd': 84.0, 'dhhhdf': 90.00000000000001, 'dhhhfh': 90.00000000000001, 'dhhhfd': 90.00000000000001, 'dhhhff': 60.0, 'dhhdhh': 83.0, 'dhhdhd': 81.66666666666666, 'dhhdhf': 77.33333333333334, 'dhhddh': 84.33333333333333, 'dhhddd': 0.0, 'dhhddf': 83.33333333333333, 'dhhdfh': 90.00000000000001, 'dhhdfd': 83.33333333333333, 'dhhdff': 73.33333333333334, 'dhhfhh': 90.0, 'dhhfhd': 77.66666666666666, 'dhhfhf': 75.0, 'dhhfdh': 90.00000000000001, 'dhhfdd': 83.33333333333333, 'dhhfdf': 73.33333333333334, 'dhhffh': 61.333333333333336, 'dhhffd': 73.33333333333334, 'dhhfff': 0.0}

最も事故るシャッフル:評価値
[('dhhddd', 0.0), ('dhhfff', 0.0)]

最も混ざるシャッフル:評価値
[('dhhdf', 90.00000000000001), ('dhhfd', 90.00000000000001), ('dhhhdf', 90.00000000000001), ('dhhhfh', 90.00000000000001), ('dhhhfd', 90.00000000000001), ('dhhdfh', 90.00000000000001), ('dhhfdh', 90.00000000000001)]

4回シャッフルするとき

シャッフル: 評価値
{'dhh': 40.0, 'dhhh': 40.0, 'dhhd': 84.66666666666667, 'dhhf': 90.0, 'dhhhh': 40.0, 'dhhhd': 84.66666666666667, 'dhhhf': 90.0, 'dhhdh': 86.66666666666667, 'dhhdd': 84.0, 'dhhdf': 90.00000000000001, 'dhhfh': 90.0, 'dhhfd': 90.00000000000001, 'dhhff': 60.0, 'dhhhhh': 40.0, 'dhhhhd': 84.66666666666667, 'dhhhhf': 90.0, 'dhhhdh': 86.66666666666667, 'dhhhdd': 84.0, 'dhhhdf': 90.00000000000001, 'dhhhfh': 90.00000000000001, 'dhhhfd': 90.00000000000001, 'dhhhff': 60.0, 'dhhdhh': 83.0, 'dhhdhd': 81.66666666666666, 'dhhdhf': 77.33333333333334, 'dhhddh': 84.33333333333333, 'dhhddd': 0.0, 'dhhddf': 83.33333333333333, 'dhhdfh': 90.00000000000001, 'dhhdfd': 83.33333333333333, 'dhhdff': 73.33333333333334, 'dhhfhh': 90.0, 'dhhfhd': 77.66666666666666, 'dhhfhf': 75.0, 'dhhfdh': 90.00000000000001, 'dhhfdd': 83.33333333333333, 'dhhfdf': 73.33333333333334, 'dhhffh': 61.333333333333336, 'dhhffd': 73.33333333333334, 'dhhfff': 0.0, 'dhhhhhh': 40.0, 'dhhhhhd': 84.66666666666667, 'dhhhhhf': 90.0, 'dhhhhdh': 86.66666666666667, 'dhhhhdd': 84.0, 'dhhhhdf': 90.00000000000001, 'dhhhhfh': 90.0, 'dhhhhfd': 90.00000000000001, 'dhhhhff': 60.0, 'dhhhdhh': 83.0, 'dhhhdhd': 81.66666666666666, 'dhhhdhf': 77.33333333333334, 'dhhhddh': 84.33333333333333, 'dhhhddd': 0.0, 'dhhhddf': 83.33333333333333, 'dhhhdfh': 90.0, 'dhhhdfd': 83.33333333333333, 'dhhhdff': 73.33333333333334, 'dhhhfhh': 90.00000000000001, 'dhhhfhd': 77.66666666666666, 'dhhhfhf': 75.0, 'dhhhfdh': 90.0, 'dhhhfdd': 83.33333333333333, 'dhhhfdf': 73.33333333333334, 'dhhhffh': 61.33333333333333, 'dhhhffd': 73.33333333333334, 'dhhhfff': 0.0, 'dhhdhhh': 86.66666666666667, 'dhhdhhd': 83.33333333333333, 'dhhdhhf': 90.0, 'dhhdhdh': 74.66666666666667, 'dhhdhdd': 44.333333333333336, 'dhhdhdf': 72.66666666666667, 'dhhdhfh': 72.0, 'dhhdhfd': 72.66666666666667, 'dhhdhff': 66.66666666666667, 'dhhddhh': 85.33333333333333, 'dhhddhd': 48.0, 'dhhddhf': 85.0, 'dhhdddh': 5.666666666666666, 'dhhdddd': 40.0, 'dhhdddf': 10.0, 'dhhddfh': 84.0, 'dhhddfd': 10.0, 'dhhddff': 82.0, 'dhhdfhh': 90.00000000000001, 'dhhdfhd': 79.66666666666667, 'dhhdfhf': 77.66666666666666, 'dhhdfdh': 84.0, 'dhhdfdd': 10.0, 'dhhdfdf': 82.0, 'dhhdffh': 73.33333333333334, 'dhhdffd': 82.0, 'dhhdfff': 40.0, 'dhhfhhh': 90.0, 'dhhfhhd': 82.66666666666666, 'dhhfhhf': 60.00000000000001, 'dhhfhdh': 80.0, 'dhhfhdd': 74.0, 'dhhfhdf': 80.00000000000001, 'dhhfhfh': 76.33333333333333, 'dhhfhfd': 80.00000000000001, 'dhhfhff': 59.999999999999986, 'dhhfdhh': 90.00000000000001, 'dhhfdhd': 79.66666666666667, 'dhhfdhf': 77.66666666666666, 'dhhfddh': 84.0, 'dhhfddd': 10.0, 'dhhfddf': 82.0, 'dhhfdfh': 73.33333333333334, 'dhhfdfd': 82.0, 'dhhfdff': 40.0, 'dhhffhh': 62.666666666666664, 'dhhffhd': 60.33333333333333, 'dhhffhf': 66.0, 'dhhffdh': 73.33333333333334, 'dhhffdd': 82.0, 'dhhffdf': 40.0, 'dhhfffh': 5.666666666666666, 'dhhfffd': 40.0, 'dhhffff': 10.0}

最も事故るシャッフル:評価値
[('dhhddd', 0.0), ('dhhfff', 0.0), ('dhhhddd', 0.0), ('dhhhfff', 0.0)]

最も混ざるシャッフル:評価値
[('dhhdf', 90.00000000000001), ('dhhfd', 90.00000000000001), ('dhhhdf', 90.00000000000001), ('dhhhfh', 90.00000000000001), ('dhhhfd', 90.00000000000001), ('dhhdfh', 90.00000000000001), ('dhhfdh', 90.00000000000001), ('dhhhhdf', 90.00000000000001), ('dhhhhfd', 90.00000000000001), ('dhhhfhh', 90.00000000000001), ('dhhdfhh', 90.00000000000001), ('dhhfdhh', 90.00000000000001)]

5回シャッフルするとき

シャッフル: 評価値
{'dhh': 40.0, 'dhhh': 40.0, 'dhhd': 84.66666666666667, 'dhhf': 90.0, 'dhhhh': 40.0, 'dhhhd': 84.66666666666667, 'dhhhf': 90.0, 'dhhdh': 86.66666666666667, 'dhhdd': 84.0, 'dhhdf': 90.00000000000001, 'dhhfh': 90.0, 'dhhfd': 90.00000000000001, 'dhhff': 60.0, 'dhhhhh': 40.0, 'dhhhhd': 84.66666666666667, 'dhhhhf': 90.0, 'dhhhdh': 86.66666666666667, 'dhhhdd': 84.0, 'dhhhdf': 90.00000000000001, 'dhhhfh': 90.00000000000001, 'dhhhfd': 90.00000000000001, 'dhhhff': 60.0, 'dhhdhh': 83.0, 'dhhdhd': 81.66666666666666, 'dhhdhf': 77.33333333333334, 'dhhddh': 84.33333333333333, 'dhhddd': 0.0, 'dhhddf': 83.33333333333333, 'dhhdfh': 90.00000000000001, 'dhhdfd': 83.33333333333333, 'dhhdff': 73.33333333333334, 'dhhfhh': 90.0, 'dhhfhd': 77.66666666666666, 'dhhfhf': 75.0, 'dhhfdh': 90.00000000000001, 'dhhfdd': 83.33333333333333, 'dhhfdf': 73.33333333333334, 'dhhffh': 61.333333333333336, 'dhhffd': 73.33333333333334, 'dhhfff': 0.0, 'dhhhhhh': 40.0, 'dhhhhhd': 84.66666666666667, 'dhhhhhf': 90.0, 'dhhhhdh': 86.66666666666667, 'dhhhhdd': 84.0, 'dhhhhdf': 90.00000000000001, 'dhhhhfh': 90.0, 'dhhhhfd': 90.00000000000001, 'dhhhhff': 60.0, 'dhhhdhh': 83.0, 'dhhhdhd': 81.66666666666666, 'dhhhdhf': 77.33333333333334, 'dhhhddh': 84.33333333333333, 'dhhhddd': 0.0, 'dhhhddf': 83.33333333333333, 'dhhhdfh': 90.0, 'dhhhdfd': 83.33333333333333, 'dhhhdff': 73.33333333333334, 'dhhhfhh': 90.00000000000001, 'dhhhfhd': 77.66666666666666, 'dhhhfhf': 75.0, 'dhhhfdh': 90.0, 'dhhhfdd': 83.33333333333333, 'dhhhfdf': 73.33333333333334, 'dhhhffh': 61.33333333333333, 'dhhhffd': 73.33333333333334, 'dhhhfff': 0.0, 'dhhdhhh': 86.66666666666667, 'dhhdhhd': 83.33333333333333, 'dhhdhhf': 90.0, 'dhhdhdh': 74.66666666666667, 'dhhdhdd': 44.333333333333336, 'dhhdhdf': 72.66666666666667, 'dhhdhfh': 72.0, 'dhhdhfd': 72.66666666666667, 'dhhdhff': 66.66666666666667, 'dhhddhh': 85.33333333333333, 'dhhddhd': 48.0, 'dhhddhf': 85.0, 'dhhdddh': 5.666666666666666, 'dhhdddd': 40.0, 'dhhdddf': 10.0, 'dhhddfh': 84.0, 'dhhddfd': 10.0, 'dhhddff': 82.0, 'dhhdfhh': 90.00000000000001, 'dhhdfhd': 79.66666666666667, 'dhhdfhf': 77.66666666666666, 'dhhdfdh': 84.0, 'dhhdfdd': 10.0, 'dhhdfdf': 82.0, 'dhhdffh': 73.33333333333334, 'dhhdffd': 82.0, 'dhhdfff': 40.0, 'dhhfhhh': 90.0, 'dhhfhhd': 82.66666666666666, 'dhhfhhf': 60.00000000000001, 'dhhfhdh': 80.0, 'dhhfhdd': 74.0, 'dhhfhdf': 80.00000000000001, 'dhhfhfh': 76.33333333333333, 'dhhfhfd': 80.00000000000001, 'dhhfhff': 59.999999999999986, 'dhhfdhh': 90.00000000000001, 'dhhfdhd': 79.66666666666667, 'dhhfdhf': 77.66666666666666, 'dhhfddh': 84.0, 'dhhfddd': 10.0, 'dhhfddf': 82.0, 'dhhfdfh': 73.33333333333334, 'dhhfdfd': 82.0, 'dhhfdff': 40.0, 'dhhffhh': 62.666666666666664, 'dhhffhd': 60.33333333333333, 'dhhffhf': 66.0, 'dhhffdh': 73.33333333333334, 'dhhffdd': 82.0, 'dhhffdf': 40.0, 'dhhfffh': 5.666666666666666, 'dhhfffd': 40.0, 'dhhffff': 10.0, 'dhhhhhhh': 40.0, 'dhhhhhhd': 84.66666666666667, 'dhhhhhhf': 90.0, 'dhhhhhdh': 86.66666666666667, 'dhhhhhdd': 84.0, 'dhhhhhdf': 90.00000000000001, 'dhhhhhfh': 90.00000000000001, 'dhhhhhfd': 90.00000000000001, 'dhhhhhff': 60.0, 'dhhhhdhh': 83.0, 'dhhhhdhd': 81.66666666666666, 'dhhhhdhf': 77.33333333333334, 'dhhhhddh': 84.33333333333333, 'dhhhhddd': 0.0, 'dhhhhddf': 83.33333333333333, 'dhhhhdfh': 90.00000000000001, 'dhhhhdfd': 83.33333333333333, 'dhhhhdff': 73.33333333333334, 'dhhhhfhh': 90.0, 'dhhhhfhd': 77.66666666666666, 'dhhhhfhf': 75.0, 'dhhhhfdh': 90.00000000000001, 'dhhhhfdd': 83.33333333333333, 'dhhhhfdf': 73.33333333333334, 'dhhhhffh': 61.333333333333336, 'dhhhhffd': 73.33333333333334, 'dhhhhfff': 0.0, 'dhhhdhhh': 86.66666666666667, 'dhhhdhhd': 83.33333333333333, 'dhhhdhhf': 90.0, 'dhhhdhdh': 74.66666666666667, 'dhhhdhdd': 44.333333333333336, 'dhhhdhdf': 72.66666666666666, 'dhhhdhfh': 72.0, 'dhhhdhfd': 72.66666666666666, 'dhhhdhff': 66.66666666666667, 'dhhhddhh': 85.33333333333333, 'dhhhddhd': 48.0, 'dhhhddhf': 85.0, 'dhhhdddh': 5.666666666666666, 'dhhhdddd': 40.0, 'dhhhdddf': 10.0, 'dhhhddfh': 84.0, 'dhhhddfd': 10.0, 'dhhhddff': 82.0, 'dhhhdfhh': 90.00000000000001, 'dhhhdfhd': 79.66666666666669, 'dhhhdfhf': 77.66666666666667, 'dhhhdfdh': 84.0, 'dhhhdfdd': 10.0, 'dhhhdfdf': 82.0, 'dhhhdffh': 73.33333333333333, 'dhhhdffd': 82.0, 'dhhhdfff': 40.0, 'dhhhfhhh': 90.00000000000001, 'dhhhfhhd': 82.66666666666667, 'dhhhfhhf': 60.00000000000001, 'dhhhfhdh': 80.00000000000001, 'dhhhfhdd': 74.0, 'dhhhfhdf': 80.00000000000001, 'dhhhfhfh': 76.33333333333333, 'dhhhfhfd': 80.00000000000001, 'dhhhfhff': 59.99999999999999, 'dhhhfdhh': 90.00000000000001, 'dhhhfdhd': 79.66666666666669, 'dhhhfdhf': 77.66666666666667, 'dhhhfddh': 84.0, 'dhhhfddd': 10.0, 'dhhhfddf': 82.0, 'dhhhfdfh': 73.33333333333333, 'dhhhfdfd': 82.0, 'dhhhfdff': 40.0, 'dhhhffhh': 62.666666666666664, 'dhhhffhd': 60.333333333333336, 'dhhhffhf': 66.0, 'dhhhffdh': 73.33333333333333, 'dhhhffdd': 82.0, 'dhhhffdf': 40.0, 'dhhhfffh': 5.666666666666666, 'dhhhfffd': 40.0, 'dhhhffff': 10.0, 'dhhdhhhh': 82.66666666666669, 'dhhdhhhd': 87.33333333333333, 'dhhdhhhf': 71.99999999999999, 'dhhdhhdh': 83.66666666666667, 'dhhdhhdd': 60.66666666666667, 'dhhdhhdf': 74.0, 'dhhdhhfh': 90.00000000000001, 'dhhdhhfd': 74.0, 'dhhdhhff': 69.33333333333334, 'dhhdhdhh': 76.00000000000001, 'dhhdhdhd': 66.0, 'dhhdhdhf': 76.99999999999999, 'dhhdhddh': 51.66666666666668, 'dhhdhddd': 47.99999999999999, 'dhhdhddf': 66.33333333333333, 'dhhdhdfh': 74.0, 'dhhdhdfd': 66.33333333333333, 'dhhdhdff': 85.33333333333334, 'dhhdhfhh': 72.0, 'dhhdhfhd': 43.0, 'dhhdhfhf': 75.33333333333334, 'dhhdhfdh': 74.0, 'dhhdhfdd': 66.33333333333333, 'dhhdhfdf': 85.33333333333334, 'dhhdhffh': 67.66666666666666, 'dhhdhffd': 85.33333333333334, 'dhhdhfff': 47.99999999999999, 'dhhddhhh': 81.0, 'dhhddhhd': 46.66666666666667, 'dhhddhhf': 86.0, 'dhhddhdh': 51.00000000000001, 'dhhddhdd': 65.33333333333334, 'dhhddhdf': 76.33333333333333, 'dhhddhfh': 81.66666666666667, 'dhhddhfd': 76.33333333333333, 'dhhddhff': 78.33333333333334, 'dhhdddhh': 11.333333333333332, 'dhhdddhd': 54.0, 'dhhdddhf': 21.333333333333336, 'dhhddddh': 40.0, 'dhhddddd': 84.66666666666667, 'dhhddddf': 90.0, 'dhhdddfh': 30.66666666666667, 'dhhdddfd': 90.0, 'dhhdddff': 45.33333333333333, 'dhhddfhh': 85.66666666666664, 'dhhddfhd': 58.0, 'dhhddfhf': 86.33333333333333, 'dhhddfdh': 30.66666666666667, 'dhhddfdd': 90.0, 'dhhddfdf': 45.33333333333333, 'dhhddffh': 84.0, 'dhhddffd': 45.33333333333333, 'dhhddfff': 84.66666666666667, 'dhhdfhhh': 90.0, 'dhhdfhhd': 77.33333333333333, 'dhhdfhhf': 73.33333333333334, 'dhhdfhdh': 69.0, 'dhhdfhdd': 56.0, 'dhhdfhdf': 71.33333333333333, 'dhhdfhfh': 76.33333333333334, 'dhhdfhfd': 71.33333333333333, 'dhhdfhff': 74.66666666666667, 'dhhdfdhh': 85.66666666666664, 'dhhdfdhd': 58.0, 'dhhdfdhf': 86.33333333333333, 'dhhdfddh': 30.66666666666667, 'dhhdfddd': 90.0, 'dhhdfddf': 45.33333333333333, 'dhhdfdfh': 84.0, 'dhhdfdfd': 45.33333333333333, 'dhhdfdff': 84.66666666666667, 'dhhdffhh': 73.33333333333334, 'dhhdffhd': 74.0, 'dhhdffhf': 90.0, 'dhhdffdh': 84.0, 'dhhdffdd': 45.33333333333333, 'dhhdffdf': 84.66666666666667, 'dhhdfffh': 40.0, 'dhhdfffd': 84.66666666666667, 'dhhdffff': 90.0, 'dhhfhhhh': 90.0, 'dhhfhhhd': 77.66666666666669, 'dhhfhhhf': 75.0, 'dhhfhhdh': 82.0, 'dhhfhhdd': 72.66666666666667, 'dhhfhhdf': 58.66666666666665, 'dhhfhhfh': 61.333333333333336, 'dhhfhhfd': 58.66666666666665, 'dhhfhhff': 63.33333333333332, 'dhhfhdhh': 80.66666666666666, 'dhhfhdhd': 75.0, 'dhhfhdhf': 70.0, 'dhhfhddh': 76.66666666666667, 'dhhfhddd': 10.0, 'dhhfhddf': 71.66666666666666, 'dhhfhdfh': 80.33333333333333, 'dhhfhdfd': 71.66666666666666, 'dhhfhdff': 73.33333333333333, 'dhhfhfhh': 76.33333333333334, 'dhhfhfhd': 71.33333333333334, 'dhhfhfhf': 68.66666666666667, 'dhhfhfdh': 80.33333333333333, 'dhhfhfdd': 71.66666666666666, 'dhhfhfdf': 73.33333333333333, 'dhhfhffh': 60.666666666666664, 'dhhfhffd': 73.33333333333333, 'dhhfhfff': 10.0, 'dhhfdhhh': 90.0, 'dhhfdhhd': 77.33333333333333, 'dhhfdhhf': 73.33333333333334, 'dhhfdhdh': 69.0, 'dhhfdhdd': 56.0, 'dhhfdhdf': 71.33333333333333, 'dhhfdhfh': 76.33333333333334, 'dhhfdhfd': 71.33333333333333, 'dhhfdhff': 74.66666666666667, 'dhhfddhh': 85.66666666666664, 'dhhfddhd': 58.0, 'dhhfddhf': 86.33333333333333, 'dhhfdddh': 30.66666666666667, 'dhhfdddd': 90.0, 'dhhfdddf': 45.33333333333333, 'dhhfddfh': 84.0, 'dhhfddfd': 45.33333333333333, 'dhhfddff': 84.66666666666667, 'dhhfdfhh': 73.33333333333334, 'dhhfdfhd': 74.0, 'dhhfdfhf': 90.0, 'dhhfdfdh': 84.0, 'dhhfdfdd': 45.33333333333333, 'dhhfdfdf': 84.66666666666667, 'dhhfdffh': 40.0, 'dhhfdffd': 84.66666666666667, 'dhhfdfff': 90.0, 'dhhffhhh': 63.99999999999999, 'dhhffhhd': 80.0, 'dhhffhhf': 5.333333333333333, 'dhhffhdh': 60.66666666666667, 'dhhffhdd': 79.66666666666666, 'dhhffhdf': 85.66666666666667, 'dhhffhfh': 70.66666666666667, 'dhhffhfd': 85.66666666666667, 'dhhffhff': 42.33333333333333, 'dhhffdhh': 73.33333333333334, 'dhhffdhd': 74.0, 'dhhffdhf': 90.0, 'dhhffddh': 84.0, 'dhhffddd': 45.33333333333333, 'dhhffddf': 84.66666666666667, 'dhhffdfh': 40.0, 'dhhffdfd': 84.66666666666667, 'dhhffdff': 90.0, 'dhhfffhh': 11.333333333333332, 'dhhfffhd': 54.0, 'dhhfffhf': 21.333333333333336, 'dhhfffdh': 40.0, 'dhhfffdd': 84.66666666666667, 'dhhfffdf': 90.0, 'dhhffffh': 30.66666666666667, 'dhhffffd': 90.0, 'dhhfffff': 45.33333333333333}

最も事故るシャッフル:評価値
[('dhhddd', 0.0), ('dhhfff', 0.0), ('dhhhddd', 0.0), ('dhhhfff', 0.0), ('dhhhhddd', 0.0), ('dhhhhfff', 0.0)]

最も混ざるシャッフル:評価値
[('dhhdf', 90.00000000000001), ('dhhfd', 90.00000000000001), ('dhhhdf', 90.00000000000001), ('dhhhfh', 90.00000000000001), ('dhhhfd', 90.00000000000001), ('dhhdfh', 90.00000000000001), ('dhhfdh', 90.00000000000001), ('dhhhhdf', 90.00000000000001), ('dhhhhfd', 90.00000000000001), ('dhhhfhh', 90.00000000000001), ('dhhdfhh', 90.00000000000001), ('dhhfdhh', 90.00000000000001), ('dhhhhhdf', 90.00000000000001), ('dhhhhhfh', 90.00000000000001), ('dhhhhhfd', 90.00000000000001), ('dhhhhdfh', 90.00000000000001), ('dhhhhfdh', 90.00000000000001), ('dhhhdfhh', 90.00000000000001), ('dhhhfhhh', 90.00000000000001), ('dhhhfdhh', 90.00000000000001), ('dhhdhhfh', 90.00000000000001)]

6回シャッフルするとき

シャッフル: 評価値
(とても長いので省略)

最も事故るシャッフル:評価値
[('dhhddd', 0.0), ('dhhfff', 0.0), ('dhhhddd', 0.0), ('dhhhfff', 0.0), ('dhhhhddd', 0.0), ('dhhhhfff', 0.0), ('dhhhhhddd', 0.0), ('dhhhhhfff', 0.0)]

最も混ざるシャッフル:評価値
[('dhhdf', 90.00000000000001), ('dhhfd', 90.00000000000001), ('dhhhdf', 90.00000000000001), ('dhhhfh', 90.00000000000001), ('dhhhfd', 90.00000000000001), ('dhhdfh', 90.00000000000001), ('dhhfdh', 90.00000000000001), ('dhhhhdf', 90.00000000000001), ('dhhhhfd', 90.00000000000001), ('dhhhfhh', 90.00000000000001), ('dhhdfhh', 90.00000000000001), ('dhhfdhh', 90.00000000000001), ('dhhhhhdf', 90.00000000000001), ('dhhhhhfh', 90.00000000000001), ('dhhhhhfd', 90.00000000000001), ('dhhhhdfh', 90.00000000000001), ('dhhhhfdh', 90.00000000000001), ('dhhhdfhh', 90.00000000000001), ('dhhhfhhh', 90.00000000000001), ('dhhhfdhh', 90.00000000000001), ('dhhdhhfh', 90.00000000000001), ('dhhhhhhdf', 90.00000000000001), ('dhhhhhhfd', 90.00000000000001), ('dhhhhhfhh', 90.00000000000001), ('dhhhhdfhh', 90.00000000000001), ('dhhhhfdhh', 90.00000000000001), ('dhhhdhhfh', 90.00000000000001), ('dhhhdfhhh', 90.00000000000001), ('dhhhfdhhh', 90.00000000000001), ('dhhdddddf', 90.00000000000001), ('dhhddddfd', 90.00000000000001), ('dhhdddfdd', 90.00000000000001), ('dhhddfddd', 90.00000000000001), ('dhhddffff', 90.00000000000001), ('dhhdfhhhh', 90.00000000000001), ('dhhdfdddd', 90.00000000000001), ('dhhdfdfff', 90.00000000000001), ('dhhdffhfh', 90.00000000000001), ('dhhdffdff', 90.00000000000001), ('dhhdfffdf', 90.00000000000001), ('dhhdffffd', 90.00000000000001), ('dhhfdhhhh', 90.00000000000001), ('dhhfddddd', 90.00000000000001), ('dhhfddfff', 90.00000000000001), ('dhhfdfhfh', 90.00000000000001), ('dhhfdfdff', 90.00000000000001), ('dhhfdffdf', 90.00000000000001), ('dhhfdfffd', 90.00000000000001), ('dhhffdhfh', 90.00000000000001), ('dhhffddff', 90.00000000000001), ('dhhffdfdf', 90.00000000000001), ('dhhffdffd', 90.00000000000001), ('dhhfffddf', 90.00000000000001), ('dhhfffdfd', 90.00000000000001), ('dhhffffdd', 90.00000000000001)]

結論

2回シャッフルするのであれば, 事故らせるシャッフルは


a. シャッフルせず返す。
b. ヒンドゥーシャッフルを1回する。
c. ヒンドゥーシャッフルを2回する。

3回以上シャッフルするのであれば,事故らせるシャッフルは

a. ディールシャッフルを3回する。
b. ファローシャッフルを3回する。
c. ヒンドゥーシャッフルを1回してから、ディールシャッフルを3回する。
d. ヒンドゥーシャッフルを1回してから、ファローシャッフルを3回する。
e. ヒンドゥーシャッフルを2回してから、ディールシャッフルを3回する。
f. ヒンドゥーシャッフルを2回してから、ファローシャッフルを3回する。
g. ヒンドゥーシャッフルを3回してから、ディールシャッフルを3回する。
h. ヒンドゥーシャッフルを3回してから、ファローシャッフルを3回する。
               ~
つまり

ヒンドゥーシャッフルをn回してから、ディールシャッフルを3回する。
または
ヒンドゥーシャッフルをn回してから、ファローシャッフルを3回する。
(nは0以上の整数)

評価値が0というのは, つまり同名カードが全て連続している状態ということである。

考察

プログラムの仕様と初期条件の影響でファローorディールを3回すると同名カードが並ぶ状態になると考えられる。
あくまでも机上の空論のため, 実際のCSの現場では使えないと考えられる。正直, 実際の相手が初期条件を満たすとは考えられない。

一方, 混ざりやすいシャッフルをみると, 3種のシャッフルをよく組み合わせている傾向がある。
また, シャッフルの回数を増やすごとに, 事故らせるシャッフルに比べて, より多い組み合わせが現れている。
つまり, デッキを混ぜたければ, 色々なシャッフルをできるだけ多く組み合わせるべきということだ。