Search code examples
pythonindex-error

Python: Cows and Bulls game


I am writing a code fora game which randomly generates a 4-digit number. Ask the user to guess a 4-digit number. For every digit that the user guessed correctly in the correct place, they have a “cow”. For every digit the user guessed correctly in the wrong place is a “bull.” Every time the user makes a guess, tell them how many “cows” and “bulls” they have. Once the user guesses the correct number, the game is over. Keep track of the number of guesses the user makes throughout the game and tell the user at the end.

The code is below.

import random

rand=[random.randint(0,9) for n in range(3)]


user_guess=[input("Please guess 4-digit number: ")]

def game():
    count=0
    while True:
        guess=[i for i in rand]
        listnum=[i for i in user_guess]

        if guess == listnum:
            print("You won.")
            print("It took you "+str(count)+" guess.")
            break

        if guess != listnum:
            cow=0
            bull=0
            count+=1
            for x in range(0,3):
                if guess[x]==listnum[x]:
                    cow+=1

        if len(set(guess)&set(listnum))>num:
            bull=len(set(guess)&set(listnum)) - cow

        print("Cows: "+str(cow)+' Bulls: '+str(bull))

game()

But I am getting the following error after it asks the user to guess the number and takes the input. The error is given below.

Please guess 4-digit number: 1234

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-48-64a0b0d4d766> in <module>()
     41         print("Cows: "+str(cow)+' Bulls: '+str(bull))
     42 
---> 43 game()
     44 
     45 

<ipython-input-48-64a0b0d4d766> in game()
     33             count+=1
     34             for x in range(0,3):
---> 35                 if guess[x]==listnum[x]:
     36                     cow+=1
     37 

IndexError: list index out of range

What mistake am I making here?


Solution

  • Your definition of when a digit is a bull is a little bit unclear. Let's say your solution key is e.g. [1, 8, 5, 8] and your guess 8888. The number 8 is present multiple times in the solution key. So you have 2 cows. But what is your expected output for bulls in this case? One possible solution (see below) would be to check if each guessed number is present anywhere in the solution key (even though it might already be a cow).

    The solution below includes some of the remarks already mentioned by others (see post by @Bill M.).

    Possible solution:

    import random
    
    def game(num_digits):
        # generate list of random integers of length num_digits
        listnum = [random.randint(0,9) for n in range(num_digits)]
        print("Solution key = " + str(listnum))
    
        count=0
        while True:
            count+=1
            print("~~~ Guess: " + str(count) + " ~~~")
    
            print("Please guess " + str(num_digits) + "-digit number: ")
            # transform input string (e.g. "1234") to list of integers (e.g. [1,2,3,4])
            guess = [int(i) for i in str(input())]
    
            if guess == listnum:
                print("You won.")
                print("It took you "+str(count)+" guess(es).")
                break
    
            else:
                cow=0
                bull=0
    
                for x in range(0,num_digits):
                    if guess[x]==listnum[x]:
                        cow += 1
                    elif guess[x] in listnum: # look if digit is somewhere else in the solution key (might already be a cow)
                        bull += 1
    
            print("Cows: "+str(cow)+" Bulls: "+str(bull))
            print("++++++++++++++++")
    
    game(4)
    

    Example output:

    Solution key = [1, 8, 5, 8]
    ~~~ Guess: 1 ~~~
    Please guess 4-digit number:
    2288
    Cows: 1 Bulls: 1
    ++++++++++++++++
    ~~~ Guess: 2 ~~~
    Please guess 4-digit number:
    8888
    Cows: 2 Bulls: 2
    ++++++++++++++++
    ~~~ Guess: 3 ~~~
    Please guess 4-digit number:
    1858
    You won.
    It took you 3 guess(es).