The game “Bulls and cows” in Python

The game "Bulls and cows" in Python

Good day to everyone. One day, while receiving additional education, the teacher decided to test the students’ knowledge and suggested writing a game “Bulls and Cows”. I wrote the game pretty quickly and even managed to make the game play itself through the built-in random library.

What is “Bulls and Cows”

This is a logic game. In the course of it, the player must, in several attempts. understand what the opponent has made up his mind (it can be numbers, symbols, words, and so on). After each attempt, the player who conceived puts up an “estimate”: how many letters / numbers / symbols are guessed without matching the positions (that is, it shows the number of “cows”) and how many are guessed exactly, along with the location (that is, it shows the number of “bulls”).

Idea

  1. Generate two different numbers.
  2. Find the number of “cows” and “bulls” in each number.
  3. Using a loop for go through the number:
    3.1 If the figure is in the list of “bulls” indices, then do not touch this figure.
    3.2 If the figure is in the list of cow indexes, then randomly change this figure with another “cow”, if any
    3.3 If the digit is neither “cow” nor “bull”, then randomly generate a new digit.
  4. Get two identical numbers.

Implementation of the game “Bulls and cows”

Creating variables and lists for further work with them. Generating unique numbers. To generate a unique number, we write a function that will check the number passed to it.

def is_valid(number):
""" Проверка числа на уникальность. Все 4 цифры числа должны быть разные """
  try:
    # переводим наше число в список из символов.
    # сравниваем с множеством.
    # (в множестве нет повторяющихся символов)
    number_list = list(str(number))
    if len(set(number_list)) == 4:
      return True
    return False
  except:
    return False
# переменные
number_guess = 0  # загаданное число
number_computer = 0  # число, которое нужно отгадать
n = 0  # кол-во попыток
# списки
n_c = []
n_b = []
# генерируем число, которое нужно отгадать
while not is_valid(number_guess):
  number_guess = random.randint(1000, 9999)
# генерируем число от которого наша программа будет отталкиваться
while not is_valid(number_computer):
  number_computer = random.randint(1000, 9999))

We are writing a function for finding “cows” and “bulls” in a number.

def check(number_guess, number_computer):
    """ Находим количество коров и быков в числе """

    # индексы коров и быков
    n_c, n_b = [], []

    try:
        # переводим наши числа в список из символов.
        number_guess_list = list(str(number_guess))
        number_computer_list = list(str(number_computer))

        # проходимся по числ
        for index in range(len(number_guess_list)):

            # если в разных числа в одинаковых
            # индексах цифры ровны,   то это бык
            if number_computer_list[index] == number_guess_list[index]:
                n_b.append(index)
            # если в числах есть одинаковые цифры, но на разных местах, то это корова
            elif number_guess_list[index] in number_computer_list:
                n_c.append(index)

        # возвращаем списки индексов коров и быков
        return n_c, n_b

    except:
        return n_c, n_b

We are writing a function that will reassemble the number from the available data.

def game(number_guess, n_c, n_b):
    """ Ф-я, пересоборки числа из имеющихся данных """

    # переводим наше число в список из символов
    number_guess_list = list(str(number_guess))

    # проходимся по списку number_guess_list
    for index in range(len(number_guess_list)):
        # если индекса цифры нет в списке индексов быков,
        # но есть в в списке коров
        if index not in n_b and index in n_c:
            # рандомным способом переставляем
            index_random = n_c[random.randint(0, len(n_c)-1)]
            number_guess_list[index], number_guess_list[index_random] = number_guess_list[index_random], number_guess_list[index]
        # если индекса цифры нет ни в одном из списков
        if index not in n_b and index not in n_c:
            number_guess_list[index] = str(random.randint(1, 9))
            while not is_valid(int(''.join(number_guess_list))):
                number_guess_list[index] = str(random.randint(1, 9))

    return int(''.join(number_guess_list))

We are writing the main cycle, which will work until there are 4 “bulls”. In this cycle, we will reassemble our number and get a new list of “cows” and “bulls” indices based on the new number.

# главный цикл, работает, пока не будет 4 быка, то есть
# два числа не будут ровны между собой

# получаем списки индексов коров и быков
n_c, n_b = check(number_guess, number_computer)

while len(n_b) != 4:
    # пересоберем число из имеющихся данных
    number_guess = game(number_guess, n_c, n_b)

    # получаем списки индексов коров и быков
    n_c, n_b = check(number_guess, number_computer)
    n += 1
    print(f"Попытка: {n}; Число: {number_guess}; Число, которое нужно отгадать: {number_computer}")

print(number_guess)

end

I hope this article was useful to you. I will be glad to read the criticism in the comments.

IOS Development Company | Python Outsourcing Company

Ready to see us in action:

More To Explore

IWanta.tech
Logo
Enable registration in settings - general
Have any project in mind?

Contact us:

small_c_popup.png