概率统计大作业

本研究通过构建简化的游戏战斗模型,比较两种不同武器在面对怪物时的击杀效率,采用蒙特卡洛仿真和期望分析方法,在此基础上引入暴击机制和伪随机补偿机制,从概率统计角度探讨武器平衡性的调整方法。研究表明,引入复杂机制可有效平衡武器性能,提升玩家体验

游戏平衡机制的研究:以伤害期望为例

——基于蒙特卡洛仿真的统计学研究

X 经济与管理学院 学号已脱敏 笔者

摘要:

本研究通过构建简化的游戏战斗模型,比较两种不同武器在面对怪物时的击杀效率,采用蒙特卡洛仿真和期望分析方法,在此基础上引入暴击机制和伪随机补偿机制,从概率统计角度探讨武器平衡性的调整方法。研究表明,引入复杂机制可有效平衡武器性能,提升玩家体验。

关键词:游戏平衡、蒙特卡洛模拟、伪随机补偿

引言:

游戏设计中,武器平衡性是提升玩家体验和保持竞技公平性的关键因素。武器若存在显著优劣,会影响玩家选择与策略,甚至削弱游戏寿命。本文从概率论与数理统计角度出发,研究两种伤害模型各异的武器在击杀敌人所需攻击次数上的差异,并通过仿真数据量化差距。同时,引入现代游戏中常见的暴击机制与补偿机制,进一步分析其对武器平衡的影响。

1 方法:概率建模与蒙特卡洛仿真

我们将击杀怪物所需的攻击次数建模为一个随机变量问题。设怪物初始生命值为$H \in \mathbb{N}^{+}$,攻击所造成的伤害为离散随机变量 D,其概率分布由武器决定。

定义如下:

对于武器1,其伤害集合为

1
\mathcal{D}_{1} = \{ 1,2,3,4,5\}

,均匀分布,则每一项概率为:$\mathbb{P}(D = d) = \frac{1}{5}$ ,$\ \ d \in \mathcal{D}_{1}\$;

对于武器2,其伤害集合为

1
\mathcal{D}_{2} = \{ 2,3,4\}

,每一项概率为:$\mathbb{P}(D = d) = \frac{1}{3}$ $\ \ d \in \mathcal{D}_{2}$。

1.1 模型目标

我们感兴趣的目标是,击杀血量为H的怪物所需攻击次数的期望,记作$\mathbb{E}\lbrack N_{H}\rbrack$。

由于伤害是离散的、递减的非线性过程,难以通过解析方法直接求解,因此采用蒙特卡洛模拟逼近其期望值。

2 蒙特卡洛模拟方法

定义仿真轮数为 T(如 15000),每轮模拟过程如下[1]:

2.1初始化生命值

1
h: = H

,攻击计数 $n: = 0$

2.2 循环:直到

1
h \leq 0

2.3 随机从$\mathcal{D}$中抽取一次伤害

1
\ d \sim D

2.4 更新血量:

1
h: = h - d

2.5 累加攻击次数:

1
n: = n + 1

2.6 记录当前轮击杀所需次数 $n$

完成 T 次仿真后,期望估计值为:

1
\mathbb{E}\lbrack N_{H}\rbrack \approx \frac{1}{T}\sum_{i = 1}^{T}n_{i}

模拟结果如下(图1、图2):

Screenshot 2025-05-30 at 14.58.52

图1 : 原始模型下预期击杀所需次数

Screenshot 2025-05-30 at 15.00.58

图2 : 原始模型下两把武器攻击次数的差值

3 扩展机制建模

我们进一步引入两个常见机制:

3.1暴击机制(Critical Hit)

设暴击概率为

1
p

,暴击倍率为

1
\beta

,则每次攻击的伤害变为:

