编写程序使用蒙特卡洛方法以模拟计算游戏《红色警戒2》中坦克集群间交战的所有可能交换比和双方的获胜概率。通过计算,得到了一些可以修正兰彻斯特方程的结果,对指挥官的战前分析决策具有实际意义。
本文公式较多,在浏览器中将会花较长时间用于渲染公式。
兰彻斯特方程
该理论于一战前期的1914年,由英国人弗雷德里克·威廉·兰彻斯特首先创立。
它采用数学演绎战术原则,将数学与军事战术学结合起来。兰彻斯特最先提出了一个关于空战战术的尝试性数学模型,描述作战双方兵力变化过程的数学微分方程。
这个理论属于确定性数学模型,一般认为可宏观地描述双方战斗的毁伤过程。常用于优选步兵作战兵力的投放、西方研究战争的定量、科学的常用方法。
在近代战斗条件下,红、蓝两军交战,双方各自装备同类武器,相互通视,并在武器射程范围内进行直接瞄准射击;双方每一战斗单位射击对方每一战斗单位的机会大致相同。将双方在战斗中尚存的战斗单位数作为连续的状态变量,以m(t)、n(t)表示在战斗开始后t时刻蓝方、红方在战斗中尚存的作战单位数,可用下列微分方程组来描述战斗过程中双方兵力随时间的损耗关系:
\begin{equation}
\frac{dm(t)}{dn(t)} = \frac{-\beta{n(t)}}{-\alpha{n(t)}}
\end{equation}
式中α、β分别为蓝方、红方在单位时间内每一战斗单位毁伤对方战斗单位的数目, 简称为蓝方、 红方的毁伤率系数。
这是一个连续的方程,它的通解形式、它的实际意义,例如平方率、线性率什么的在网上均有大量论述,这里不再陈述。
红警的伤害机制
《红色警戒》是一款经典的RTS游戏。我们可以研究红警中的伤害机制,并编写交战模拟平台的程序,从而验证兰彻斯特方程,为交战提供策略。红警作战主要以坦克战为主,因此我们这里的研究对象也就是坦克了。
红警里面有一个Rulesmd.ini文件,用来定义单位的各种属性。红警中坦克分为轻甲、中甲和重甲。武器对对方的伤害是杀伤力乘上对这种装甲的伤害系数。坦克在受到攻击后,血条便减少相应的伤害值。此外,我们在模拟平台中还要体现装弹间隔时间。红警里面部分单位还有自动回血能力,例如天启坦克、基洛夫空艇、武装采矿车等。这里以对战中的头号杀器:犀牛坦克为例,列举这些属性的值:
- 制造成本:900
- 杀伤力:90
- 对轻甲、中甲、重甲的伤害分别为:75%,100%,100%
- 体力:400
- 装弹间隔时间:65
- 不具有自动回血能力
编写如下的代码:
struct TANK
{
int life;
int atk; //攻击力
int target;
int time;
int once; //判断临死一击
int cover;
int value;
int armor; //1、 轻甲 2、中甲 3、重甲
int ps[3];
};
typedef struct TANK tank;
剩下的就是编写程序模拟作战过程了。以一个循环的计数器作为时间线,坦克在最初随意地寻找攻击目标,在锁定目标之后便每间隔一次装填时间完成一次对目标的进攻(以及每经过一次回血周期便恢复一定的血量)。在红警中可能会出现许多个坦克攻击同一辆坦克,导致坦克在毁灭的时刻遭受了远远大于其残余血量的伤害,这个在模拟中也要得到体现。因此,临死一击以及临死所受伤害是一个相对不太好处理的地方。程序里把常见的八种坦克的数据收录进去:灰熊坦克、犀牛坦克、天启坦克、幻影坦克、光棱坦克、遥控坦克、坦克杀手、武装采矿车,用户不用手动输入坦克的属性。根据蒙特卡洛方法的思想,对作战过程总共进行1500次模拟。
程序运行的截图如下所示:
又比如,模拟结果显示,在理想条件下,30辆犀牛坦克(红军)与25辆坦克杀手(蓝军)交战的结果为
交换比:
最高1.25
最低0.33
平均0.64
价值交换比:0.64
胜率:11.67%
零伤亡概率:0.00%
在理想条件下,40辆犀牛坦克(红军)与20辆坦克杀手(蓝军)交战的结果为
交换比:
最高20.00
最低1.82
平均3.27
价值交换比:3.27
胜率:100.00%
零伤亡概率:0.00%
总结
- 可以看出,连续的兰彻斯特方程对于小数目的离散作战不能真实预测。若将5辆灰熊坦克与3辆犀牛坦克,则5辆灰熊坦克仅能勉强战胜3辆犀牛坦克。而经过实际的模拟,5辆灰熊坦克与3辆犀牛坦克交战,灰熊坦克胜率为100%,且平均只损失一辆坦克1.56辆坦克,足可见两种模型的差距
- 若双方是相同数目的同等坦克,则双方胜率均会低于50%。如若1辆坦克对抗1辆同型号坦克,同时开火,则双方都不会获胜(双方坦克同时被摧毁)。若双方各两辆坦克对抗,则双方胜率均为26%。双方十辆坦克对抗,任一方胜率为40%.若双方45辆坦克对抗,则任一方胜率为48%.由此可见,坦克的数目越大,可能出现的情况就越多,出现平局的可能性就越小
- 许多人认为成群的光棱海无法击破,实际上单一的光棱坦克没有别的坦克配合的话很难与犀牛坦克群的阵型冲击、天启坦克的重火力重护甲、矿车的重护甲高射速抗衡。尽管光棱坦克射程极远,但没有幻影坦克配合,无法直接正面参与坦克战
- 一般而言,人们常常喜欢集中优势兵力攻打某个单位,这种战术在特殊情况下是错误的。例如天启坦克群与别的坦克群交战,天启坦克依靠重火力有很大的胜算,但是如果所有天启坦克集中火力攻击一辆坦克,这样反而浪费炮弹
- 这里没有考虑兵种配合的问题。如在坦克阵中假如与之配合的步兵(尤其是反坦克步兵),则既能吸引敌方火力向步兵开火,又能给以敌方杀伤
- 作为一个资深红警玩家(2017年更新,早就不玩了),也知道这个模拟平台还是有不完善的地方。在真实的红警坦克战里,如果考虑操作,那么坦克攻击范围、移动速度、炮塔转动角度、是否能够移动攻击都会造成非常大的影响,更不用提什么分兵战术、迂回战术等。而且这里没有考虑到光棱坦克的溅射伤害和幻影坦克的隐蔽性,还有作战单位升级的情况
- 事实上,对于真正的坦克战而言,机动性、射程、移动攻击能力、阵型、布坦协同都是十分重要的,而我的程序模拟的是定点攻击,这实际上与火炮别无两样。坦克需要发挥其阵型冲锋、冲锋打散阵型、移动攻击等机动性优势,例如犀牛坦克常常强势冲锋等战术,这是程序无法模拟的。因此,程序仅仅能提供一个基本的战术参考,这替代不了指挥官的战术决策
- 2017年更新:现在看自己以前写的代码感觉是真的丑陋,不过这也说明了自己的代码水平还是有一丢丢进步的