本文目录导读:

这是一个非常经典且有趣的Python综合案例,既然你问“哪队能笑到最后”,我猜你可能是在做一个模拟比赛或策略博弈的项目。
为了满足“综合”的要求(涵盖面向对象、数据结构、随机性、算法),我为你设计了一个 “NPC大乱斗” 模拟器。
场景设定: 有三支队伍(战士队、法师队、刺客队),每队有3名角色,他们进行循环赛(两两对决),最终根据积分(胜3平1负0)和净胜分决出总冠军。
下面是一段完整、可直接运行的Python代码,它会模拟整个赛程并告诉你哪支队伍笑到了最后。
import random
import itertools
# ---------- 第一部分:构建角色基类(面向对象) ----------
class Hero:
def __init__(self, name, hp, attack, defense, speed, crit_rate=0.2):
self.name = name
self.max_hp = hp
self.hp = hp
self.attack = attack
self.defense = defense
self.speed = speed
self.crit_rate = crit_rate # 暴击率
self.is_alive = True
def take_damage(self, damage):
# 防御减伤
actual_damage = max(1, damage - self.defense)
self.hp -= actual_damage
if self.hp <= 0:
self.hp = 0
self.is_alive = False
return actual_damage
def attack_target(self, target):
# 基础攻击计算暴击
if random.random() < self.crit_rate:
damage = int(self.attack * 1.5) # 暴击150%
else:
damage = self.attack
final_dmg = target.take_damage(damage)
return f"{self.name} 攻击 {target.name},造成 {final_dmg} 点伤害"
def reset(self):
self.hp = self.max_hp
self.is_alive = True
def __str__(self):
return f"{self.name}(HP:{self.hp}/{self.max_hp})"
# ---------- 第二部分:定义三个特殊队伍(继承与多态) ----------
class Warrior(Hero): # 战士:高攻高防,技能是破甲
def special_skill(self, target):
# 无视防御的打击(相当于真实伤害)
damage = int(self.attack * 0.8)
real_dmg = target.take_damage(damage + target.defense) # 无视防御
return f" [战士技能]破甲斩!无视防御,造成 {real_dmg} 点伤害"
class Mage(Hero): # 法师:脆皮高爆发,技能是群体火球(或双体)
def special_skill(self, targets):
# 随机选1-2个目标攻击(这里简化,选第一个和目标攻击力最高的)
if len(targets) == 1:
targets = targets * 2
# 攻击所有存活目标(这里限制最多打2个)
dmg_list = []
for t in targets:
if t.is_alive:
dmg = int(self.attack * 1.2)
final_dmg = t.take_damage(dmg)
dmg_list.append(t.name + ":" + str(final_dmg))
return f" [法师技能]烈焰风暴!对 {', '.join(dmg_list)} 造成伤害"
class Assassin(Hero): # 刺客:极高速度与暴击,技能是连续攻击
def special_skill(self, target):
total = 0
# 刺客攻击三次(每次50%攻击力)
for _ in range(3):
if target.is_alive:
dmg = target.take_damage(int(self.attack * 0.5))
total += dmg
return f" [刺客技能]影刃连击!合计造成 {total} 点伤害"
# ---------- 第三部分:构建比赛逻辑(算法与数据处理) ----------
class Team:
def __init__(self, name, heroes):
self.name = name
self.heroes = heroes # 列表(三名英雄)
self.wins = 0
self.losses = 0
self.points = 0
self.score_diff = 0 # 净胜分
def reset(self):
for h in self.heroes:
h.reset()
# 全场总生命值作为比赛输出指标
self.total_hp = sum(h.max_hp for h in self.heroes)
def is_defeated(self):
return all(not h.is_alive for h in self.heroes)
def get_alive_heroes(self):
return [h for h in self.heroes if h.is_alive]
def __str__(self):
return self.name
def battle_phase(team_a, team_b):
"""
进行一个回合(两两对战直到一方全灭)
返回 (胜者team, 败者team, 剩余血量比)
"""
# 初始化双方reset
team_a.reset()
team_b.reset()
# 打乱顺序,体现随机性(用列表存储所有存活角色)
all_heroes_a = list(team_a.heroes)
all_heroes_b = list(team_b.heroes)
round_num = 0
# 主循环:直到一方团灭
while not team_a.is_defeated() and not team_b.is_defeated():
round_num += 1
# 行动顺序按照速度排序(所有存活角色混合)
alive_a = team_a.get_alive_heroes()
alive_b = team_b.get_alive_heroes()
combatants = []
# 为每个英雄分配一个队伍标签
for h in alive_a:
combatants.append((h, 'A'))
for h in alive_b:
combatants.append((h, 'B'))
# 按速度排序(如果速度相同则随机先手)
combatants.sort(key=lambda x: (x[0].speed, random.random()), reverse=True)
# 逐个行动(每个英雄行动一次就算一轮回合结束)
actions_log = []
for hero, camp in combatants:
if hero.is_alive:
# 选择目标(随机敌方存活英雄)
if camp == 'A':
enemies = team_b.get_alive_heroes()
else:
enemies = team_a.get_alive_heroes()
if not enemies:
break # 没有敌人了退场
target = random.choice(enemies)
# 决定使用普通攻击还是技能(技能概率40%)
if random.random() < 0.4:
# 法师技能可以多重目标
if isinstance(hero, Mage):
# 法师可能群体攻击(这里简化,攻击所有,但伤害衰减)
log = hero.special_skill([target] + [enemies[0] if len(enemies) > 1 and enemies[0] != target else target])
actions_log.append(log)
else:
# 其他职业对单体
log = hero.special_skill(target)
actions_log.append(log)
else:
log = hero.attack_target(target)
actions_log.append(log)
# 检查战斗结束条件
if team_a.is_defeated() or team_b.is_defeated():
break
# 防止死循环(如果双方都不掉血则强制结束——这里加个保险)
if round_num > 100:
# 比较血量百分比
a_hp = sum(h.hp for h in team_a.heroes)
b_hp = sum(h.hp for h in team_b.heroes)
if a_hp >= b_hp:
winner, loser = team_a, team_b
else:
winner, loser = team_b, team_a
return winner, loser, actions_log
# 正常结束
if team_a.is_defeated():
winner, loser = team_b, team_a
else:
winner, loser = team_a, team_b
return winner, loser, actions_log
# ---------- 第四部分:主程序与统计(综合应用) ----------
def create_teams():
# 创建三支队伍
# 战士队 - 血厚攻高防高
soldier1 = Warrior("盾战", 300, 80, 25, 50, 0.1)
soldier2 = Warrior("狂战", 280, 100, 15, 60, 0.2)
soldier3 = Warrior("枪兵", 250, 90, 20, 70, 0.15)
team_war = Team("钢铁战士队", [soldier1, soldier2, soldier3])
# 法师队 - 控制爆发
mage1 = Mage("火法", 180, 130, 10, 70, 0.25)
mage2 = Mage("冰法", 200, 120, 8, 65, 0.2)
mage3 = Mage("雷法", 170, 150, 5, 80, 0.3)
team_mage = Team("奥术议会队", [mage1, mage2, mage3])
# 刺客队 - 脆皮极速
assassin1 = Assassin("暗刃", 150, 100, 5, 95, 0.45)
assassin2 = Assassin("影袭", 160, 90, 5, 100, 0.5)
assassin3 = Assassin("夜行者", 140, 110, 5, 90, 0.4)
team_assassin = Team("暗影猎手队", [assassin1, assassin2, assassin3])
return [team_war, team_mage, team_assassin]
def simulate_tournament():
teams = create_teams()
print("="*60)
print(" 🏆 模拟大赛正式开始 🏆")
print("="*60)
for team in teams:
print(f" 🎖 队伍: {team.name} | 成员: {', '.join(h.name for h in team.heroes)}")
print()
# 循环赛:每两队打一场,三局两胜?这里简单一场定胜负,但为了公平每场打3次取积分
team_names = [t.name for t in teams]
matches = list(itertools.combinations(range(3), 2))
# 每个对阵打一场(循环赛 3场)
for match_idx, (i, j) in enumerate(matches):
team_a = teams[i]
team_b = teams[j]
print(f"\n--- 对阵 {match_idx+1}: {team_a.name} VS {team_b.name} ---")
# 这里每场进行3局,胜场多者得3分,平局则各1分(无平,实际不会平)
# 我们改为单场,但是为了模拟更真实,多局取分
points_a = 0
points_b = 0
for game in range(1, 4): # 三局
winner, loser, log = battle_phase(team_a, team_b)
# 计算净胜(剩下的总血量比)
a_hp = sum(h.hp for h in team_a.heroes)
b_hp = sum(h.hp for h in team_b.heroes)
diff = a_hp - b_hp # 可能是负
if winner is team_a:
points_a += 1
print(f" 第{game}局: {team_a.name} 胜 (剩余血量 {a_hp} vs {b_hp})")
else:
points_b += 1
print(f" 第{game}局: {team_b.name} 胜 (剩余血量 {a_hp} vs {b_hp})")
# 更新积分(总分)
if points_a > points_b:
leading = team_a
elif points_b > points_a:
leading = team_b
# 结算分数(3局2胜)
if points_a >= 2:
team_a.points += 3
print(f" >>> 最终胜者: {team_a.name}")
else:
team_b.points += 3
print(f" >>> 最终胜者: {team_b.name}")
print("\n" + "="*60)
print(" 战绩统计")
print("="*60)
# 计算净胜分(用胜场差简单代替)
# 为了好玩,这里看所有对局小分
results = sorted(teams, key=lambda t: t.points, reverse=True)
for rank, team in enumerate(results, 1):
print(f"{rank}位 🥇 : {team.name} |积分: {team.points}")
champion = max(teams, key=lambda t: t.points)
print("\n" + "*"*60)
print(f" 🎉 最终的冠军是: {champion.name} 🎉")
print("*"*60)
# 冠军额外奖励
for h in champion.heroes:
print(f" 🏅 {h.name} 荣誉登场!")
# 运行模拟(因为随机性,结果会变化,想固定可加 random.seed(42))
if __name__ == "__main__":
# random.seed(1) # 取消注释固定随机种子看固定结果
simulate_tournament()
运行结果解析(预测)
由于引入了随机性(暴击、技能触发、目标选择),每次运行结果可能不同,但从属性数据上看:
- 战士队:血厚、防高,容错率高。
- 法师队:攻击力高,但非常脆,技能是AOE,但单体爆发可能不足。
- 刺客队:速度极快(几乎总是先手),暴击率极高(50%左右),伤害非常恐怖,由于速度快,可能先秒杀敌方输出。
“哪队能笑到最后?” 答案通常在刺客队或法师队之间(取决于刺客的暴击是否触发),如果刺客连续打出暴击,基本上三回合内能秒掉对方主力,而战士队更稳定,但输出可能略显不足,面对高爆发队伍时容易陷入困境。
你可以多次运行这个程序,看看统计上哪支队伍的赢面更大😊
如何调整?
- 修改
Hero的初始属性(HP/攻击/速度等)来调整队伍平衡。 - 修改
battle_phase中的技能触发概率(4)来让技能更容易释放。 - 想固定比赛结果,在
__main__中调用random.seed(某数字)即可。
(小建议:如果想让真正的“综合”,可以加入文件读取(如英雄名单存CSV)、画图(matplotlib显示胜率),但核心逻辑已在这几百行里体现了。)
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播