实现普通牌获取决策函数(纯函数)

任务:实现普通牌获取决策函数(纯函数)

一、背景概述

在《极妙幻境》游戏中,每层共有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(即本函数内部不修改任何外部变量)。
    """
    # 你的实现代码

三、算法逻辑(必须遵循)

请严格按照以下步骤实现:

  1. 检查是否已达上限
    如果 cards_obtained >= max_cards,则本轮不可能再获得牌,直接返回 False

  2. 计算剩余轮次和剩余需求

    • 剩余轮次 = total_rounds - current_round(注意:剩余轮次不包括本轮,例如总20轮,当前第20轮,剩余轮次=0)
    • 还需牌数 = max_cards - cards_obtained
  3. 强制获得判断
    如果 还需牌数 > 剩余轮次 + 1,说明即使后面每一轮都获得牌也无法达到 max_cards(因为未来轮次不够),那么本轮必须获得牌,返回 True
    例如:总20轮,当前第18轮,已获15张,还需5张,剩余轮次=2,还需5 > 2+1=3,满足条件,返回True。

  4. 概率获得判断
    否则,计算获得牌的概率:
    概率 = 还需牌数 / (剩余轮次 + 1)
    生成一个 [0,1) 的随机小数,如果随机数 < 概率,则返回 True,否则 False
    注意:当剩余轮次+1 = 0(即当前为最后一轮且还需牌数=0)时,概率应为0,直接返回False(但这种情况已被步骤1处理)。

  5. 随机性要求
    使用 random.random() 生成随机数。为了测试可复现,你可以在函数内部不设置种子,但测试用例中可以通过 import random; random.seed(42) 来控制。

四、注意事项

  • 纯函数原则:函数内部不得修改任何输入参数或外部状态。所有计算仅基于参数。
  • 边界情况:确保 current_round1total_rounds 之间,max_cardstotal_rounds。如果输入非法,可以自行决定是否抛出异常或按合理逻辑处理(如返回False),但建议假设输入合法。
  • 浮点精度:概率计算时直接使用除法,Python的浮点数足够,无需特殊处理。
  • 随机性:必须使用 random.random(),不要使用 random.randint 等。

五、测试用例

请编写单元测试(建议使用 unittestpytest)验证函数的正确性。至少包含以下测试:

测试用例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 函数及所有测试。
  • 代码需包含必要的注释。
  • 确保测试通过,并展示测试结果。

开始实现吧!如有疑问,随时提出。

posted @ 2026-03-15 12:36  神秘园欢迎您  阅读(10)  评论(0)    收藏  举报