1
2
3
4
D’ = \left\{ \begin{matrix}
\beta \cdot D, & p \\
D, & 1 - p
\end{matrix} \right.\

这使得$D’$成为混合分布,期望伤害为:

1
\mathbb{E}\lbrack D’\rbrack = (1 - p) \cdot \mathbb{E}\lbrack D\rbrack + p \cdot \beta \cdot \mathbb{E}\lbrack D\rbrack = \mathbb{E}\lbrack D\rbrack \cdot \lbrack 1 + p(\beta - 1)\rbrack

模拟结果如下(图3、图4),可以看出不同武器差值有所下降:

Screenshot 2025-05-30 at 15.05.23

图3 : 引入暴击后预期击杀所需次数

Screenshot 2025-05-30 at 15.07.58

图4 : 引入暴击后两把武器攻击次数的差值

3.2 伪随机补偿机制(Pity System)

为模拟玩家体验优化系统,引入线性补偿机制[2]:若连续

1
\ k

次未暴击,则下一次暴击概率提高到:

1
p_{k} = \min(1,p + \delta \cdot k)

其中

1
\delta

为每次未暴击后暴击概率的递增量。这种机制通过控制波动,缓解概率失控问题。

模拟结果如下(图5、图6),可以看出不同武器差值进一步下降,平衡性补偿更好:

Screenshot 2025-05-30 at 15.10.36

图5 : 引入伪随机后预期击杀所需次数

Screenshot 2025-05-30 at 15.11.56

图6 : 引入伪随机后两把武器攻击次数的差值

4 结论分析

仿真数据显示,在基础模型下,武器2在大多数血量下击杀效率更高(期望攻击次数更少),只有当 $HP = 5$ 时武器1略有优势。
引入暴击机制后,若暴击分布均匀,武器1受益更大,因其基础伤害波动大,暴击后最高可达10。
进一步引入伪随机补偿机制后,两武器在整体期望上更为接近。说明补偿机制有助于平衡武器输出的一致性。

5 展望

未来研究可将模型扩展到更复杂的 RPG 战斗系统,如加入技能冷却、状态异常、敌人抗性等机制。同时可尝试更多平衡设计的自动化验证方法(如强化学习驱动的测试角色模拟)。

参考文献:

[1] 朱陆陆.蒙特卡洛方法及应用[D].华中师范大学,2014.

[2] 陈海龙,李宏.基于MATLAB的伪随机序列的产生和分析[J].计算机仿真,2005,(05):98-100.

案例代码:

Test 1 :

import random
import matplotlib.pyplot as plt
# === 配置参数 ===
MAX_HP = 50 # 最大怪物血量
TRIALS_PER_HP = 15000 # 每个血量下的仿真次数
# 武器伤害范围
weapon1_range = [1, 2, 3, 4, 5] # Weapon 1: 1~5
weapon2_range = [2, 3, 4] # Weapon 2: 2~4
# 存储期望攻击次数
expect1 = []
expect2 = []
# 蒙特卡洛函数
def simulate_kill(hp, damage_range, trials):
total_attacks = 0
for _ in range(trials):
current_hp = hp
attacks = 0
while current_hp > 0:
damage = random.choice(damage_range)
current_hp -= damage
attacks += 1
total_attacks += attacks
return total_attacks / trials
# 进行仿真
hp_range = list(range(1, MAX_HP + 1))
print("正在进行蒙特卡洛仿真,请稍候...")
for hp in hp_range:
e1 = simulate_kill(hp, weapon1_range, TRIALS_PER_HP)
e2 = simulate_kill(hp, weapon2_range, TRIALS_PER_HP)
expect1.append(e1)
expect2.append(e2)
print("仿真完成。开始绘图...")
# === 绘制期望攻击次数图 ===
plt.figure(figsize=(10, 6))
plt.plot(hp_range, expect1, label='Weapon 1 (1~5 dmg)', marker='o')
plt.plot(hp_range, expect2, label='Weapon 2 (2~4 dmg)', marker='s')
plt.xlabel('Monster HP')
plt.ylabel('Expected Hits to Kill')
plt.title('Expected Hits vs Monster HP (Monte Carlo Simulation)')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
# === 绘制差值图(武器1 - 武器2)===
diff = [e1 - e2 for e1, e2 in zip(expect1, expect2)]
plt.figure(figsize=(10, 4))
plt.axhline(0, color='gray', linestyle='--')
plt.plot(hp_range, diff, label='Weapon1 - Weapon2', color='purple', marker='^')
plt.xlabel('Monster HP')
plt.ylabel('Expected Hit Difference')
plt.title('Expected Hits Difference: Weapon1 - Weapon2')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()

Test 2 :

暴击机制

CRIT_CHANCE = 0.2 # 暴击率

CRIT_MULTIPLIER = 2 # 暴击伤害倍率

Test 3 :

def simulate_kill(hp, damage_range, trials):

total_attacks = 0

for _ in range(trials):

current_hp = hp

attacks = 0

crit_chance = BASE_CRIT_CHANCE

while current_hp > 0:

damage = random.choice(damage_range)

if random.random() < crit_chance:

damage *= CRIT_MULTIPLIER

crit_chance = BASE_CRIT_CHANCE # 暴击后重置暴击率

else:

crit_chance += BASE_CRIT_CHANCE # 未暴击时增加暴击率

crit_chance = min(crit_chance, 1.0) # 暴击率不超过100%

current_hp -= damage

attacks += 1

total_attacks += attacks

return total_attacks / trials