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)
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:
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 "You guessed the key: {0}".format(self.target)
print "It took you {0} guesses".format(turn)
else:
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()