王者站撸分析
问题背景
有这样两个角色
其中一个角色的被动是受到攻击会减少攻击者的攻速1%,该被动可以叠加40层
另一个角色的被动是攻击敌方会提升自己1%的免伤效果,该被动可以叠加20层。
在站撸情况下 哪方胜算更大?
为了解决这个问题,我们需要建立一个数学模型,分析两个角色在“站撸”情况下的战斗表现,并比较哪一方的胜算更大。
1. 设定符号与参数
- 角色A的被动效果:每次受到攻击减少攻击者1%的攻击速度,可以叠加40层。
- 角色B的被动效果:每次攻击敌方增加自己1%的免伤效果,可以叠加20层。
假设:
- A 0 A_0 A0 和 B 0 B_0 B0 分别为角色A和B的初始攻击速度。
- D A D_A DA 和 D B D_B DB 分别为角色A和B的初始攻击力。
- H A H_A HA 和 H B H_B HB 分别为角色A和B的初始生命值。
- T T T 为时间。
- n A ( T ) n_A(T) nA(T) 和 n B ( T ) n_B(T) nB(T) 分别表示角色A和B在时间 T T T 时的攻击次数。
- S A ( T ) S_A(T) SA(T) 和 S B ( T ) S_B(T) SB(T) 分别表示角色A和B在时间 T T T 时的攻击速度。
2. 攻击速度与免伤效果的动态变化
-
角色A每次受到攻击,攻击者的攻击速度降低1%。在时间 T 时,角色B的攻击速度为:
S B ( T ) = B 0 × ( 1 − 0.01 × min ( n B ( T ) , 40 ) ) S_B(T) = B_0 \times (1 - 0.01 \times \min(n_B(T), 40)) SB(T)=B0×(1−0.01×min(nB(T),40)) -
角色B每次攻击,自己的免伤效果增加1%。在时间 T 时,角色B的免伤效果为:
R B ( T ) = 1 − 0.01 × min ( n B ( T ) , 20 ) R_B(T) = 1 - 0.01 \times \min(n_B(T), 20) RB(T)=1−0.01×min(nB(T),20)
3. 伤害计算
假设两角色的攻击频率较高,因此可以近似认为在每个时间段内,角色A和B的攻击间隔为 1 S A ( T ) \frac{1}{S_A(T)} SA(T)1 和 1 S B ( T ) \frac{1}{S_B(T)} SB(T)1。
- 角色A在时间 ( T ) 时对角色B造成的总伤害为:
D A _ t o t a l ( T ) = n A ( T ) × D A × R B ( T ) D_{A\_total}(T) = n_A(T) \times D_A \times R_B(T) DA_total(T)=nA(T)×DA×RB(T) - 角色B在时间 ( T ) 时对角色A造成的总伤害为:
D B _ t o t a l ( T ) = n B ( T ) × D B D_{B\_total}(T) = n_B(T) \times D_B DB_total(T)=nB(T)×DB
4. 胜负判定
假设战斗结束的条件是其中一方的生命值降为零。比较角色A和B的生命值变化,哪一方首先降为零,哪一方就输掉战斗。
5. 代码模拟
设置初始生命值为1000
分为攻击力5 50 200 500对程序进行模拟,当有一方被击败,则停止模拟。
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 定义函数来模拟不同条件下的战斗结果
def simulate_battle_params(health_A, health_B, power_A, power_B, speed_A, speed_B):
h_A, h_B = health_A, health_B
s_A, s_B = speed_A, speed_B
stacks_A, stacks_B = 0, 0
delta_t = 0.05
time = 0.0
health_A_list, health_B_list = [h_A], [h_B]
while h_A > 0 and h_B > 0:
# 角色B攻击角色A
if time % (1 / s_B) < delta_t:
h_A -= power_B
stacks_A = min(stacks_A + 1, 40) # 角色A的最大叠加层数
s_B = speed_B * (1 - 0.01 * stacks_A)
# 角色A攻击角色B
if time % (1 / s_A) < delta_t:
h_B -= power_A * (1 - 0.01 * stacks_B)
stacks_B = min(stacks_B + 1, 20) # 角色B的最大叠加层数
time += delta_t
health_A_list.append(h_A)
health_B_list.append(h_B)
return health_A_list, health_B_list, time
# 分析初始攻击力相同但大小不同的情况,绘制图像
# 角色A和B的其他参数保持不变,攻击力从小到大变化
# 假设 simulate_battle_params 函数已经定义
attack_powers = [5,50,200,500] # 攻击力从10变化到100,共4种情况
fig, axs = plt.subplots(2, 2, figsize=(10, 8))
colors = ['b', 'g', 'r', 'c'] # 为每条线设置颜色
# 生成不同攻击力下的结果曲线
for index, power in enumerate(attack_powers):
health_A_list, health_B_list, _ = simulate_battle_params(1000, 1000, power, power, 1.0, 1.0)
i = index // 2
j = index % 2
ax = axs[i][j]
ax.plot(health_A_list, label=f'生命值 A (攻击力: {power})', color=colors[0])
ax.plot(health_B_list, label=f'生命值 B (攻击力 {power})', color=colors[1])
ax.set_ylim(0, 1000)
ax.set_xlabel('时间')
ax.set_ylabel('生命值')
ax.legend()
plt.tight_layout()
plt.show()
结果分析
可以看出仅在攻击力小时,B先被击败,A获胜。攻击力大于50时,A先被击败,B获胜。