开发者

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()
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