# Bulls and cows

Play the game with students as a class, explaining the rules.

The problem
The computer will generate a hidden number exactly 4 digits long. No digits are allowed to be repeated so 1458 is valid but 9902 is invalid. The number must not begin with 0. The game should display the rules and aim of the game at the start. The player has 10 attempts to guess the hidden number. They must only use digits from 0 to 9. When the guess has been made, the computer will work out and display how many 'bulls' and how many 'cows' the player guessed. A bull is a correct digit in the correct position. A cow is a correct digit but in an incorrect position. For example, assuming the hidden number is 4561:

• The player guesses 1234. This is 0 bulls and 2 cows.
• They then guess 7518. This is 1 bull and 1 cow.
• They then guess 4610. This is 1 bull and 2 cows, and so on.

The player has to use the information to make better informed guesses. They have only 10 attempts to guess the number, or they lose.

There are lots of different approaches to a solution. Ours is undoubtedly not the most effiecient. On the other hand, we hope it can be understood by most students when they come to look at it. Students need to plan out very carefully what they are going to do before starting to code. They should get one small part working and fully tested before moving on to the next part. Students should be encouraged to print off values at key points when they are testing things. They should by encouraged to use type to confirm what data type they are working with. Students need to be clear at all times whether they are working with a string or an integer when using digits.

The whole game will take most students at least three or four hours to plan, write and fully test and it makes use of lots of excellent programming techniques. The use of a Python validator will help students develop each individual function, as well as the whole program. Weaker students should be given one function at a time to develop, and more help with the pseudo-code for each function.

Overview of our solution

import random
set some global variables to store the hidden number and the guess
function to get a hidden number
function to validate the hidden number, checking for no duplicated digits
function for the player's guess
function to ensure the player's guess follows all the rules
function to work out the bulls and cows
function to display the welcome screen
main() to keep track of attempts and play the game

Pseudo-code

import random
set variables = ''

def actual()
get a number between 1000 and 9999
convert it to a string
validate it
return the number

def validate_actual(actual_num)
for i in actual_num:
if actual_num.count(i) != 1
return False
return True

def guess
input a guess from the player
while (the guess is invalid)
input a guess from the player
return the guess

def validate_guess
return True if the guess is valid and False if not

def bulls_and_cows(actual number, the_guess)
set bull counter and cow counter = 0
for i in range (4):
if actual_num[i] == the_guess[i]
bull_counter += 1

for i in range (4):
for j in range (4)
if actual_num[i] == the_guess[j]
counter_cows += 1

return counter_bulls, counter_cows - counter_bulls

def welcome()
print the welcome message and simple rules

def main()
attempts = 0
while (attempts <10) and (actual_num != the_guess)
print attempt number
get the guess
print the bulls and cows
increment attempt

if attempts < 10
print well done message
else
print 'unlucky' message and display the hidden number

welcome()
actual()
main()

Solution

Extension
Students need to test the code thoroughly. Because of the use of random numbers, they need to use a series of stubs and forced data values to test all the permutations. Students could investigate how to turn the game into a game for two players rather than playing against the computer. How could the game be made easier or harder to play? Students could investigate this and give a player the option of playing an easy game, or medium one or a harder one. Students could look at dealing with guesses or the hidden value that include duplicate digits. Why is this a problem as the code stands? What could be done about it?