代码审查和Mastermind游戏问题

时间:2011-01-23 17:34:08

标签: python

我正在尝试自学Python并在网上找到了几个练习。其中之一是设计一个Mastermind类型的游戏here

在SO的帮助下,我已经成功完成了大部分要求,但我最后一点陷入困境。我不知道如何在每次新猜测时坚持显示先前猜测值变量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 :(得分: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观察到的那样:无论如何,旧的输入仍应显示在终端上,除非你设法以某种方式清除终端。

答案 1 :(得分: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()