You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于随机生成权重的元组分组排序——TRPG先攻值生成器开发需求

TRPG先攻值生成器:同先攻值分组+随机排序解决方案

嘿,这个TRPG先攻值的需求太贴合实际场景了!我来帮你完善这个逻辑,解决分组后随机排序的问题,让你的先攻生成器完全符合规则。

首先,你的分组逻辑已经能正常工作,但可以更简洁;另外还需要补上同先攻值组内随机roll点排序的核心步骤,最后把所有组按先攻值从高到低、组内按随机数排序合并成最终列表。

完整实现代码

from itertools import groupby
from random import randint

# 初始先攻列表(可以是未排序的,代码里会先处理排序)
iniList = [('Enemy 3', 15), ('Aldare', 14), ('Enemy 2', 14), ('Enemy 5', 14), ('Enemy 1', 13), ('Enemy 4', 13)]

# 第一步:按先攻值从高到低排序(确保大的先攻值组排在前面)
sorted_ini = sorted(iniList, key=lambda x: x[1], reverse=True)

# 第二步:按先攻值分组(用itertools.groupby更简洁,前提是列表已排序)
ini_groups = []
for initiative, group in groupby(sorted_ini, key=lambda x: x[1]):
    ini_groups.append(list(group))

# 第三步:每组内生成1-6随机数模拟骰子,按随机数降序排序后合并到最终列表
final_ini_list = []
for group in ini_groups:
    # 给每个角色添加随机骰子值
    roll_results = [(randint(1, 6), char_name, ini_value) for char_name, ini_value in group]
    # 按骰子结果从大到小排序(骰子大的先行动)
    roll_results_sorted = sorted(roll_results, key=lambda x: x[0], reverse=True)
    # 去掉骰子值,保留角色和先攻值,加入最终列表
    final_ini_list.extend( (name, val) for _, name, val in roll_results_sorted )

# 输出最终先攻顺序
print("=== 最终先攻顺序 ===")
for pos, (char, ini) in enumerate(final_ini_list, 1):
    # 匹配当前角色的骰子值用于输出
    roll_val = next(r for r,n,v in roll_results if n == char)
    print(f"{pos}. {char} | 先攻值:{ini} (骰子roll点:{roll_val})")

代码解释

  1. 排序处理:先对初始列表按先攻值降序排序,确保高先攻值的组排在最前面,这是groupby能正确分组的前提(groupby只会把连续相同的元素分组)。
  2. 分组优化:用itertools.groupby替代手动循环分组,代码更简洁易读,同时也能保证分组的准确性。
  3. 随机roll点排序
    • 给组内每个角色生成1-6的随机数,模拟TRPG里的骰子roll点;
    • 按随机数降序排序,模拟“骰子大的角色先行动”的规则;
    • 去掉临时的骰子值,把角色信息合并到最终列表。

如果你不想用itertools.groupby(纯手动分组)

如果想保留手动分组的逻辑,我优化了你的原代码,解决了原代码中可能的边界问题:

from random import randint

iniList = [('Enemy 3', 15), ('Aldare', 14), ('Enemy 2', 14), ('Enemy 5', 14), ('Enemy 1', 13), ('Enemy 4', 13)]
sorted_ini = sorted(iniList, key=lambda x: x[1], reverse=True)

ini_groups = []
if sorted_ini:
    current_ini = sorted_ini[0][1]
    current_group = [sorted_ini[0]]
    # 从第二个元素开始遍历
    for item in sorted_ini[1:]:
        if item[1] == current_ini:
            current_group.append(item)
        else:
            ini_groups.append(current_group)
            current_ini = item[1]
            current_group = [item]
    # 最后别忘了把最后一组加入
    ini_groups.append(current_group)

# 后续随机排序和合并逻辑和上面一致
final_ini_list = []
for group in ini_groups:
    roll_results = [(randint(1,6), *item) for item in group]
    roll_results_sorted = sorted(roll_results, key=lambda x: x[0], reverse=True)
    final_ini_list.extend(item[1:] for item in roll_results_sorted)

print("=== 最终先攻顺序 ===")
for pos, char in enumerate(final_ini_list, 1):
    print(f"{pos}. {char[0]} (先攻值:{char[1]})")

这样处理后,你的先攻生成器就完全符合TRPG规则:高先攻值的组优先,同先攻值的角色通过随机roll点决定行动顺序,所有同先攻值的角色是“同时”参与roll点排序,而不是逐个对比。

内容的提问来源于stack exchange,提问作者PandSkin

火山引擎 最新活动