Code Review and Mastermind Game Question
开发者_JAVA百科I'm trying to teach myself Python and found a couple of exercises online. One of which is to design a Mastermind type game here.
With the help of SO, I have managed most to do most of the requirements but I'm stuck at the last bit. I don't know how I can persist the display of previous guess values, variable msg1
, with each new guess.
This is my code snippet to date. Any comments are welcomed!
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
If you want to redisplay the full history of guesses every time, make msg1 a string that grows.
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,
...
Notice that each msg now carries its linebreak, so the print doesn't need to put out one anymore.
However, as Thomas K observes: the old inputs should still be displayed on the terminal, anyway, unless you manage to clear the terminal somehow.
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()
精彩评论