Python版Mastermind游戏:高效实现可变长度的正确位置与错误位置校验方案问询
解决Mastermind游戏可变长度的位置校验问题
我完全懂你在实现这个校验逻辑时的头疼——硬编码只能撑短长度,简单循环又会重复计数。咱们来搞一个支持任意长度的高效方案,核心思路分两步走,彻底解决重复计数的问题:
正确的校验逻辑步骤
- 先算位置正确的匹配(right_spot):遍历每个索引,对比答案和猜测的对应位置数字,相同就计数加1,同时把这两个位置的数字标记为已匹配(比如用
None占位),防止后续被错误统计。 - 再算位置错误的匹配(wrong_spot):统计答案和猜测中未被标记的数字出现频率,对每个数字取两者频率的最小值,把这些最小值加起来就是错误位置的总数——这样能保证每个数字只匹配一次,不会重复计数。
实现代码
def calculate_hints(answer, line): # 转换为列表方便修改标记 answer_digits = list(str(answer)) guess_digits = list(str(line)) right_spot = 0 wrong_spot = 0 length = len(answer_digits) # 第一步:统计位置完全正确的匹配 for i in range(length): if answer_digits[i] == guess_digits[i]: right_spot += 1 # 标记为已匹配,避免后续重复计算 answer_digits[i] = None guess_digits[i] = None # 第二步:统计剩余数字的错误位置匹配 # 统计答案中剩余数字的频率 answer_counts = {} for digit in answer_digits: if digit is not None: answer_counts[digit] = answer_counts.get(digit, 0) + 1 # 统计猜测中剩余数字的频率,并计算交叉匹配数 guess_counts = {} for digit in guess_digits: if digit is not None: guess_counts[digit] = guess_counts.get(digit, 0) + 1 # 每个数字取最小出现次数累加,得到wrong_spot for digit in answer_counts: if digit in guess_counts: wrong_spot += min(answer_counts[digit], guess_counts[digit]) return right_spot, wrong_spot
测试你的示例
用你给出的场景验证:
answer = 201234,line = 202314- 第一步对比位置:索引0(2=2)、1(0=0)、5(4=4)→ right_spot=3,这三个位置被标记为
None。 - 剩余答案:
[None, None, '1', '2', '3', None],剩余猜测:[None, None, '2', '3', '1', None] - 剩余数字频率:答案里1、2、3各1个;猜测里2、3、1各1个
- 每个数字取最小次数相加:1+1+1=3 → wrong_spot=3
完全符合你预期的结果!
这个方案的优势
- 支持任意长度:不管答案是3位还是10位,逻辑直接适配,不用改代码。
- 高效低复杂度:时间复杂度是O(n),n为数字长度,比硬编码的O(n²)快得多。
- 彻底避免重复计数:通过标记已匹配位置+频率统计的方式,确保每个数字只被匹配一次,解决了你之前循环方案的核心问题。
你可以把这个函数替换掉之前的brute_force_checking,调用时传入answer和line,拿到返回的right_spot和wrong_spot后再更新你的board即可。
内容的提问来源于stack exchange,提问作者da derpy man
相关产品推荐
相关产品推荐

