带指定Epic图片保底的加权随机抽取功能实现方案咨询
满足需求的实现方案
核心逻辑
- 优先保留原有稀有度权重、同稀有度下图片随机的规则,仅通过后修正满足「指定Epic图片有且仅有1次出现」的约束
- 采用预生成+校验修正的实现路径,步骤如下:
- 按原有逻辑生成X次抽取结果
- 统计指定Epic图片的出现次数
- 根据统计结果做修正:
- 出现次数恰好为1:直接使用结果
- 出现次数为0:随机选择1次抽取结果替换为指定Epic
- 出现次数≥2:仅随机保留1次为指定Epic,其余重复出现的替换为同稀有度下其他随机图片
完整可运行代码示例
import random import os import fnmatch # 配置参数:指定要保证出现的Epic图片完整路径,自行替换为实际路径 TARGET_EPIC_IMG = "PNG/Test/Aura/Epic/target.png" # 稀有度权重配置 RARITY_WEIGHT = [ ('Common', 50), ('Uncommon', 30), ('Rare', 14), ('Legendary',5), ('Epic',1) ] # 稀有度对应的图片根目录 RARITY_BASE_PATH = "/PNG/Test/Aura/" # 原有稀有度抽取函数优化 def roll_rarity(): choices = [] for item, weight in RARITY_WEIGHT: choices.extend([item]*weight) return random.choice(choices) # 原有单张图片抽取函数优化,支持排除指定图片 def roll_single_img(exclude_img=None): rarity = roll_rarity() rarity_path = os.path.join(RARITY_BASE_PATH, rarity) # 筛选当前稀有度下的所有png图片 all_png = fnmatch.filter(os.listdir(rarity_path), '*.png') all_png = [os.path.join(RARITY_BASE_PATH, rarity, p) for p in all_png] # 排除指定图片 if exclude_img and exclude_img in all_png: all_png.remove(exclude_img) return random.choice(all_png) # 批量抽取函数,满足指定Epic恰好出现1次的约束 def batch_roll(roll_times): # 第一步:预生成所有抽取结果 roll_results = [roll_single_img() for _ in range(roll_times)] # 第二步:统计指定Epic的出现位置 target_pos = [idx for idx, img in enumerate(roll_results) if img == TARGET_EPIC_IMG] target_count = len(target_pos) # 第三步:按情况修正结果 if target_count == 1: return roll_results elif target_count == 0: # 没有出现,随机选一个位置替换为目标图片 replace_idx = random.randint(0, roll_times-1) roll_results[replace_idx] = TARGET_EPIC_IMG return roll_results else: # 出现多次,随机留1个,剩下的重新抽取 keep_idx = random.choice(target_pos) for idx in target_pos: if idx != keep_idx: roll_results[idx] = roll_single_img(exclude_img=TARGET_EPIC_IMG) return roll_results # 使用示例:抽取100次 if __name__ == "__main__": X = 100 final_results = batch_roll(X) # 验证结果 assert final_results.count(TARGET_EPIC_IMG) == 1, "指定Epic出现次数不符合要求"
补充说明
- 如果需要尽量降低对原有稀有度分布的影响,可以在
target_count=0的替换逻辑中,优先选择原本抽到Epic稀有度的结果进行替换,没有Epic结果的情况下再随机替换,进一步保证权重分布的一致性 - 若需要单次抽取时实时校验而非预生成全量结果,可以新增全局计数器记录指定Epic是否已经被抽出:如果已经抽出,后续所有抽取到Epic稀有度时都排除该图片;如果到第X-1次还没抽出,第X次强制返回该指定Epic即可
内容的提问来源于stack exchange,提问作者hustle crowe
相关产品推荐
相关产品推荐

