これが、征服王の模倣者アプレットでの戦いの勝者を決定するために使用したものです。このゲームでは、あなたの状況と同様に、攻撃値と防御値しかありません。攻撃者が勝つ確率は、攻撃者が持っているポイントが多いほど高く、防御が持っているポイントが少ないほど高く、攻撃が成功する確率は50%です。
アルゴリズム
ランダムなコインを裏返します。
1a。ヘッズ:防御はポイントを失います。
1b。テール:ヘッドはポイントを失います。
それでも防御側と攻撃側の両方にポイントがある場合は、ステップ1に戻ります。
0ポイントに下がった人は誰もが戦闘に敗北します。
3a。攻撃者の0まで:攻撃は失敗します。
3b。防御を0に下げる:攻撃は成功します。
私はJavaで作成しましたが、他の言語に簡単に翻訳できるはずです。
Random rnd = new Random();
while (att > 0 && def > 0)
{
if (rnd.nextDouble() < 0.5)
def--;
else
att--;
}
boolean attackSucceeds = att > 0;
例
たとえば、確率が50%であることを確認するために、att = 2およびdef = 2であるとします。
バトルは最大n = att + def - 1
コインフリップで決定されます。この例では3です(ここでは基本的に3のベストです)。コインフリップの可能な組み合わせは2 n通りあります。ここで、「W」は攻撃者がコインフリップに勝ったことを意味し、「L」は攻撃者がコインフリップに負けたことを意味します。
L,L,L - Attacker loses
L,L,W - Attacker loses
L,W,L - Attacker loses
L,W,W - Attacker wins
W,L,L - Attacker loses
W,L,W - Attacker wins
W,W,L - Attacker wins
W,W,W - Attacker wins
攻撃者は4/8、またはケースの50%で勝利します。
数学
この単純なアルゴリズムから生じる数学的確率は、アルゴリズム自体よりも複雑です。
正確にx Lsが存在する組み合わせの数は、組み合わせ関数によって与えられます。
C(n, x) = n! / (x! * (n - x)!)
0
とatt - 1
Lの間に攻撃者が勝利します。入賞組合せの数はからの組合せの和に等しい0
介してatt - 1
、累積二項分布:
(att - 1)
w = Σ C(n, x)
x = 0
攻撃者が勝つ確率は、wを2 nで割った累積2項確率です。
p = w / 2^n
以下は、任意att
とdef
値のこの確率を計算するJavaのコードです。
/**
* Returns the probability of the attacker winning.
* @param att The attacker's points.
* @param def The defense's points.
* @return The probability of the attacker winning, between 0.0 and 1.0.
*/
public static double probWin(int att, int def)
{
long w = 0;
int n = att + def - 1;
if (n < 0)
return Double.NaN;
for (int i = 0; i < att; i++)
w += combination(n, i);
return (double) w / (1 << n);
}
/**
* Computes C(n, k) = n! / (k! * (n - k)!)
* @param n The number of possibilities.
* @param k The number of choices.
* @return The combination.
*/
public static long combination(int n, int k)
{
long c = 1;
for (long i = n; i > n - k; i--)
c *= i;
for (long i = 2; i <= k; i++)
c /= i;
return c;
}
テストコード:
public static void main(String[] args)
{
for (int n = 0; n < 10; n++)
for (int k = 0; k <= n; k++)
System.out.println("C(" + n + ", " + k + ") = " + combination(n, k));
for (int att = 0; att < 5; att++)
for (int def = 0; def < 10; def++)
System.out.println("att: " + att + ", def: " + def + "; prob: " + probWin(att, def));
}
出力:
att: 0, def: 0; prob: NaN
att: 0, def: 1; prob: 0.0
att: 0, def: 2; prob: 0.0
att: 0, def: 3; prob: 0.0
att: 0, def: 4; prob: 0.0
att: 1, def: 0; prob: 1.0
att: 1, def: 1; prob: 0.5
att: 1, def: 2; prob: 0.25
att: 1, def: 3; prob: 0.125
att: 1, def: 4; prob: 0.0625
att: 1, def: 5; prob: 0.03125
att: 2, def: 0; prob: 1.0
att: 2, def: 1; prob: 0.75
att: 2, def: 2; prob: 0.5
att: 2, def: 3; prob: 0.3125
att: 2, def: 4; prob: 0.1875
att: 2, def: 5; prob: 0.109375
att: 2, def: 6; prob: 0.0625
att: 3, def: 0; prob: 1.0
att: 3, def: 1; prob: 0.875
att: 3, def: 2; prob: 0.6875
att: 3, def: 3; prob: 0.5
att: 3, def: 4; prob: 0.34375
att: 3, def: 5; prob: 0.2265625
att: 3, def: 6; prob: 0.14453125
att: 3, def: 7; prob: 0.08984375
att: 4, def: 0; prob: 1.0
att: 4, def: 1; prob: 0.9375
att: 4, def: 2; prob: 0.8125
att: 4, def: 3; prob: 0.65625
att: 4, def: 4; prob: 0.5
att: 4, def: 5; prob: 0.36328125
att: 4, def: 6; prob: 0.25390625
att: 4, def: 7; prob: 0.171875
att: 4, def: 8; prob: 0.11328125
観察
確率は0.0
、攻撃者が0
ポイントを持っている場合、攻撃者がポイントを1.0
持っているが防御が0
ポイントがある0.5
場合、ポイントが等しい0.5
場合、攻撃者が防御よりもポイントが少ない場合よりも少なく、攻撃者が防御よりも0.5
ポイントが多い場合よりも大きい。
とを使用するatt = 50
とdef = 80
、BigDecimal
オーバーフローを回避するためにs に切り替える必要がありましたが、約0.0040の確率が得られます。
あなたは、変更することにより、0.5に近い確率作ることができるatt
の平均値であることををatt
してdef
値。Att = 50、Def = 80は(65、80)となり、0.1056の確率になります。