算法与Python 知识量:10 - 40 - 100
猜词游戏的玩法是这样的:一个人写下几个数字让另外一人猜,当每次答题方猜完之后,出题方会给答题方一个提示,告诉他刚才的猜测中有多少位数字和确切位置都猜对了(称为“Bulls”,公牛),还有多少位数字猜对了但是位置不对(称为“Cows”,奶牛)。答题方将会根据出题方的提示继续猜,直到猜出秘密数字为止。
这是一个经典的数字猜测游戏,通常被称为“牛和奶牛”游戏。以下提供一个基本的Python实现,玩家可以猜测数字,并根据提示进行更新。
首先,定义一个函数来计算公牛和奶牛的数量:
def count_bulls_and_cows(secret, guess): bulls = 0 cows = 0 secret_digits = set(str(secret)) guess_digits = set(str(guess)) for digit in secret_digits: if digit in guess_digits: bulls += 1 secret_digits.remove(digit) guess_digits.remove(digit) for digit in guess_digits: if digit in secret_digits: cows += 1 guess_digits.remove(digit) secret_digits.remove(digit) return bulls, cows
接下来,可以实现游戏的逻辑:
def game(): secret = input("请输入一个四位数的秘密数字:") while len(set(str(secret))) != 4: # 检查是否是四位数 secret = input("请重新输入一个四位数的秘密数字:") while True: guess = input("请猜一个数字:") bulls, cows = count_bulls_and_cows(secret, guess) print(f"公牛:{bulls},奶牛:{cows}") if bulls == 4: # 如果全部数字都猜对了,结束游戏 print("恭喜,猜对了!") break elif cows == 4: # 如果所有数字位置都猜错了,重新开始 print("很遗憾,全部猜错了。请重新开始。") game() else: # 否则继续猜数字 print("请继续猜数字。")
现在,可以运行game()函数来开始游戏。玩家将输入一个四位数作为秘密数字,然后开始猜测数字。每次猜测后,程序将告诉玩家有多少位数字完全正确(公牛)和有多少位数字位置不正确(奶牛)。如果玩家猜测的数字全部正确,程序将恭喜玩家并结束游戏。如果玩家猜测的数字全部不正确,程序将告诉玩家并重新开始游戏。
要使用哈希表(在Python中通常使用字典实现)来解决“公牛和奶牛”游戏的问题,需要一个方法来跟踪猜测中哪些数字是正确的,并且是在正确的位置上(公牛),以及哪些数字是正确的但位置不正确(奶牛)。
下面是一个使用哈希表的Python实现:
def count_bulls_and_cows(secret, guess): if len(secret) != len(guess) or not secret.isdigit() or not guess.isdigit(): raise ValueError("Secret and guess must be of equal length and consist of digits only.") bulls = 0 # 公牛数 cow_dict = {} # 用来计算奶牛的哈希表,存储猜测中每个数字出现的次数 for s, g in zip(secret, guess): if s == g: bulls += 1 elif g in cow_dict: cow_dict[g] += 1 else: cow_dict[g] = 1 cows = 0 # 奶牛数 for s in secret: if s in cow_dict and cow_dict[s] > 0: cows += 1 cow_dict[s] -= 1 # 已经计算过的奶牛数需要减去 return bulls, cows def game(): secret = input("请输入一个四位数的秘密数字:") while len(secret) != 4 or not secret.isdigit(): # 检查是否是四位数且只包含数字 secret = input("请重新输入一个四位数的秘密数字:") while True: guess = input("请猜一个四位数:") while len(guess) != 4 or not guess.isdigit(): # 检查猜测是否是四位数且只包含数字 guess = input("请重新输入一个四位数:") bulls, cows = count_bulls_and_cows(secret, guess) print(f"公牛:{bulls},奶牛:{cows}") if bulls == 4: # 如果公牛数为4,则猜对了 print("恭喜,你猜对了!") break
上述实现中的count_bulls_and_cows函数在计算奶牛数时有一个问题:它可能会错误地计算那些既是公牛又是奶牛的数字。为了解决这个问题,需要稍微调整算法,确保在计算奶牛之前排除掉公牛。下面是修正后的实现:
def count_bulls_and_cows(secret, guess): if len(secret) != len(guess) or not secret.isdigit() or not guess.isdigit(): raise ValueError("Secret and guess must be of equal length and consist of digits only.") bulls = 0 # 公牛数 cows = 0 # 奶牛数 secret_counts = {} # 存储秘密数字中每个数字出现的次数 guess_counts = {} # 存储猜测中每个数字出现的次数(不考虑位置) # 统计秘密数字和猜测中每个数字的出现次数 for s, g in zip(secret, guess): if s == g: # 公牛,数字和位置都匹配 bulls += 1 else: # 更新数字的出现次数(奶牛候选) secret_counts[s] = secret_counts.get(s, 0) + 1 guess_counts[g] = guess_counts.get(g, 0) + 1 # 计算奶牛数(只考虑那些位置不匹配的数字) for digit, count in guess_counts.items(): cows += min(count, secret_counts.get(digit, 0)) # 取两个计数的最小值作为匹配的奶牛数 cows -= bulls # 从总奶牛数中减去公牛数,因为公牛已经被计算过了 return bulls, cows if cows >= 0 else 0 # 确保奶牛数不会为负数(理论上不应该发生,但作为一个安全措施)
现在,count_bulls_and_cows函数应该能够正确地计算公牛和奶牛的数量了。可以调用game()函数来开始游戏。
Copyright © 2017-Now pnotes.cn. All Rights Reserved.
编程学习笔记 保留所有权利
MARK:3.0.0.20240214.P35
From 2017.2.6