WorldSimulation / Character.py
yingqianjiang-lingoace
update
0a0d866
raw
history blame
11.8 kB
import random
import math
from utils import get_random_name, get_random_clan_name
from config import P_DIE_WHEN_LOSE, IMMORTAL_RANK
cultivation_rank_map = ["炼气期", "筑基期", "结丹期", "元婴期", "化神期", "成仙者"]
class Character:
def __init__(self, name, gender, special_constitution, spiritual_roots, clan=None, partner=None, parents=None):
self.name = name
self.gender = gender
self.real_age = 0
self.apparent_age = 0
self.cultivation_level = 0 # 等级
self.cultivation_rank = 0 # 层次
self.special_constitution = special_constitution
self.spiritual_roots = spiritual_roots
self.experience_points = 0
self.combat_power = self.calculate_combat_power()
self.partner = partner
self.is_alive = True
self.is_immortal = False
self.buff = False
self.history = []
self.special_history = []
self.consume_spiritual_energy = 0
self.parents = parents
self.children = []
self.clan = clan # 宗族
def die(self):
if self.is_alive and not self.is_immortal:
self.history.append(f"{self.real_age}岁,死亡")
self.special_history.append(f"{self.real_age}岁,死亡")
self.is_alive = False
def cultivate(self, experience_points):
if not self.is_alive:
print("角色已经死亡,无法进行修炼。")
return
# 成仙者不再修炼
if self.is_immortal:
return
self.experience_points += experience_points
# 根据经验值计算等级,等级越高,升级需要的经验值就越多
self.cultivation_level = math.floor(self.experience_points / ((1 + self.cultivation_rank) * 1000 + (1 + self.cultivation_level) * 100))
# 判断是否达到突破修为层次的条件
if self.cultivation_level >= 10:
# 使用一个随机数来表示突破的概率,当前rank越高,则突破成功的概率越低
success_probability = 0.9 / (self.cultivation_rank * 2 + 1)
if random.random() < success_probability:
cultivation_level = self.cultivation_level
self.cultivation_rank += 1
self.cultivation_level = 0
self.experience_points = 0
self.history.append(f"{self.real_age}岁,突破成功,在{cultivation_level}级, 到达{self.view_rank()}")
self.special_history.append(f"{self.real_age}岁,突破成功,在{cultivation_level}级, 到达{self.view_rank()}")
# 判断是否达到成仙的条件
if self.cultivation_rank >= IMMORTAL_RANK:
self.is_immortal = True
self.history.append(f"{self.real_age}岁,成仙了")
self.special_history.append(f"{self.real_age}岁,成仙了")
else:
self.history.append(f"{self.real_age}岁,突破失败,在{self.cultivation_level}级")
def marry(self, partner):
# 成仙者不再结婚
if self.is_immortal:
return
if not self.is_alive:
print("角色已经死亡,无法结婚。")
return
self.partner = partner
partner.partner = self
# 结婚合并宗族
if self.clan and partner.clan:
if random.random() < 0.5:
partner.clan = self.clan
else:
self.clan = partner.clan
else:
self.clan = self.clan or partner.clan or get_random_clan_name()
partner.clan = self.clan
self.history.append(f"{self.real_age}岁,结婚了")
self.partner.history.append(f"{self.partner.real_age}岁,结婚了")
self.special_history.append(f"{self.real_age}岁,结婚了")
self.partner.special_history.append(f"{self.partner.real_age}岁,结婚了")
def give_birth(self):
# 成仙者不会生育
if self.is_immortal:
return
if not self.is_alive:
print("角色已经死亡,无法生育。")
return
if not self.partner:
print("角色没有结婚,无法生育。")
return
# 合欢体质加buff
if self.special_constitution[1] == 1:
self.buff = True
# 小孩有一定几率遗传父亲或母亲的特殊体质和灵根
special_constitution = [a if random.random() < 0.5 else b for (a, b) in zip(self.special_constitution, self.partner.special_constitution)]
spiritual_roots = [a if random.random() < 0.5 else b for (a, b) in zip(self.spiritual_roots, self.partner.spiritual_roots)]
# spiritual_roots 一定几率突变
spiritual_roots = [random.choice([0, 1]) if random.random() < 0.01 else v for v in spiritual_roots]
child = Character(get_random_name(), random.choice(["男", "女"]), special_constitution, spiritual_roots, clan=self.clan, parents=[self, self.partner])
self.history.append(f"{self.real_age}岁,生下小孩{child.name}")
self.partner.history.append(f"{self.partner.real_age}岁,生下小孩{child.name}")
self.children.append(child)
self.partner.children.append(child)
return child
def grow(self):
# 成仙者不会衰老
if self.is_immortal:
return
self.real_age += 1
# 根据修为层次 和 是否拥有木灵根 计算表观年龄
# 修为层次越高,外表看起来越年轻
ratio = 1 + self.cultivation_rank
# 灵龟和蜉蝣体质
if self.special_constitution[2] == 1: # 灵龟体质
ratio *= 2
elif self.special_constitution[3] == 1: # 蜉蝣体质
ratio *= 0.5
# 根据修为层次计算加成比例,初始加成为10%
bonus = 0.1 * (self.cultivation_rank * 0 + 1)
if self.spiritual_roots[1] == 1: # 拥有木灵根(灵根的第二位),最大寿命有加成
ratio *= 1 + bonus
self.apparent_age = math.floor(self.real_age / ratio)
def calculate_combat_power(self):
# 根据修为层次和修为等级计算战斗力参数:等级越高,各数值都越高;层次对等级是碾压效果
attack_power = (self.cultivation_rank + 1) * 30 + 1 * (1 + self.cultivation_level)
defense_power = (self.cultivation_rank + 1) * 30 + 1 * (1 + self.cultivation_level)
attack_speed = (self.cultivation_rank + 1) * 30 + 1 * (1 + self.cultivation_level)
health_points = (self.cultivation_rank + 1) * 90 + 3 * (1 + self.cultivation_level)
# 根据修为层次计算加成比例,初始加成为10%
bonus = 0.1 * (self.cultivation_rank * 0 + 1)
# 根据灵根调整战斗力参数,灵根分别为:[金木水火土], 分别对以下属性有加成:攻击速度, 最大寿命, 生命值, 攻击力, 防御力
if self.spiritual_roots[0] == 1: # 金
attack_speed *= 1 + bonus
if self.spiritual_roots[2] == 1: # 水
health_points *= 1 + bonus
if self.spiritual_roots[3] == 1: # 火
attack_power *= 1 + bonus
if self.spiritual_roots[4] == 1: # 土
defense_power *= 1 + bonus
return {
'attack_power': math.ceil(attack_power),
'defense_power': math.ceil(defense_power),
'attack_speed': math.ceil(attack_speed),
'health_points': math.ceil(health_points),
}
def before_battle(self):
self.combat_power = self.calculate_combat_power()
def attack(self, opponent, params={"P_CRIT": 0.2, "P_DODGE": 0.05, "P_BLOCK": 0.1, "P_COUNTER": 0.05}):
# 成仙者不会打架
if self.is_immortal:
return
if not self.is_alive:
print("角色已经死亡,无法攻击。")
return
# 战斗体质加buff
if self.special_constitution[0] == 1:
self.buff = True
# 根据攻击速度计算攻击次数
attack_times = math.ceil(self.combat_power['attack_speed'] / 10)
# 根据攻击力计算伤害
damage = self.combat_power['attack_power'] * attack_times
# 根据防御力计算伤害减免
damage -= opponent.combat_power['defense_power']
# 伤害最小为1
damage = max(1, damage)
# 根据概率计算暴击
if random.random() < params['P_CRIT']:
damage *= 2
print("暴击!")
# 根据概率计算闪避
if random.random() < params['P_DODGE']:
print("闪避!")
return
# 根据概率计算格挡
if random.random() < params['P_BLOCK']:
print("格挡!")
damage = max(1, damage // 2)
# 根据概率计算反击
if random.random() < params['P_COUNTER']:
print("反击!")
damage = max(1, damage // 2)
opponent.combat_power['health_points'] -= damage
return
if damage > 0:
opponent.combat_power['health_points'] -= damage
def check_is_alive(self):
if self.combat_power['health_points'] <= 0:
# 一定概率会死亡
if random.random() < P_DIE_WHEN_LOSE:
self.die()
return False
return True
def __str__(self):
# Display current attributes
history = "\n".join(self.history)
attributes = [
f"名字: {self.name}",
f"性别: {self.gender}",
f"年龄: {self.real_age}",
f"表观年龄: {self.apparent_age}",
f"修仙阶段: ({self.cultivation_rank}){self.view_rank()}",
f"特殊体质: {[special_constitution for (special_constitution, is_active) in zip(['战斗体质', '合欢体质', '灵龟体质', '蜉蝣体质'], self.special_constitution) if is_active]}",
f"灵根: {[spiritual_root for (spiritual_root, is_active) in zip(['金', '木', '水', '火', '土'], self.spiritual_roots) if is_active]}",
f"伴侣: {self.partner.name if self.partner is not None else '无'}",
f"存活: {self.is_alive}",
f"宗族: {self.clan if self.clan is not None else '无'}",
f"父母: {[parent.name for parent in self.parents] if self.parents is not None else '无'}",
f"孩子: {[child.name for child in self.children]}",
f"Combat Power: {self.combat_power}",
f"Experience Points: {self.experience_points}",
f"Buff: {self.buff}",
f"历程: {history}",
]
return "\n".join(attributes)
def view_rank(self):
if self.cultivation_rank <= len(cultivation_rank_map):
return f"{cultivation_rank_map[self.cultivation_rank]}({self.cultivation_level})"
else:
return "天外飞仙"
def to_list(self):
numerical_attributes = [
self.real_age,
self.apparent_age,
self.cultivation_level,
self.cultivation_rank,
self.experience_points,
self.combat_power["attack_power"],
self.combat_power["defense_power"],
self.combat_power["attack_speed"],
self.combat_power["health_points"],
*self.special_constitution, # [1, 0, 0, 0], 数组解构拼接
*self.spiritual_roots, # [1, 0, 0, 0, 0], 数组解构拼接
1 if self.is_alive else 0, # bool转int
1 if self.buff else 0, # bool转int
len(self.children),
]
return numerical_attributes