本文目录导读:

为了给你提供最有价值的答案,我假设你是在游戏开发(如RTS、自走棋)或数据分析场景下,需要用一个脚本来快速模拟并统计两个地面单位(或两组单位)对战的胜率。
以下我提供三个不同深度的Python脚本方案,从最简单的数值对比到带随机性的蒙特卡洛模拟。
基础属性碾压(纯数值计算)
适用场景:没有随机性,纯看攻击力、血量、防御的数值对比,脚本直接通过公式判断谁先倒下。
def ground_combat_winner(unit_a, unit_b):
"""
纯数值对抗计算,返回胜者名字
unit_a/b 字典格式: {'name': '步兵', 'hp': 100, 'attack': 15, 'defense': 5}
规则: 伤害 = max(1, attack - defense)
"""
hp_a = unit_a['hp']
hp_b = unit_b['hp']
while hp_a > 0 and hp_b > 0:
# A攻击B
damage_to_b = max(1, unit_a['attack'] - unit_b['defense'])
hp_b -= damage_to_b
if hp_b <= 0:
return unit_a['name']
# B攻击A
damage_to_a = max(1, unit_b['attack'] - unit_a['defense'])
hp_a -= damage_to_a
if hp_a <= 0:
return unit_b['name']
return "平局" # 理论可能
# 使用示例
soldier = {'name': '人类步兵', 'hp': 100, 'attack': 20, 'defense': 5}
zombie = {'name': '丧尸', 'hp': 120, 'attack': 15, 'defense': 0}
winner = ground_combat_winner(soldier, zombie)
print(f"纯数值计算胜者: {winner}")
蒙特卡洛模拟(含命中率/暴击,最实用)
适用场景:你的游戏有闪避、暴击、攻击间隔等概率元素,脚本通过模拟成千上万次战斗,统计出胜率,这才是真正的“统计”。
import random
def simulate_battle(unit_a, unit_b, rounds=10000):
"""
蒙特卡洛模拟统计胜率
unit_a/b 属性: hp, attack, defense, hit_rate(命中率), crit_rate(暴击率)
"""
wins_a = 0
wins_b = 0
for _ in range(rounds):
hp_a = unit_a['hp']
hp_b = unit_b['hp']
while hp_a > 0 and hp_b > 0:
# A攻击B
if random.random() < unit_a['hit_rate']: # 命中判定
damage = max(1, unit_a['attack'] - unit_b['defense'])
if random.random() < unit_a['crit_rate']: # 暴击判定
damage *= 2
hp_b -= damage
if hp_b <= 0:
wins_a += 1
break
# B攻击A
if random.random() < unit_b['hit_rate']:
damage = max(1, unit_b['attack'] - unit_a['defense'])
if random.random() < unit_b['crit_rate']:
damage *= 2
hp_a -= damage
if hp_a <= 0:
wins_b += 1
break
total = wins_a + wins_b
print(f"=== 战斗统计 (模拟{rounds}次) ===")
print(f"单位A胜率: {wins_a/total:.2%} ({wins_a}次)")
print(f"单位B胜率: {wins_b/total:.2%} ({wins_b}次)")
return wins_a / total # 返回A的胜率
# 使用示例
swordsman = {'name': '剑士', 'hp': 150, 'attack': 25, 'defense': 10, 'hit_rate': 0.85, 'crit_rate': 0.20}
tank = {'name': '重甲兵', 'hp': 250, 'attack': 15, 'defense': 20, 'hit_rate': 0.75, 'crit_rate': 0.05}
a_win_rate = simulate_battle(swordsman, tank, rounds=20000)
基于时间轴的模拟(处理攻击速度)
适用场景:双方攻击速度不同(攻速快但伤害低 vs 攻速慢但伤害高),脚本通过离散时间步长(tick)来精确统计。
import random
def time_based_winner(unit_a, unit_b, tick_interval=0.1, max_time=100):
"""
基于时间轴的精确模拟
unit 属性: hp, damage, attack_speed (每秒攻击次数), hit_rate
"""
time = 0.0
# 记录下一次攻击时间
next_attack_a = 1 / unit_a['attack_speed'] # 初始立即攻击
next_attack_b = 1 / unit_b['attack_speed']
hp_a = unit_a['hp']
hp_b = unit_b['hp']
while time < max_time:
time += tick_interval
# Check A's attack
if time >= next_attack_a:
# 处理命中与伤害
if random.random() < unit_a['hit_rate']:
hp_b -= unit_a['damage']
next_attack_a += 1 / unit_a['attack_speed']
if hp_b <= 0:
return unit_a['name']
# Check B's attack
if time >= next_attack_b:
if random.random() < unit_b['hit_rate']:
hp_a -= unit_b['damage']
next_attack_b += 1 / unit_b['attack_speed']
if hp_a <= 0:
return unit_b['name']
return "超时平局"
# 批量统计胜率的壳子
def stats_winner(unit_a, unit_b, trials=5000):
results = {'a': 0, 'b': 0, 'draw': 0}
for _ in range(trials):
result = time_based_winner(unit_a, unit_b)
if result == unit_a['name']:
results['a'] += 1
elif result == unit_b['name']:
results['b'] += 1
else:
results['draw'] += 1
print(f"战士A胜: {results['a']/trials:.2%}, 战士B胜: {results['b']/trials:.2%}, 平局: {results['draw']/trials:.2%}")
# 测试数据
fast_attacker = {'name': '刺客', 'hp': 80, 'damage': 8, 'attack_speed': 2.0, 'hit_rate': 0.9}
heavy_hitter = {'name': '拳击手', 'hp': 150, 'damage': 30, 'attack_speed': 0.6, 'hit_rate': 0.8}
stats_winner(fast_attacker, heavy_hitter)
终极技巧:通过Excel公式快速估算(无需编程)
如果你不想写代码,也可以用Excel/Google Sheets模拟,但效率较低,一般用RAND()和IF嵌套模拟一次战斗,然后下拉100行统计胜场。
你还需要什么?
如果你需要的是特定游戏(如LOL、War3)的底层数据计算,或者你需要读取JSON配置文件来做大量单位的对比,请告诉我:
- 你的数据源是什么?(JSON/MongoDB/CSV?)
- 你的“地面对抗”包含哪些参数?(是否有AOE、吸血、控制技能?)
可以直接复制方案二的代码,填入你实际的对局数据,运行即可得到精确的胜率统计。 这是大多数游戏平衡性测试的标准做法。