实现普通牌获取决策函数(纯函数)
任务:实现普通牌获取决策函数(纯函数)
一、背景概述
在《极妙幻境》游戏中,每层共有20轮选择,玩家通过每轮选择获得普通牌(善/恶/中立)。本模块的目标是:决定在当前轮次,玩家是否应该获得一张普通牌。最终需要保证整层下来玩家获得的总牌数不超过预设的最大值,且具有随机性和一定的可控性。
你(CodeBuddy)需要实现一个纯函数,输入四个参数,输出本轮是否获得牌的布尔值。该函数不维护内部状态,所有依赖都通过参数传递,便于单元测试和集成。
二、函数签名
def should_get_card(
total_rounds: int, # 本层总轮数(固定值,如20)
current_round: int, # 当前轮次,从1开始
cards_obtained: int, # 截止上一轮结束已经获得的牌数
max_cards: int # 本层允许获得的最大牌数(≤ total_rounds)
) -> bool:
"""
返回 True 表示本轮应获得一张普通牌,False 表示不获得。
调用方负责在获得牌后更新 cards_obtained(即本函数内部不修改任何外部变量)。
"""
# 你的实现代码
三、算法逻辑(必须遵循)
请严格按照以下步骤实现:
-
检查是否已达上限
如果cards_obtained >= max_cards,则本轮不可能再获得牌,直接返回False。 -
计算剩余轮次和剩余需求
- 剩余轮次 =
total_rounds - current_round(注意:剩余轮次不包括本轮,例如总20轮,当前第20轮,剩余轮次=0) - 还需牌数 =
max_cards - cards_obtained
- 剩余轮次 =
-
强制获得判断
如果还需牌数 > 剩余轮次 + 1,说明即使后面每一轮都获得牌也无法达到max_cards(因为未来轮次不够),那么本轮必须获得牌,返回True。
例如:总20轮,当前第18轮,已获15张,还需5张,剩余轮次=2,还需5 > 2+1=3,满足条件,返回True。 -
概率获得判断
否则,计算获得牌的概率:
概率 = 还需牌数 / (剩余轮次 + 1)
生成一个[0,1)的随机小数,如果随机数 < 概率,则返回True,否则False。
注意:当剩余轮次+1 = 0(即当前为最后一轮且还需牌数=0)时,概率应为0,直接返回False(但这种情况已被步骤1处理)。 -
随机性要求
使用random.random()生成随机数。为了测试可复现,你可以在函数内部不设置种子,但测试用例中可以通过import random; random.seed(42)来控制。
四、注意事项
- 纯函数原则:函数内部不得修改任何输入参数或外部状态。所有计算仅基于参数。
- 边界情况:确保
current_round在1到total_rounds之间,max_cards≤total_rounds。如果输入非法,可以自行决定是否抛出异常或按合理逻辑处理(如返回False),但建议假设输入合法。 - 浮点精度:概率计算时直接使用除法,Python的浮点数足够,无需特殊处理。
- 随机性:必须使用
random.random(),不要使用random.randint等。
五、测试用例
请编写单元测试(建议使用 unittest 或 pytest)验证函数的正确性。至少包含以下测试:
测试用例1:已达上限
- 输入:total_rounds=20, current_round=5, cards_obtained=10, max_cards=10
- 期望输出:False(无论如何都不能再得)
测试用例2:必须获得(剩余轮次不足)
- 输入:total_rounds=20, current_round=19, cards_obtained=18, max_cards=20
- 计算:剩余轮次=1,还需=2,2 > 1+1=2?注意此处是“大于”,2 > 2 不成立,所以不是强制。那强制的情况应是:还需=3,剩余轮次=1,3 > 2 成立。我们构造一个强制例子:total_rounds=20, current_round=19, cards_obtained=17, max_cards=20 → 还需=3,剩余轮次=1,3 > 2 → True
- 期望输出:True(必须获得)
测试用例3:概率计算正确性(统计验证)
- 设定随机种子,多次调用函数,统计获得牌的比例是否接近理论概率。
- 例如:total_rounds=20, current_round=10, cards_obtained=5, max_cards=18 → 剩余轮次=10,还需=13,概率=13/(10+1)=13/11≈1.18,但实际概率>1应取1?注意:根据强制判断,如果概率>1,应已经在步骤3中处理为强制获得。但此处还需=13,剩余轮次+1=11,13>11,所以强制获得。所以这个情况应该返回True,且无需概率计算。
- 真正的概率情况:total_rounds=20, current_round=10, cards_obtained=8, max_cards=18 → 还需=10,剩余轮次+1=11,概率=10/11≈0.909。设置种子后,执行1000次,统计True的比例应接近0.909。
测试用例4:边缘情况(最后一轮且还需为0)
- 输入:total_rounds=20, current_round=20, cards_obtained=18, max_cards=18
- 期望输出:False(已达上限)
测试用例5:最后一轮且还需为1
- 输入:total_rounds=20, current_round=20, cards_obtained=17, max_cards=18
- 计算:剩余轮次=0,还需=1,1 > 0+1?1>1不成立,所以概率=1/(0+1)=1,随机数<1必True
- 期望输出:True
六、提交要求
- 提供完整可运行的 Python 代码文件,包含
should_get_card函数及所有测试。 - 代码需包含必要的注释。
- 确保测试通过,并展示测试结果。
开始实现吧!如有疑问,随时提出。

浙公网安备 33010602011771号