代码审查与智谋游戏问题
我正在自学Python,网上找到了一些练习。其中一个是设计一个类似于“猜颜色”游戏的项目,具体内容可以在这里查看。
在StackOverflow的帮助下,我已经完成了大部分要求,但在最后一步遇到了困难。我不知道怎么才能在每次新猜测时,保持之前猜测的结果显示,也就是变量msg1
的值。
这是我目前的代码片段,欢迎大家提出意见!
def position(x, y):
position = sum(1 for a,b in zip(x ,y) if (a == b))
return position
def exists(x, y):
exists = len(set(x) & set(y))
return exists
checks = [
lambda n: (len(n)==4, "Enter 4 digits only."),
lambda n: (n.isdigit(), "Enter digits only."),
lambda n: (len(set(str(n)))==4, "Enter non duplicate numbers only.")
]
a = raw_input("Enter the 4 numbers you want to play with: ")
sturn = 1
lturn = 8 #this set the maximum number of turns
while sturn <= lturn:
b = raw_input("Enter your guess: ")
all_good = True
for check in checks:
good, msg = check(b)
if not good:
print msg
all_good = False
break
if int(b) == int(a):
print ("You guessed the key {0}! It took you {1} tries").format(a, sturn)
if sturn == lturn and int(b) != int(a):
print ("You lose. The answer was {0}").format(a)
elif int(b) != int(a) :
msg1 = ("{0}: position:{1}, exists {2}").format(b, position(a, b), (exists(a, b) - position(a, b)))
print msg1
sturn += 1
2 个回答
0
在编程中,有时候我们需要在代码里插入一些特定的内容,比如变量的值或者其他信息。为了做到这一点,我们可以使用一种叫做“字符串插值”的技术。简单来说,就是在字符串中直接放入变量,这样在运行程序时,变量的值会自动替换进去。
比如说,如果你有一个变量叫做“名字”,它的值是“张三”,那么你可以这样写:
import random class Mastermind(object): "Play the Mastermind game" def __init__(self, chars='0123456789', places=4, repeats=False, tries=12, target=None): """Set up a game @params chars: string, legal characters @param places: int, number of characters in solution @param repeats: boolean, are repeated characters are allowed in solution @param tries: int, number of attempts allowed @param target: string, solution """ super(Mastermind,self).__init__() self.chars = chars self.places = places self.repeats = repeats self.tries = tries if target is None: self.target = self.makeTarget() elif self.isValidGuess(target): self.target = target else: raise ValueError('Bad target value') if len(chars)<places and not repeats: raise ValueError('Too few unique chars') self.guesses = [] def makeTarget(self): "Generate a random target" if self.repeats: chars = [random.choice(self.chars) for i in range(self.places)] return ''.join(chars) else: chars = list(self.chars) random.shuffle(chars) return ''.join(chars[:self.places]) def validateGuess(self, guess): "Throw error if guess is invalid" msg = "****guess must have length of {0}, try again".format(self.places) if len(guess) != self.places: raise ValueError(msg) msg = "****contains characters not in '{0}', try again".format(self.chars) if not set(guess).issubset(set(self.chars)): raise ValueError(msg) msg = "****no repeated chars, try again" if self.repeats==False and len(guess)!=len(set(guess)): raise ValueError(msg) def isValidGuess(self, guess): try: self.validateGuess(guess) return (True, 'valid guess') except ValueError, e: return (False, str(e)) def getGuess(self): good = False while not good: print guess = raw_input("Guess:") good,msg = self.isValidGuess(guess) if not good: print msg for oldGuess in self.guesses: print oldGuess return guess def evaluate(self, guess): exact = sum(a==b for a,b in zip(guess, self.target)) unmatched = self.target[:] for ch in guess: unmatched = unmatched.replace(ch, '', 1) wrongpos = self.places - len(unmatched) - exact return exact,wrongpos def do_turn(self): guess = self.getGuess() exact,wrongpos = self.evaluate(guess) if exact==self.places: return True else: res = "{0}: exact:{1}, position:{2}".format(guess, exact, wrongpos) self.guesses.append(res) print res return False def play(self): turn = 0 while turn < self.tries: turn += 1 solved = self.do_turn() if solved: break if solved: print print "You guessed the key: {0}".format(self.target) print "It took you {0} guesses".format(turn) else: print print "Sorry, you didn't get it!" print "The hidden key was: {0}".format(self.target) def main(): mm = Mastermind(target=raw_input("What is the key:")) mm.play() if __name__=="__main__": main()
这样,当程序运行时,输出的结果会是“你好,张三!”。这让我们的代码看起来更整洁,也更容易理解。
1
如果你想每次都显示完整的猜测历史记录,可以把 msg1 设成一个不断增长的字符串。
msg1 = ""
...
elif int(b) != int(a):
msg1 += ("{0}: position:{1}, exists {2}\n").format(b, position(a, b), (exists(a, b) - position(a, b)))
print msg1,
...
注意,现在每条 msg 都自带换行符,所以打印的时候就不需要再加换行了。
不过,正如 Thomas K 所说:旧的输入仍然应该在终端上显示,除非你能以某种方式清除终端的内容。