我是 python 的新手,我需要编写一个“公牛和奶牛”游戏(又名 Mastermind) 它是这样的:
一开始你有 2 个输入; 1 代表 secret 的长度(可以是 4-6),第二个代表 secret 的长度(可以是 6-10)。 你可以假设 secret 和猜测都具有给定的长度(你不需要确定) 稍后,您还有另外 2 个输入。 1 代表 secret (一串由空格分隔的数字),第二个代表基数(一串由空格分隔的数字)。 如果 secret 的数字等于或超过基数,程序将输出错误并退出。
举例说明:
5 (First input, length should be 5)
8 (The base. It means that no number is allowed to be 8 or beyond. You are only allowed to use 0,1,2,3,4,5,6,7)
1 2 7 2 5 (this is the secret)
7 2 2 1 1 (this is the guess)
输出:
1 BULLS 3 COWS
另一个例子:
6
9
0 0 0 0 0 6
8 22 2 2 1 4
输出:
0 BULLS 0 COWS
好的,所以我开始编写代码,但我不确定我应该使用什么,所以到目前为止我这样做了:
#get the length of the guess - an int number between 4(included) to 6(included)
secretL = input()
#get the base of the guess - an int number between 6(included) to 10(included)
secretB = input()
#get the guess
secret = raw_input()
secretsNumbers = map(int, secret.split())
#turn the chain into a singular INT number in order to make sure each of its digits does not equal or exceeds base, using %10
secretsNumbersMerge = int(''.join(map(str,secretsNumbers)))
newSecretsNumbersMerge = secretsNumbersMerge
while newSecretsNumbersMerge!= 0:
checker = newSecretsNumbersMerge%10
if checker<secretBase:
newSecretsNumbersMerge = newSecretsNumbersMerge/10
else:
print ("ERROR")
quit()
guess = raw_input()
guessNumbers = map(int, guess.split())
到目前为止一切都很好。这确实确保 secret 满足基本要求。现在我正处于检查公牛和母牛的主要位置,但我不太确定如何从这一点开始。
我的想法是先检查公牛,然后将它们移除(这样它就不会与奶牛混在一起),然后检查奶牛,但是是的..我一无所知。
我什至不确定在 Python 中使用什么。
提前致谢!
最佳答案
这是您的代码,但请尝试理解其中的每一行:
import re
from collections import Counter
#get the length of the guess - an int number between 4(included) to 6(included)
secretL = input()
#get the base of the guess - an int number between 6(included) to 10(included)
secretB = input()
#get the guess
secret = raw_input()
# Check if the secret input uses a digit greater than the base value
# You can use the check on the next line as well. It can be made faster
# too by using search in place of findall.
# if len(re.findall(r"[^0-" + str(secretB) + r" ]+", secret)):
if sum((i!=" " and int(i) > secretB) for i in secret) > 0:
print("Error")
quit()
secretNumbers = map(int, secret.split())
guess = raw_input()
guessNumbers = map(int, guess.split())
# Count the bulls by iterating over the two lists simultaneously
bulls = sum(i==j for i, j in zip(secretNumbers, guessNumbers))
# Remove the bulls before counting the cows
secretNumbers, guessNumbers = zip(*((x,y) for x,y in zip(secretNumbers, guessNumbers) if x!=y))
# Cows are defined as the elements present in both the guess and the secret
# but not in the right position.
# If we ignore duplicates, this is the way to go about it.
cows = len(set(secretNumbers) & set(guessNumbers))
## If we count [1,1,2,4] and [5,3,1,1] to have 2 cows, this is how it should be:
#counter = Counter(secretNumbers) & Counter(guessNumbers)
#cows = sum(counter.itervalues())
print(str(bulls) + " BULLS " + str(cows) + " COWS")
如果有什么不清楚的地方,请告诉我,我会添加解释。
另外,我不知道mastermind的规则,是从你的描述中推断出来的。对于第二个例子,我不清楚你是如何得到 0 头奶牛的。
更新 1
if sum(i > secretB for i in secretNumbers) > 0:
how does it work exactly?
请在评论、问题或答案中使用反引号 (`) 来引用小段代码。现在,让我们将这段代码分解成易于理解的部分:
- 考虑列表理解
[ i > secretB for i in secretNumbers]
。这将生成一个 bool 值列表。因此,如果您的基数是 6 并且 secretNumbers 是[1,2,7,2,5]
,它将返回[False, False, True, False, False]
. (根据您的评论,这不是规则的解释方式,但我很确定您可以根据需要修改此条件。) - sum()是 Python 中一个非常有用的标准内置函数,它返回传递给它的任何可迭代对象的总和。因此,
sum([1,2,3,4])
将返回 10。 - 还有待回答对 bool 值列表求和是什么意思。以这种方式将
True
添加到True
最初可能看起来很奇怪,但我不认为它是 unpythonic;毕竟,bool
is a subclass自 2.3 以来所有版本中的int
:
_
>>>issubclass(bool, int)
True
所以,你去吧:sum(i > secretB for i in secretNumbers)
告诉你输入中有多少数字超过基数。
更新 2:
经过 OP 的澄清,更新 1 的解释不再适用于正在讨论的代码,尽管 OP 现在理解使用列表推导来做强大事情的一般技术。
此外,计算 COWS 的条件已经明确,代码现在列出了两种方法 - 一种是忽略重复项;另一种是忽略重复项。其次是计算每个重复的实例。
关于python - Python 中的 Bulls & Cows(策划者)。应该比较容易,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20006944/