6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Python で高校数学 シャドウバース2pick 勝率何%で無限に遊べるか?

Last updated at Posted at 2025-12-05

 こんにちは。くろこんです。今回はオンラインカードゲーム、シャドウバース・ビヨンドの2pickの報酬の分析です。高校数学の範囲で分かる内容となっています。

 計算には Python を使っていきます。

2pick とは

 いわゆるリミテッドと呼ばれるカードゲームのフォーマットです。ランダムにカードを取得して、そこからデッキを作り遊びます。

 このタイプのフォーマットでは、大体報酬が用意されているのが通例で、その量は勝利数に応じます。この勝利数を勝率へ変換した場合にどうなるのか、という問題です。

 シャドウバース・ビヨンドでは2敗する、または7勝するまで対戦が可能です。

 勝利数に応じた報酬は以下のようになります。

def gem():
    return [100, 300, 500, 700, 850, 1000, 1250, 1500]

 (シャドウバースのお金の単位はルピですが、単位無しで扱っていきます)

 0勝だと100で、7勝だと1500ということです。他にもカードパックがもらえたりしますが、今回は無限に遊ぶための条件ということで、お金の報酬だけを計算します。

確率の計算

 まず、場合分けを考えます。一番単純な、勝利数での場合分けをします。勝率を$p$として計算していきます。

0勝の場合

 勝率 $p$ ということは、敗率は $1-p$ です。0回勝つ確率を $q_0$ とすると、

q_0 = (1-p)^2

 となります。

1勝の場合

 2敗するまで、なので、2試合目までが1勝1敗で、3試合目が負け、となります。

q_1= \ _2 C_1 p(1-p)\ \  (1-p) = 2p(1-p)^2

2勝の場合

 2敗するまで、なので、3試合目までが2勝1敗で、4試合目が負け、となります。

q_2= \ _3 C_1 p^2(1-p)\ \  (1-p) = 3p^2(1-p)^2

0~6勝の場合

 6勝までは、最後の試合が負け、という同じ性質を持つので、一般化して表しましょう。

q_n= \ _{n+1} C_1 p^n(1-p)\ \  (1-p) = (n+1)p^n(1-p)^2

7勝の場合

 7連勝する場合と、1敗して最後に勝つ場合の2通りがあります。

q_7= p^7 + \ _7 C_1 p^6(1-p)\ \ p = p^7 (8-7p)

 もしくは、$\sum^6_{n=0} q_n$ を計算して 1 から引いてもよいです。

\sum^6_{n=0}q_n = (1-p)^2 (1+2p+3p^2+4p^3+5p^4+6p^5+7p^6)
\ \ \ \ \ \ \ \ = (1-p) (1+p+p^2+p^3+p^4+p^5+p^6-7p^7)
= 1-p^7 -7p^7+7p^8 = 1 - p^7 (8 - 7p) \ \ \ \ \ \ \ 

Python で期待値の計算

 先ほど計算した確率を使って、期待値を計算していきます。

def calc(p):
    g = gem()
    
    pm1 = 1-p
    pp = 1
    exg = 0
    
    for w in range(7):
        q = pp * pm1 * pm1 * (w + 1)
        pp = pp * p
        exg = exg + q * g[w]
        
    exg = exg + pp * (8 - 7 * p) * g[7]
    
    return exg

 プログラム中の pp は、$p^n$ を使いまわすために計算しています。

 これで、$p$ の値をしらみつぶしに探していくと、無限に遊べる勝率がわかります。今のところ 2pick のプレイ料金は 1000 なので、勝率 75.7 %で報酬期待値が 1000.0656733244928 になります。

検算

 プログラミングの世界では、計算したから終了、というのは非常に危険な行為です。何かしらの検算がおすすめです。

 今回は勝敗を乱数で生成したシミュレーションで確認します。

def sim(p,itr):
    g = gem()
    
    v = 0 #報酬累計
    c = 0 #入場数
    
    w = 0 #勝利数
    l = 0 #敗北数
    
    for i in range(itr):
        x = random.random()
        if x < p:
            w = w + 1
        else:
            l = l + 1
            
        if l == 2 or w == 7:
            v = v + g[w]
            w = 0
            l = 0
            c = c + 1
            
    print(v / c, v, c, itr)
1001.3594341453945 165072100 164848 1000000

 勝率 75.7 %で 1000000 試合すると、164848 入場で報酬が 165072100 になって、平均はほぼ 1000 となりました。(ランダムなので毎回結果は変わります)

おまけ python での勝率探索結果

# この数値や3桁以上の近似値などを載せる場合は、この記事の URL などを併記してください
0.7569747594467667

おまけ 2pick は得か損か

 パック価格が 500 であることから、報酬を書き換えます。

def gem():
    return [600, 800, 1000, 1200, 1350, 1500, 1750, 2500]

 これで $p=0.5$ で計算します。

999.0234375

 ……微妙ですね。

おまけ 外部サイト様との比較

 計算の結果が載っているサイト様がありました。勝率 75 % のとき 981.9 は同じ結果になっています。

6
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?