I'm a tutor that is helping one of my students with a simple guessing game program. It's supposed to be similar to the board game Mastermind. This program should prompt the user to enter 5 distinct digits, and it should return the how many digits are correct and how many are in the right position. It does all of this, but it's not returning the correct values. I must have one of my loops messed up when the program is calculating these two numbers. If my spidey senses are correct, then I think the problem is in the numRight(x) function and the rightPosition(y) function. Any feedback would be lovely.

import random

def randomNumGenerator():
    ## this function constructs the five digit string that the
    ## user has to guess correctly.
    concStr = '' ## accumulator for string concatenation
    sequence = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] ## list of ints
    random.shuffle(sequence) ## shuffles the list
    numToGuess = random.sample(sequence, 5) ## shortens the list to 5 elements
    for i in range(5):
        ## this loop concatenates the list of ints into a single string
        new = numToGuess.pop() ## gets the last element from the list
        newStr = str(new) ## converts the element to a string
        concStr += newStr ## concatenates 
    return concStr  

def numRight(x):
    rightCount = 0 ## counter for how many numbers are right
    randNums = list(randomNumGenerator()) ## need list for loop
    userNums = list(x) ## need list for loop
    for userNum in userNums:
        ## this loop takes an element from the userNums list
        ## and checks to see if it is the same as any of the
        ## other elements in the randNums list.  It will return
        ## how many numbers the user guessed correctly.
        for randNum in randNums:
            if(userNum == randNum):
                rightCount = rightCount + 1 ## counter
    return(rightCount)

def rightPosition(y):
    posCount = 0
    randPos = list(randomNumGenerator()) ## need list for loop
    userPos = list(y) ## need list for loop
    for u in userPos:
        ## this loop compares the positions of the elements in each list.
        ## if the lists have the same value at any position, then the
        ## counter is incremented.
        ## @return posCount numbers at correct positions
        ## @precondition elements in each list must be distinct
        for r in randPos:
            if(u == r):
                if(userPos.index(u) == randPos.index(r)):
                    posCount = posCount + 1 ## counter
    return(posCount)

def userGuess():
    ## this function simply gets the user's guess
    guess = input("Enter your guess (5 distinct numbers): ") ## gets input from user
    guessStr = str(guess) ## safety precaution, converts guess to a string
    return guess

def mastermind(maxGuesses):
    tryToGuessMe = randomNumGenerator()
    for guess in range(maxGuesses):
        aGuess = userGuess()
        ##print(aGuess)
        aRightNum = numRight(aGuess)
        ##print(aRightNum)
        aRightPos = rightPosition(aGuess)
        ##print(aRightPos)
        print("You have", aRightNum, "numbers out of 5 correct.")
        print("You have", aRightPos, "numbers in the right place.")
        if aRightNum == 5:
            if aRightPos == 5:
                print("You win!")
                break
    print("Sorry, you lose.")

mastermind(20)

Recommended Answers

All 3 Replies

You call randomNumGenerator() twice, once in each of the two functions and so are working with two different values (althought it is possible to return the same value twice). If you are going to tutor then you should try to follow the Python Style Guide and stop using the half-camelCase naming convention.

Also, in this code

   for u in userPos:
       for r in randPos:
           if(u == r):
               if(userPos.index(u) == randPos.index(r)):
                    posCount = posCount + 1

index will only find the first letter's position so if you have multiples of the same letter it will not work as expected. In addition

for u in userPos:
       for r in randPos:
           if(u == r):

will compare "u" to every postion in randPos, so if there is only one "2" in userPos and 2 in randPos it will report two postions that are the same which is not true. You want to compare the first postions of both strings/lists, then the second postion of both, etc. Finally, why do you convert to a string in randomNumGenerator() and then convert it back to it's original form, a list, in the functions?

Why you are using random module but reimplement the random.sample?

>>> import random
>>> import string
>>> print random.sample(string.digits, 5)
['6', '2', '5', '1', '8']

Also the commenting is very superfluous.

Thank you for the help. I'm used to coding in Java, which explains the camel case. The reason for having so many comments is that I couldn't make it to my tutoring session; so, I had to e-mail the student my code. We got this problem solved. I'll mark it up.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.