方法的问题在于,您在决定主要属性时就决定了战斗结果。当您有4个主要统计数据时,而战斗机仅在其中一个统计数据中表现更好,则无论实际差异有多大,他们的获胜几率始终为1比4。当您想要更细粒度的结果时,您需要更细粒度的随机性。
首先,我认为您可以保留对main属性的随机选择,也可以根据需要保留公式。这个数字代表了这个战斗员在这次特定遭遇中所拥有的优势。对于本文的其余部分,我将其简称为power
。
我在很多游戏中使用的一种方法,当在确定性的两件事之间进行决斗时,对我很有用,一种方法power
是在两者之间0
以及power
在两者之间滚动一个随机浮点数,然后看看谁滚动得更高。这是此方法的预期结果的列表。百分比不是计算出来的,而是通过每个组合进行100000次打斗和迭代计数并计算赢得频率的人来实验产生的:
PowerA | PowerB | Win chance of A
9 | 1 | 94.5%
8 | 2 | 87.5%
7 | 3 | 78.6%
6 | 4 | 66.6%
5 | 5 | 50.0%
4 | 6 | 33.3%
3 | 7 | 21.5%
2 | 8 | 12.5%
1 | 9 | 5.5%
关于此算法的好处是,无论您处理多少数字,它都可以缩放。0.3与0.7的机会与3与7、300与700或3,000,000,000与7,000,000,000的机会相同。
如果您的口味仍然难以预测,则可以通过为每个战斗人员滚动多个随机数并将其相加来使战斗更加可预测。由于大数定律,许多随机事件将平均并导致更可预测的结果。这是具有不同迭代次数的表。
| A | B | Iterations
| | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
-----------------------------------------------------------------------------------
| 9 | 1 | 94.5% | 99.3% | 99.9% |100.0% |100.0% |100.0% |100.0% |100.0% |100.0% |
| 8 | 2 | 87.4% | 96.3% | 98.8% | 99.5% | 99.8% |100.0% |100.0% |100.0% |100.0% |
| 7 | 3 | 78.7% | 89.2% | 94.0% | 96.6% | 97.8% | 98.9% | 99.2% | 99.6% | 99.7% |
| 6 | 4 | 66.8% | 74.3% | 79.2% | 82.9% | 85.7% | 88.0% | 89.9% | 91.2% | 92.5% |
| 5 | 5 | 50.0% | 50.0% | 50.0% | 50.0% | 50.0% | 50.0% | 50.0% | 50.0% | 50.0% |
| 4 | 6 | 33.6% | 25.6% | 20.9% | 17.1% | 14.7% | 12.0% | 10.2% | 8.9% | 7.5% |
| 3 | 7 | 21.4% | 10.7% | 6.0% | 3.5% | 2.0% | 1.2% | 0.7% | 0.4% | 0.3% |
| 2 | 8 | 12.7% | 3.7% | 1.2% | 0.4% | 0.1% | 0.1% | 0.0% | 0.0% | 0.0% |
| 1 | 9 | 5.5% | 0.7% | 0.1% | 0.0% | 0.0% | 0.0% | 0.0% | 0.0% | 0.0% |
上表中100%和0%的结果是由于四舍五入而产生的一种幻觉。除非power
非战斗人员的恰好为0,总有可能获胜。在上面的测试中它只是没有发生,因此您可以期望它低于1:100000。
您可能还会注意到一些细微的不正常现象,这可能归因于java.lang.Random的情绪波动,当您使用其他种子再次运行代码时可能不会出现。
我用来生成此表的程序(Java)。
public class Main {
private static Random random = new Random();
private static final int SAMPLES = 100000;
public static void main(String[] args) {
for (int i = 1; i < 10; i++) {
double powerA = 10.0 - i;
double powerB = i;
System.out.print("| ");
System.out.print((int)powerA);
System.out.print(" | ");
System.out.print((int)powerB);
System.out.print(" | ");
for (int iterations = 1; iterations < 10; iterations++) {
int wins = 0;
for (int j = 0; j < SAMPLES; j++) {
if (fight(powerA, powerB, iterations)) wins++;
}
System.out.print(String.format("%2.1f", 100.0 * (double)wins / (double)SAMPLES));
System.out.print("% | ");
}
System.out.print("\n");
}
}
private static boolean fight(double powerA, double powerB, int iterations) {
double sumA = 0.0f;
double sumB = 0.0f;
for (int i = 0; i < iterations; i++) {
sumA += random.nextDouble() * powerA;
sumB += random.nextDouble() * powerB;
}
return sumA > sumB;
}
}
如果您想在游戏中使用此代码,则该代码已由Sam Hocevar发布的WTF Public License Version 2许可。