How to solve the “Mastermind” guessing game?

后端 未结 10 451
有刺的猬
有刺的猬 2020-12-04 07:42

How would you create an algorithm to solve the following puzzle, \"Mastermind\"?

Your opponent has chosen four different colours from a set of six (yellow, blue, gre

10条回答
  •  情歌与酒
    2020-12-04 08:36

    Here's a link to pure Python solver for Mastermind(tm): http://code.activestate.com/recipes/496907-mastermind-style-code-breaking/ It has a simple version, a way to experiment with various guessing strategies, performance measurement, and an optional C accelerator.

    The core of the recipe is short and sweet:

    import random
    from itertools import izip, imap
    
    digits = 4
    fmt = '%0' + str(digits) + 'd'
    searchspace = tuple([tuple(map(int,fmt % i)) for i in range(0,10**digits)])
    
    def compare(a, b, imap=imap, sum=sum, izip=izip, min=min):
        count1 = [0] * 10
        count2 = [0] * 10
        strikes = 0
        for dig1, dig2 in izip(a,b):
            if dig1 == dig2:
                strikes += 1
            count1[dig1] += 1
            count2[dig2] += 1
        balls = sum(imap(min, count1, count2)) - strikes
        return (strikes, balls)
    
    def rungame(target, strategy, verbose=True, maxtries=15):
        possibles = list(searchspace)
        for i in xrange(maxtries):
            g = strategy(i, possibles)
            if verbose:
                print "Out of %7d possibilities.  I'll guess %r" % (len(possibles), g),
            score = compare(g, target)
            if verbose:
                print ' ---> ', score
            if score[0] == digits:
                if verbose:
                    print "That's it.  After %d tries, I won." % (i+1,)
                break
            possibles = [n for n in possibles if compare(g, n) == score]
        return i+1
    
    def strategy_allrand(i, possibles):
        return random.choice(possibles)
    
    if __name__ == '__main__':
        hidden_code = random.choice(searchspace)
        rungame(hidden_code, strategy_allrand)
    

    Here is what the output looks like:

    Out of   10000 possibilities.  I'll guess (6, 4, 0, 9)  --->  (1, 0)
    Out of    1372 possibilities.  I'll guess (7, 4, 5, 8)  --->  (1, 1)
    Out of     204 possibilities.  I'll guess (1, 4, 2, 7)  --->  (2, 1)
    Out of      11 possibilities.  I'll guess (1, 4, 7, 1)  --->  (3, 0)
    Out of       2 possibilities.  I'll guess (1, 4, 7, 4)  --->  (4, 0)
    That's it.  After 5 tries, I won.
    

提交回复
热议问题