下記の続きです。
simplestar-tech.hatenablog.com
ダメージ回数が2の場合のスプリットダメージについて、様々な盤面における
カードごとの撃破率をみていきます。
■問題1
場に2枚のカードがあり
すべてのカードのライフが1だった場合
★答え1
いずれのカードも撃破率は 1 です。
すべてのカードのライフ合計がダメージ回数以下の場合は無条件で 1 です。
■問題2
場に3枚のカードがあり
すべてのカードのライフが1だった場合
★答え2
いずれのカードも撃破率は 2/3 です。
前回調べた通り、ダメージ回数が1だった場合は撃破率 1/3 でした。
今回は 2/3 の確率で生き残った後、場のカード数が 3 から 2 に減った状態で
ダメージを与えられる確率は 1/2 です。
2/3 * 1/2 という割合で撃破されることが考えられます。
ダメージ回数が1のときに撃破される確率と
ダメージ回数が2のときに撃破される確率について
撃破率を出すため足し合わせます。
1/3 + 2/3 * 1/2 = 2/3
■問題3
場に2枚のカードがあり
一方のカードのライフが1の場合
一方のカードのライフが2の場合
★答え3
カードのライフが1のカードの撃破率は 3/4
カードのライフが2のカードの撃破率は 1/4
カードのライフが1のカードをAとします。
Aはダメージ回数1のときに1/2で撃破される可能性があることは前回示しました。
1/2の確率で生き残った後、場のカード数が2から変動しない状態で
ダメージを与えられる可能性は 1/2 です。
1/2 * 1/2 という割合で撃破されることが考えられます。
ダメージ回数が1のときに撃破される確率と
ダメージ回数が2のときに撃破される確率について
撃破率を出すため足し合わせます。
1/2 + 1/2 * 1/2 = 3/4
カードのライフが2のカードをBとします。
Bはダメージ回数1のときに 0 で撃破される可能性がないことは前回示しました。
1/2 でダメージ回数1のダメージを受けた後、場のカード数が2から変動しない状態で
1/2 でダメージ回数2のダメージを受けた場合にのみ撃破されます。
1/2 でダメージ回数1のダメージを受けなかった後、場のカード数が 2 から 1 に減った状態で
この時ダメージ回数よりもライフ数の方が大きいため無条件で撃破率は 0 です。
1/2 * 1/2 + 0という割合で撃破されることが考えられます。
ダメージ回数が1のときに撃破される確率と
ダメージ回数が2のときに撃破される確率について
撃破率を出すため足し合わせます。
0 + (1/2 * 1/2 + 0) = 1/4
■問題4
場に3枚のカードがあり
一枚目のカードのライフが1の場合
二枚目のカードのライフが2の場合
三枚目のカードのライフが2の場合
★答え4
一枚目のカードのライフが1のカードの撃破率は 5/9
ニ枚目のカードのライフが2のカードの撃破率は 1/9
三枚目のカードのライフが2のカードの撃破率は 1/9
カードのライフが1のカードをAとします。
Aはダメージ回数1のときに1/3で撃破される可能性があることは前回示しました。
2/3の確率で生き残った後、場のカード数が3から変動しない状態で
ダメージを与えられる可能性は 1/3 です。
2/3 * 1/3 という割合で撃破されることが考えられます。
ダメージ回数が1のときに撃破される確率と
ダメージ回数が2のときに撃破される確率について
撃破率を出すため足し合わせます。
1/3 + 2/3 * 1/3 = 5/9
カードのライフが2のカードをBとします。
Bはダメージ回数1のときに 0 で撃破される可能性がないことは前回示しました。
1/3 でダメージ回数1のダメージを受けた後、場のカード数が3から変動しない状態で
1/3 でダメージ回数2のダメージを受けた場合にのみ撃破されます。
2/3 でダメージ回数1のダメージを受けなかった後、
場のカード数が 3 から変動しない状態のになる確率が 1/2
場のカード数が 3 から 2 に減った状態のになる確率が 1/2
いずれの場合もダメージ回数よりもライフ数の方が大きいため無条件で撃破率は 0 です。
1/3 * 1/3 + 0という割合で撃破されることが考えられます。
ダメージ回数が1のときに撃破される確率と
ダメージ回数が2のときに撃破される確率について
撃破率を出すため足し合わせます。
0 + (1/3 * 1/3 + 0) = 1/9
■問題5
場に4枚のカードがあり
一枚目のカードのライフが1の場合
ニ枚目のカードのライフが1の場合
三枚目のカードのライフが2の場合
四枚目のカードのライフが2の場合
★答え4
一枚目のカードのライフが1のカードの撃破率は 11/24
ニ枚目のカードのライフが1のカードの撃破率は 11/24
三枚目のカードのライフが2のカードの撃破率は 1/16
四枚目のカードのライフが2のカードの撃破率は 1/16
カードのライフが1のカードをAとします。
Aはダメージ回数1のときに1/4で撃破される可能性があります。(前回求めた式より)
3/4の確率で生き残った後、
場のカード数が 4 から変動しない状態になる確率は 2/3 (A以外のカード数が3で、ライフ1より大きいカードが2枚あるので)
場のカード数が 4 から 3 に減った状態になる確率が 1/3(A以外のカード数が3で、ライフ1のカードが1枚あるので)
ダメージ回数2のダメージを受ける可能性はそれぞれのケースにおいて 1/4 と 1/3 です。
場のカード数が 4 になっている時にダメージ回数2の攻撃で撃破される確率と
場のカード数が 3 になっている時にダメージ回数2の攻撃で撃破される確率について
撃破率を出すため足し合わせます。
2/3 * 1/4 + 1/3 * 1/3 という割合で撃破されることが考えられます。
ダメージ回数が1のときに撃破される確率と
ダメージ回数が2のときに撃破される確率について
撃破率を出すため足し合わせます。
1/4 + 3/4 * (2/3 * 1/4 + 1/3 * 1/3) = 11/24
カードのライフが2のカードをBとします。
Bはダメージ回数1のときに 0 で撃破される可能性はない。(前回求めた式より)
1/4 でダメージ回数1のダメージを受けた後、場のカード数が4から変動しない状態で
1/4 でダメージ回数2のダメージを受けた場合にのみ撃破されます。
それ以外ではダメージ回数よりもライフ数の方が大きいため無条件で撃破率は 0 です。
撃破率を出すため足し合わせます。
0 + (1/4 * 1/4 + 0) = 1/16
ここまで見てきて、撃破率に関わるパラメータには次のものがあることがわかります。
カードのライフ life
場のカードの数 numCard
場におけるライフ1のカードの数 numLife1Card
これらを利用して、ダメージ回数が2の時についてのカードごとの撃破率の計算式は次のとおりです。
public void CalcuP(int[] cardLives, int damageCount, float[] defeatRates) { Dictionary<int, float> backNumber = new Dictionary<int, float>(); int numCards = cardLives.Length; for (int i = 0; i < numCards; i++) { defeatRates[i] = 0; int life = cardLives[i]; if (backNumber.ContainsKey(life)) { defeatRates[i] = backNumber[life]; } else { float p = 0; if (1 == damageCount) { p = _CalcuOneShot(numCards, life); } else if (2 == damageCount) { p = _CalcuTwoShot(cardLives, i); } defeatRates[i] = p; backNumber[life] = defeatRates[i]; } } } private float _CalcuTwoShot(int[] cardLives, int i) { int life = cardLives[i]; if (3 > life) { if (2 == life) { float p1 = 1 / (float)(cardLives.Length); float p2 = p1; return p1 * p2; } else { float p1 = _CalcuOneShot(cardLives.Length, life); float p2_1 = 1 - p1; int numlife1Card = _GetNumLife1(cardLives, i); float p2 = 0; if (0 < cardLives.Length - 1) { float p2_2 = numlife1Card / (float)(cardLives.Length - 1); float p2_3 = 1 - p2_2; float p2_4 = _CalcuOneShot(cardLives.Length - 1, life); p2 = p2_1 * (p2_3 * p1 + p2_2 * p2_4); } return p1 + p2; } } else { return 0; } } private static int _GetNumLife1(int[] cardLives, int idx) { int numlife1Card = 0; for (int i = 0; i < cardLives.Length; i++) { if (1 == cardLives[i] && i != idx) { ++numlife1Card; } } return numlife1Card; } private float _CalcuOneShot(int numCards, int life) { float p = 1; if (1 == life) { p = 1 / (float)numCards; } else { p = 0; } return p; } }
上の式を使って
場にカードが5枚あり、すべてのカードのライフが1のとき
それぞれのカードの撃破率が 0.4 と出ました。
行って欲しい計算としては
1/5 + 4/5 * (0 * 1/5 + 1 * 1/4) = 2/5
つまり 0.4 が正解です。
合ってますね。
最終的にはシミュレータを作って
おおよそ一致するのか確認する予定です。
続いて、難しくなってくるダメージ回数が3の場合について見ていきましょう。