题目重点:题目逐步追加 52 张牌、洗牌、Player.draw、空牌堆与谁决定继续抽牌;用接口和状态转移回答。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练版标准 52 张牌,4 种花色×13 点数,无 Joker;只设计抽牌流程,不假称题目要求 split、保险、庄家软 17 等规则。
- 洗牌算法并 q12;Game 统一控制发牌回合,Player 可提供 hit/stand 意图,Deck 是唯一牌源。
解题路线
- Card 为不可变 value object;Deck 持有未发牌列表与 nextIndex,shuffle 只在新轮开始或显式重置时执行。
- Player 持有 hand 与决策接口,draw 不自行制造 Card,而调用 Deck.draw;空牌堆返回明确错误/None,不能静默生成新牌。
- Game 持有 Deck、Players、turn 和状态机:开始→发初始牌→轮到玩家→hit/stand→结算;Game 验证行动合法性并决定何时轮换。
- 将‘是否继续抽’拆成策略和执行:人类/AI player 决定意图,Game 依据规则和牌堆状态批准/执行;若题面只需单 Player,可先交简单接口再扩展。
- 以不变量测试 52 张牌唯一、抽出的牌不会回到未发集合、牌堆用尽不能再抽、回合外不能抽。
手动走一遍
Deck 余 1 张,当前玩家提出 hit,Game 检查回合合法后从 Deck 取牌入 Player.hand;下一次 hit 因 Deck 空返回异常/游戏结束信号。玩家意图和游戏规则由不同对象负责。
规模与取舍
建牌 O(52),洗牌 O(52),单次 draw O(1);推广到 D 副牌则建牌/洗牌 O(D),牌组空间 O(D)。状态机规模随规则分支增长。
易错点与追问
容易失分的边界
- Player 自己维护牌堆导致多玩家抽到重复牌。
- Deck 空时越界。
- 把选择 hit 的策略与回合执行完全混在一个类。
- 没有测试洗牌之后牌的唯一性。
- 臆造题目没说的完整 Blackjack 规则。
继续深挖
- 谁决定继续抽牌?
- 多人并发行动如何保证同一张牌只发一次?
- 新一轮如何重置/洗牌?
- 加入 AI 策略该放在哪层?
