This time we are going to implement a simple yet fun guessing game called „Cows and Bulls”.
“Cows and Bulls” is a word or number puzzle game where one player, the codemaker, selects a secret code composed of four unique digits, while the other player, the codebreaker, attempts to guess it. After each guess, the codemaker provides feedback in the form of ‘cows’ and ‘bulls.’ A ‘cow’ signifies a correct digit in the right position, while a ‘bull’ represents a correct digit in the wrong position. The codebreaker continues making guesses and receiving feedback until they correctly guess the secret code (four cows) or decide to give up.
The challenge of the game lies in using the feedback provided by cows and bulls to deduce the correct sequence of the secret code. It’s a fun and engaging game of deduction and logic.
If you need to refresh your knowledge, follow the link below. 👇👇👇
Solution
Let’s start by reiterating the game rules:
The codemaker selects a secret code, which is usually a sequence of four digits (e.g., 1 - 9), with no repeating digits.
💡 Example: The sequence of „1234”.
The codebreaker makes guesses, also four-digit numbers, trying to figure out the secret code.
After each guess, the codemaker provides feedback in the form of “cows” and “bulls”. Here’s what these terms mean:
“Cow” is used to represent a correct digit in the correct position.
💡 Example: If the secret code is “1234” and the guess is “1538,” there is 1 cow because “1” is in the correct position.
“Bull” is used to represent a correct digit in the wrong position.
💡 Example: If the secret code is “1234” and the guess is “5671,” there are 2 bulls (for “1” and “4”) because they appear in the secret code but in the wrong positions.
The codebreaker continues making guesses and receiving feedback until they guess the exact secret code (four cows) or decide to give up.
We can assume that the computer is going to be a codemaker while we are going to be a codebreaker. We have to start with selecting the secret code, so let's write a function for that. We want to generate the secret at random, so we will import the random module.
import random
def generate_secret_number() -> str:
return str(random.randint(1000, 9999))
The provided imports the random
module and defines a function called generate_secret_number()
, which, when invoked, returns a random 4-digit number as a string. This function utilizes random.randint(1000, 9999)
to generate a random integer between 1000 and 9999 (inclusive), and then it converts that integer into a string before returning it.
Now let's write a function that compares the guess with the secret number.
from typing import Tuple
def compare_numbers(secret: str, guess: str) -> Tuple[int, int]:
cows: int = 0
bulls: int = 0
for i in range(4):
if guess[i] == secret[i]:
bulls += 1
elif guess[i] in secret:
cows += 1
return cows, bulls
The above code defines a function called compare_numbers
, which takes two string arguments, secret
and guess
, and returns a tuple of two integers. The function initializes two integer variables, cows
and bulls
, both set to zero and then iterates through the characters or digits in the secret
and guess
strings. It compares these characters or digits at each position, incrementing the bulls
count when a correct digit is in the correct place and the cows
count when a correct digit is in the wrong place. Finally, it returns a tuple with the counts of cows and bulls. The type hint with Tuple[int, int]
clarifies the expected return type and aids in type checking.
Now let's write the main loop.
def main():
secret_number: str = generate_secret_number()
attempts: int = 0
while True:
guess: str = input("Enter a 4-digit number: ")
if len(guess) != 4 or not guess.isdigit():
print("Please enter a valid 4-digit number.")
continue
attempts += 1
cows, bulls = compare_numbers(secret_number, guess)
if bulls == 4:
print(f'Congratulations! You guessed the secret number {secret_number} in {attempts} attempts.')
break
else:
print(f'Cows: {cows}, Bulls: {bulls}')
The provided code defines a main()
function that is the heart of the "Cows and Bulls" guessing game. It initializes variables for a random 4-digit secret_number
and an attempts
counter. The game enters a loop where the player inputs 4-digit numbers, validates the input and keeps track of the number of attempts. It uses the compare_numbers(secret_number, guess)
function to assess the correctness of each guess, distinguishing between "cows" (correct digits in the wrong position) and "bulls" (correct digits in the correct position). The game continues until the player correctly guesses the secret number (4 bulls), at which point it displays a congratulatory message with the number of attempts made. If not, it provides feedback on the cows and bulls in the guess, creating an interactive and engaging "Cows and Bulls" guessing game experience.
Let's wrap it up.
import random
from typing import Tuple
def generate_secret_number() -> str:
return str(random.randint(1000, 9999))
def compare_numbers(secret: str, guess: str) -> Tuple[int, int]:
cows: int = 0
bulls: int = 0
for i in range(4):
if guess[i] == secret[i]:
bulls += 1
elif guess[i] in secret:
cows += 1
return cows, bulls
def main():
secret_number: str = generate_secret_number()
attempts: int = 0
while True:
guess: str = input("Enter a 4-digit number: ")
if len(guess) != 4 or not guess.isdigit():
print("Please enter a valid 4-digit number.")
continue
attempts += 1
cows, bulls = compare_numbers(secret_number, guess)
if bulls == 4:
print(f'Congratulations! You guessed the secret number {secret_number} in {attempts} attempts.')
break
else:
print(f'Cows: {cows}, Bulls: {bulls}')
if __name__ == "__main__":
main()
Now we are ready to play it!
❯ python3 main.py
Enter a 4-digit number: 3762
Cows: 2, Bulls: 1
Enter a 4-digit number: 3826
Congratulations! You guessed the secret number 3826 in 2 attempts.
Really nice game... But I used the debugger to find out the number anyway. 😂
Summary
The "Cows and Bulls" game is an engaging number puzzle that challenges players to decipher a secret code by making educated guesses and interpreting feedback in the form of cows and bulls. The objective is to deduce the correct sequence of digits through deductive reasoning and logical thinking. This classic game provides an enjoyable exercise in problem-solving and strategy and is often played for fun or as a brain teaser. The game concludes with the player's satisfaction upon successfully unraveling the mystery of the secret code, providing a sense of accomplishment and intellectual challenge.