user2782067
user2782067

Reputation: 422

Mastermind solver guessing problems

I need to write a mastermind solver, with 4 letter codes with letters A to F. However, my guess eliminator is leaving guesses which should have been eliminated. Here is my guess eliminator code:

def getFeedback(self, feedbackStr): 
    if guesscount == 1:
        import itertools #i know this shouldnt be here but homework comes with limitations
        global guesslist
        guesslist=list("".join(k) for k in itertools.product('ABCDEF', repeat=4))        
    guess_score=feedbackStr
    for i in guesslist:
        i_score=computeFeedback(guess, i)#compares possible code to current guess
        if i_score != guess_score: #remove all non matching guesses
            guesslist.remove(i) 
    return guesslist

and here is the computerFeedback code:

def computeFeedback(code,guess):
    # Given a code and guess computes the feedback string

    b = 0
    w = 0
    inCodeCount = {'A':0,'B':0,'C':0,'D':0, 'E':0, 'F':0}
    inGuessCount = {'A':0,'B':0,'C':0,'D':0, 'E':0, 'F':0}
    for i in range(0,4):
        if code[i] == guess [i]:
            b += 1
        inCodeCount[code[i]] += 1
        inGuessCount[guess[i]] += 1
    for ch in inCodeCount:
        w += min(inCodeCount [ch], inGuessCount [ch])
    w -= b 
    feedback = str(w)+'w'+str(b)+'b'
    return feedback

however, when code = BBAA and the first guess is AABB, for example, guesslist is ['BBAA', 'CCAE', 'DDBC', 'EECA', 'FFCE'] my program should eliminate everything except for BBAA, but it is not. It eliminated 1290/1295 wrong guesses, but some incorrect guesses always seem to slip through.

The rouge wrong guesses will always be the same depending on the code inputted.

i've gone through it line by line, and, for example,

  computeFeedback('BBAA','AABB')  <----- this is my guess vs the code

  '4w0b' 
 computeFeedback('AABB','DDBC')   <----- this is my guess vs a
  possible code.

 '0w1b' 

 computeFeedback('AABB','CCAE') 
'1w0b'
  computeFeedback('AABB','EECA') 
 '1w0b' 
 computeFeedback('AABB','FFCE')
 '0w0b'

none of the feedback strings match, so they should have been eliminated. i apologize if this is too specific of a question, but i cant figure out why this would happen.

Upvotes: 2

Views: 1180

Answers (1)

Michael0x2a
Michael0x2a

Reputation: 64068

Your problem is with the getFeedback function.

I suspect that because you're simultaneously iterating over and yet modifying a list at the same time, your code is acting wonky. If I change it to a more functional style (so that instead of modifying lists, it constantly returns a new one), it works as expected.

(Note: I removed some of the code from within getFeedback since it made testing a little difficult. You said you had unusual constraints, so you may need change it to add in the guesslist generation code back in. It would be cleaner to make it a separate function, but I suppose that's tangential.)

import itertools

def generateInitialGuesslist():
    return list("".join(k) for k in itertools.product('ABCDEF', repeat=4))

def getFeedback(guess, feedbackStr, guess_list):
    guess_score = feedbackStr
    new_guess_list = []
    for candidate in guess_list:
        candidate_score = computeFeedback(guess, candidate)
        if candidate_score == guess_score:        #remove all non matching guesses
            new_guess_list.append(candidate)
    return new_guess_list

def computeFeedback(code,guess):
    # Given a code and guess computes the feedback string

    b = 0
    w = 0
    inCodeCount = {'A':0,'B':0,'C':0,'D':0, 'E':0, 'F':0}
    inGuessCount = {'A':0,'B':0,'C':0,'D':0, 'E':0, 'F':0}
    for i in range(0,4):
        if code[i] == guess [i]:
            b += 1
        inCodeCount[code[i]] += 1
        inGuessCount[guess[i]] += 1
    for ch in inCodeCount:
        w += min(inCodeCount [ch], inGuessCount [ch])
    w -= b 
    feedback = str(w)+'w'+str(b)+'b'
    return feedback

guesslist = generateInitialGuesslist()
guesslist = getFeedback('AABB', '1w1b', guesslist)
print guesslist
print len(guesslist)

I tested this by starting with AABB as a guess and ABCD as the correct answer. Your code states that the there are 208 guesses remaining using 1w1b as feedback, which is identical to what my own mastermind solver says.

Upvotes: 2

Related Questions