You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mastermind类猜数字游戏代码问题:红/白校验逻辑异常问询

解决Mastermind猜数字游戏中Whitecheck统计错误的问题

嘿,我来帮你搞定这个恼人的统计bug!你遇到的问题本质是校验顺序搞反了——原代码先统计数字对但位置错的情况,之后才处理位置和数字都对的情况,导致已经匹配正确位置的数字被错误计入whitecheck。比如你说的例子:答案是1234,猜测是4234,原代码先检查位置1的4,发现它在答案里但位置不对,就先加了whitecheck,之后处理位置4的4时,虽然标记了checklist,但已经没法把之前加的whitecheck减回去了。

正确的校验逻辑应该这么走

要彻底解决这个问题,得把校验顺序反过来:

  • 第一步:先统计所有redcheck(位置和数字都正确),同时把这些已经匹配的数字标记出来,避免后续重复统计。
  • 第二步:再统计whitecheck(数字正确但位置错误),这时候要排除已经被redcheck匹配的数字,还要保证答案里的每个数字只能被匹配一次。

优化后的代码实现

你的修改思路是对的——分离red和white的校验顺序,但我们可以把代码写得更简洁通用,比如用列表标记已匹配的数字,避免一堆重复的if语句:

import random

# 生成不重复的4位数字密码(范围1-4)
code = []
while len(code) != 4:
    n = random.randint(1, 4)
    if n not in code:
        code.append(n)
answer = ''.join(str(num) for num in code)
attempts = 3

print(f"调试用:生成的密码是 {answer}")

while attempts > 0:
    # 简化输入:让用户直接输入连续的4位数字
    guess = input("请输入4个1-4的数字(直接连输,比如1234):").strip()
    
    # 输入合法性校验
    if len(guess) != 4 or not guess.isdigit() or any(int(c) not in range(1, 5) for c in guess):
        print("喂,得输入合法的4位1-4数字哦!")
        continue

    redcheck = 0
    whitecheck = 0
    # 把答案和猜测转成列表,方便标记已匹配的数字
    answer_copy = list(answer)
    guess_copy = list(guess)

    # 第一步:统计redcheck,标记已匹配的位置
    for i in range(4):
        if guess_copy[i] == answer_copy[i]:
            redcheck += 1
            # 用特殊字符标记,避免后续重复统计
            answer_copy[i] = 'X'
            guess_copy[i] = 'X'

    # 第二步:统计whitecheck,跳过已标记的位置
    for i in range(4):
        if guess_copy[i] != 'X' and guess_copy[i] in answer_copy:
            whitecheck += 1
            # 找到答案中对应的数字并标记,防止重复匹配
            match_idx = answer_copy.index(guess_copy[i])
            answer_copy[match_idx] = 'X'
            guess_copy[i] = 'X'

    print(f"你输入的是:{guess}")
    if guess == answer:
        print(f"🎉 太棒了!你破解了密码!")
        print(f"正确位置且数字正确:{redcheck} 个")
        print(f"数字正确但位置错误:{whitecheck} 个")
        break
    else:
        attempts -= 1
        print(f"❌ 不对哦,还有 {attempts} 次机会。")
        print(f"正确位置且数字正确:{redcheck} 个")
        print(f"数字正确但位置错误:{whitecheck} 个")

if attempts == 0:
    print(f"😔 很遗憾,你输了,正确密码是:{answer}")

代码为啥这么写?

  1. 输入更友好:让用户直接输入连续数字,比逐个输入位置方便多了,还加了输入校验,防止乱输。
  2. 标记法避免重复统计:用X标记已经匹配的数字,不管是red还是white,每个数字只会被统计一次,完美解决了你之前的bug。比如测试答案1234、猜测4234的情况:
    • 第一步统计redcheck:位置2、3、4的数字都匹配,redcheck=3,这三个位置被标记成X。
    • 第二步统计whitecheck:猜测的位置1是4,但答案里的4已经被标记成X了,所以不会计入whitecheck,最终whitecheck=0,完全符合预期。
  3. 扩展性强:哪怕以后你想改成允许密码里有重复数字,这个逻辑也能直接用,不用大改。

对你修改方案的小补充

你之前分离red和white校验顺序的思路完全正确,但原修改代码里的checklist逻辑在处理重复数字时会有问题(不过你的游戏现在是生成不重复数字,所以暂时没暴露),而用标记列表的方法更通用,能覆盖所有情况。

内容的提问来源于stack exchange,提问作者Pythonnoob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:41:30