diff --git a/src/classes/sect.py b/src/classes/sect.py index 72c9651..3d2daf4 100644 --- a/src/classes/sect.py +++ b/src/classes/sect.py @@ -38,6 +38,8 @@ class Sect: headquarter: SectHeadQuarter # 本宗关联的功法名称(来自 technique.csv 的 sect 列) technique_names: list[str] + # 随机选择宗门时使用的权重(默认1) + weight: float = 1.0 # 功法:在technique.csv中配置 # TODO:法宝 # TODO:宗内等级和称谓 @@ -80,6 +82,10 @@ def _load_sects() -> tuple[dict[int, Sect], dict[str, Sect]]: if str(tname).strip() ] + # 读取权重(缺省/NaN 则为 1.0) + weight_val = row.get("weight", 1) + weight = float(str(weight_val)) if str(weight_val) != "nan" else 1.0 + sect = Sect( id=int(row["id"]), name=str(row["name"]), @@ -96,6 +102,7 @@ def _load_sects() -> tuple[dict[int, Sect], dict[str, Sect]]: image=image_path, ), technique_names=technique_names, + weight=weight, ) sects_by_id[sect.id] = sect sects_by_name[sect.name] = sect diff --git a/src/run/run.py b/src/run/run.py index 15902a3..6a54c00 100644 --- a/src/run/run.py +++ b/src/run/run.py @@ -2,7 +2,7 @@ import random import asyncio import sys import os -from typing import List, Tuple, Dict, Any +from typing import List, Tuple, Dict, Any, Sequence, Optional # 添加项目根目录到Python路径 sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) @@ -46,25 +46,43 @@ def random_gender() -> Gender: return Gender.MALE if random.random() < 0.5 else Gender.FEMALE -def make_avatars(world: World, count: int = 12, current_month_stamp: MonthStamp = MonthStamp(100 * 12)) -> dict[str, Avatar]: +def sample_existed_sects(all_sects: Sequence, max_sects: int) -> list: + """ + 按权重无放回抽样本局启用的宗门;当权重和为0时退回均匀无放回抽样。 + 返回长度不超过 max_sects。 + """ + if max_sects <= 0 or not all_sects: + return [] + k = min(max_sects, len(all_sects)) + pool = list(all_sects) + base_weights = [max(0.0, s.weight) for s in pool] + if sum(base_weights) <= 0: + random.shuffle(pool) + return pool[:k] + result: list = [] + for _ in range(k): + weights = [max(0.0, s.weight) for s in pool] + chosen = random.choices(pool, weights=weights, k=1)[0] + result.append(chosen) + pool.remove(chosen) + return result + +def make_avatars(world: World, count: int = 12, current_month_stamp: MonthStamp = MonthStamp(100 * 12), existed_sects: Optional[List] = None) -> dict[str, Avatar]: avatars: dict[str, Avatar] = {} width, height = world.map.width, world.map.height # 依据配置决定宗门人数占比:当 init_npc_num > sect_num 时启用宗门逻辑 num_total = int(count) - max_sects = int(getattr(CONFIG.game, "sect_num", 0) or 0) - use_sects = num_total > max_sects and max_sects > 0 + use_sects = bool(existed_sects) # 约 2/3 为宗门弟子,1/3 为散修 sect_member_target = int(num_total * 2 / 3) if use_sects else 0 - # 随机抽取启用的宗门列表 - enabled_sects = list(sects_by_id.values()) - random.shuffle(enabled_sects) - enabled_sects = enabled_sects[:max_sects] if use_sects else [] - # 在地图上添加启用宗门的总部(仅显示名称与描述) - if enabled_sects: - add_sect_headquarters(world.map, enabled_sects) - # 循环均匀分配宗门成员(轮询宗门) - sect_assign_index = 0 + # 本局启用的宗门(已在上方确定) + # 在地图上添加本局宗门总部 + if existed_sects: + add_sect_headquarters(world.map, existed_sects) + # 按权重分配宗门成员 sect_member_count = 0 + # 先得到存在的宗门(已在上方计算) + for i in range(count): # 随机生成年龄,范围从16到60岁 age_years = random.randint(16, 60) @@ -73,9 +91,13 @@ def make_avatars(world: World, count: int = 12, current_month_stamp: MonthStamp gender = random_gender() # 分配宗门或散修 assigned_sect = None - if use_sects and sect_member_count < sect_member_target and enabled_sects: - assigned_sect = enabled_sects[sect_assign_index % len(enabled_sects)] - sect_assign_index += 1 + if use_sects and sect_member_count < sect_member_target and existed_sects: + # 使用已启用宗门按权重抽样;若权重之和不大于0则退回均匀随机 + weights = [max(0.0, s.weight) for s in existed_sects] + if sum(weights) > 0: + assigned_sect = random.choices(existed_sects, weights=weights, k=1)[0] + else: + assigned_sect = random.choice(existed_sects) sect_member_count += 1 # 根据宗门生成姓名 name = get_random_name_for_sect(gender, assigned_sect) @@ -149,9 +171,15 @@ async def main(): # 创建模拟器 sim = Simulator(world) + + # 得到本局的宗门 + all_sects = list(sects_by_id.values()) + max_sects = int(getattr(CONFIG.game, "sect_num", 0) or 0) + existed_sects = sample_existed_sects(all_sects, max_sects) # 创建角色,传入当前年份确保年龄与生日匹配,使用配置文件中的NPC数量 - world.avatar_manager.avatars.update(make_avatars(world, count=CONFIG.game.init_npc_num, current_month_stamp=world.month_stamp)) + all_avatars = make_avatars(world, count=CONFIG.game.init_npc_num, current_month_stamp=world.month_stamp, existed_sects=existed_sects) + world.avatar_manager.avatars.update(all_avatars) front = Front( simulator=sim, diff --git a/static/game_configs/sect.csv b/static/game_configs/sect.csv index f9847d4..e5ea4f7 100644 --- a/static/game_configs/sect.csv +++ b/static/game_configs/sect.csv @@ -1,11 +1,11 @@ -id,name,desc,member_act_style,alignment,sect_surnames,male_sect_given_names,female_sect_given_names -,,宗门名称与描述,宗门成员行事风格,阵营(正/中/邪),宗门常用姓氏(分号分隔),男性常用名(分号分隔),女性常用名(分号分隔) -1,明心剑宗,通玄界东方第一宗,以无上剑道称雄于世。云纹禁制为不传心法。,清明克己,行止如一。重剑与心法并重,讲究明心见性。,正,明;灵;清,阁;松;德;吉;和;澜;彦;珣;智;海;泉,如;玑;碧;清霁;素心;明珑;玄音;澄如;玉衡 -2,百兽宗,以驯养灵兽闻名,豢养各种妖兽灵怪为战力。,你言语直接,重视力量与血性,崇尚狩猎与搏斗。,邪,,驼王;飞熊;虎魄;狼行;熊罡;白猿;石坚;山岚;青鬃;玄爪,狐绮;白貂;青翎;雪牙;赤羽;玄狸;灵爪;月狐 -3,水镜宗,正道十宗之一,实则严守中立。拥有仙界异宝"彻天水镜"可预知未来。,你处事冷静圆融,喜以柔克刚,擅借力与反制。,中,水;镜;颜;玉;寒;霜;冰;清;沐;阮,岚;照心;寒江,水月;映月;寒影;秋水;轻漪;雪落;如镜;青荷;凝霜 -4,冥王宗,行走幽冥之道,术法阴冷狠厉。,你言辞冷厉少情,敬畏因果而不惧杀伐,偏向效率与结果。,邪,宋;元;冥;王;玄;幽;夜;白;江;冷,元敕;元难;元烁;冥焰;噬魂;夜阙;幽垣;玄骨;寒魄;冥狱;影灭;夜行,冥霜;幽绫;夜珑;寒鸢;阎铃;魇瑶;玄魄;幽棂 -5,朱勾宗,邪宗大派。以炼器、机关、暗杀闻名于世,素来阴毒冷僻。,你直面欲望与代价,不惧黑暗,以攻伐见长。,邪,朱;血;狱;百;,血手;勾魂;朱砂;赤狱;凝血;摄魄;夺心;吞灵;渊渟;夜烬,朱绫;夜鸢;绯刃;寒簪;明玥;凝芒;血莹;玉珥 -6,合欢宗,以情入道,双修与魅术并重,善驭人心,长于权变。,你辞令婉转,善于拿捏人欲与局势,以柔制刚。,中,合;欢;苏;陆;柳;花;月;楚;顾;白,流烟,婉心;轻柔;疏影;如梦;绮念;月华;惜香;慕雪;倾城 -7,镇魂宗,铁血风格,擅安魂、封邪、渡厄,兼有刚烈镇压之术。,你肃穆沉稳,重安魂镇邪,少言而果决。,正,厉;卢;镇;魂;钟;青;凌;白;楚;顾,斗量;阳;镇灵;定魄;钟离;安魂;肃霜;白岭;清钟;涤秽;正鸣;宁川,清宁;素铃;靖霜;澄心;灵钟;镇月;安祈;涤魂 -8,幽魂噬影宗,镇宗典籍《幽冥录》。幽明气为根基。,你行事隐秘果断,重结果轻虚名,擅潜行与出其不意。,邪,冥;阎;鬼;百;幽;归;应;阴;碧;夜,璃;无藏;馑;噬影;隐魄;夜藏;无相;玄影;摄魂;遁形;寒星;绝响;空痕,采儿;幽姝;冥绮;寒灯;影绫;夜绡;魇歌;暗萝 -9,千帆城,炼器大宗,巧匠云集。著名法宝有灵灭丝、定魂蓝星、天罗网、万里极光壁、飞翼等。商旅云集,自成体系。,你务实精明,重交易与信誉,崇尚规则与秩序。,中,商;楚;顾;白;苏;林;叶;秦;赵;魏,商行;持衡;清评;问价;立契;通衡;问道;理市;衡准;守约,素蓝;明衡;巧心;青帆;绫舟;观星;衡绫;星槎 +id,name,desc,member_act_style,alignment,sect_surnames,male_sect_given_names,female_sect_given_names,weight +,,宗门名称与描述,宗门成员行事风格,阵营(正/中/邪),宗门常用姓氏(分号分隔),男性常用名(分号分隔),女性常用名(分号分隔),权重(默认1) +1,明心剑宗,通玄界东方第一宗,以无上剑道称雄于世。云纹禁制为不传心法。,清明克己,行止如一。重剑与心法并重,讲究明心见性。,正,明;灵;清,阁;松;德;吉;和;澜;彦;珣;智;海;泉,如;玑;碧;清霁;素心;明珑;玄音;澄如;玉衡,1 +2,百兽宗,以驯养灵兽闻名,豢养各种妖兽灵怪为战力。,你言语直接,重视力量与血性,崇尚狩猎与搏斗。,邪,,驼王;飞熊;虎魄;狼行;熊罡;白猿;石坚;山岚;青鬃;玄爪,狐绮;白貂;青翎;雪牙;赤羽;玄狸;灵爪;月狐,1 +3,水镜宗,正道十宗之一,实则严守中立。拥有仙界异宝"彻天水镜"可预知未来。,你处事冷静圆融,喜以柔克刚,擅借力与反制。,中,水;镜;颜;玉;寒;霜;冰;清;沐;阮,岚;照心;寒江,水月;映月;寒影;秋水;轻漪;雪落;如镜;青荷;凝霜,1 +4,冥王宗,行走幽冥之道,术法阴冷狠厉。,你言辞冷厉少情,敬畏因果而不惧杀伐,偏向效率与结果。,邪,宋;元;冥;王;玄;幽;夜;白;江;冷,元敕;元难;元烁;冥焰;噬魂;夜阙;幽垣;玄骨;寒魄;冥狱;影灭;夜行,冥霜;幽绫;夜珑;寒鸢;阎铃;魇瑶;玄魄;幽棂,1 +5,朱勾宗,邪宗大派。以炼器、机关、暗杀闻名于世,素来阴毒冷僻。,你直面欲望与代价,不惧黑暗,以攻伐见长。,邪,朱;血;狱;百;,血手;勾魂;朱砂;赤狱;凝血;摄魄;夺心;吞灵;渊渟;夜烬,朱绫;夜鸢;绯刃;寒簪;明玥;凝芒;血莹;玉珥,1 +6,合欢宗,以情入道,双修与魅术并重,善驭人心,长于权变。,你辞令婉转,善于拿捏人欲与局势,以柔制刚。,中,合;欢;苏;陆;柳;花;月;楚;顾;白,流烟,婉心;轻柔;疏影;如梦;绮念;月华;惜香;慕雪;倾城,1 +7,镇魂宗,铁血风格,擅安魂、封邪、渡厄,兼有刚烈镇压之术。,你肃穆沉稳,重安魂镇邪,少言而果决。,正,厉;卢;镇;魂;钟;青;凌;白;楚;顾,斗量;阳;镇灵;定魄;钟离;安魂;肃霜;白岭;清钟;涤秽;正鸣;宁川,清宁;素铃;靖霜;澄心;灵钟;镇月;安祈;涤魂,1 +8,幽魂噬影宗,镇宗典籍《幽冥录》。幽明气为根基。,你行事隐秘果断,重结果轻虚名,擅潜行与出其不意。,邪,冥;阎;鬼;百;幽;归;应;阴;碧;夜,璃;无藏;馑;噬影;隐魄;夜藏;无相;玄影;摄魂;遁形;寒星;绝响;空痕,采儿;幽姝;冥绮;寒灯;影绫;夜绡;魇歌;暗萝,1 +9,千帆城,炼器大宗,巧匠云集。著名法宝有灵灭丝、定魂蓝星、天罗网、万里极光壁、飞翼等。商旅云集,自成体系。,你务实精明,重交易与信誉,崇尚规则与秩序。,中,商;楚;顾;白;苏;林;叶;秦;赵;魏,商行;持衡;清评;问价;立契;通衡;问道;理市;衡准;守约,素蓝;明衡;巧心;青帆;绫舟;观星;衡绫;星槎,1