Reputation: 422
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
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