Перейти к содержимому

Как сделать крестики нолики на python

  • автор:

Игра «Крестики-нолики» для двух игроков на Python

В данной статье мы разработаем небольшую консольную программу «Крестики-нолики» для закрепления темы «Функции в Python«. Сначала рекомендуем изучить теорию создания функций и потом возвращаться к этой статье.

Используемые функции в программе

draw_board() — рисует игровое поле в привычном для человека формате.
take_input() — принимает ввод пользователя. Проверяет корректность ввода.
check_win — функция проверки игрового поля, проверяет, выиграл ли игрок.

main() — основная функция игры, которая будет запускать все ранее описанные функции. Данная функция запускает и управляет игровым процессом.

Полный листинг программы
print("*" * 10, " Игра Крестики-нолики для двух игроков ", "*" * 10) board = list(range(1,10)) def draw_board(board): print("-" * 13) for i in range(3): print("|", board[0+i*3], "|", board[1+i*3], "|", board[2+i*3], "|") print("-" * 13) def take_input(player_token): valid = False while not valid: player_answer = input("Куда поставим " + player_token+"? ") try: player_answer = int(player_answer) except: print("Некорректный ввод. Вы уверены, что ввели число?") continue if player_answer >= 1 and player_answer 4: tmp = check_win(board) if tmp: print(tmp, "выиграл!") win = True break if counter == 9: print("Ничья!") break draw_board(board) main(board) input("Нажмите Enter для выхода!")
Функция draw_board()

Внутри программы игровое поле представлено в виде одномерного списка с числами от 1 до 9.

Функция take_input()

Задачи данной функции:
1. Принять ввод пользователя.

2. Обработать некорректный ввод, например, введено не число. Для преобразования строки в число используем функцию int().

3. Обработать ситуации. когда клетка занята или когда введено число не из диапазона 1..9.

Для обработки некорректного ввода мы используем блок try…except. Если пользователь введет строку, то выполнение программы не прервется, а будет выведено сообщение «Некорректный ввод. Вы уверены, что ввели число?», а затем цикл перейдет на следующую итерацию с возможностью по-новому ввести число.

Функция check_win()

Данная функция проверяет игровое поле. Мы создаем кортеж с выигрышными координатами и проходимся циклом for по нему.

Если символы во всех трех заданных клетках равны — возвращаем выигрышный символ, иначе — возвращаем значение False.

Непустая строка(выигрышный символ) при приведении ее к логическому типу вернет True.

Функция main()

В данной функции создаем цикл while. Цикл выполняется пока один из игроков не выиграл. В данном цикле мы выводим игровое поле, принимаем ввод пользователя, при этом определяя токен(икс или нолик) игрока.

Ждем, когда переменная counter станет больше 4 для того, чтобы избежать заведомо ненужного вызова функции check_win.

Переменная tmp была создана для того, чтобы лишний раз не вызывать функцию check_win, мы просто «запоминаем» ее значение и при необходимости используем в строке «print(tmp, «выиграл!»)».

Вывод программы:

Наша игра получилась очень простой. Рекомендуется самостоятельно написать данный код для полного его понимания. Ждем ваших предложений по улучшению или модернизации данной игры.

Видео по созданию игры:

Пишем игру крестики-нолики на Python на двоих и против компьютера

Если вы учитесь программировать, то программирование игр — это очень хороший способ освоить алгоритмы и структуры данных. В этом уроке мы разберем запрограммируем игру крестики нолики на Python. Полный код программы с искусственным интеллектом для игрока-компьютера занимает всего 140 строк. В варианте игры где человек играет против человека — раза в два меньше.

Игра крестики-нолики хороша тем, что ее правила знакомы всем с детства и понятны каждому. Это даст вам возможность сосредоточиться именно на процессе программирования, а не на анализе правил игры. В процессе работы над игрой крестики-нолики мы будем использовать только стандартные функции языка Python без подключения каких либо сторонних библиотек.

Шаг 1. Подбор структуры данных

Программирование любой игры начинается с моделирования ее объектов средствами языка программирования. Когда мы программируем игру крестики нолики нам нужно подумать где в программе хранить поле для игры с ходами которые сделали игроки.

В языке программирования Python наилучшим выбором будет список из 9 значений. Назовем его maps. Первоначально этот список будет заполнен цифрами от 1 до 9. Это сделано для удобства организации диалога с пользователем. Пользователю будет достаточно ввести символ от 1 до 9, что бы мы смогли понять куда он сделал ход. После того как ход сделан, цифру мы заменим на символ нолика или крестика. (Можно было заполнить цифрами от 0 до 8. В этом случает было бы удобнее работать — цифра и есть индекс элемента в списке, но первый нолик будет смущать игроков).

Еще мы создадим второй список victories в котором будем хранить информацию обо всех выигрышных комбинациях. И нам будет нужно создать функцию print_maps, которая будет выводить содержимое нашего списка maps на экран.

# Инициализация карты maps = [1,2,3, 4,5,6, 7,8,9] # Инициализация победных линий victories = [[0,1,2], [3,4,5], [6,7,8], [0,3,6], [1,4,7], [2,5,8], [0,4,8], [2,4,6]] # Вывод карты на экран def print_maps(): print(maps[0], end = " ") print(maps[1], end = " ") print(maps[2]) print(maps[3], end = " ") print(maps[4], end = " ") print(maps[5]) print(maps[6], end = " ") print(maps[7], end = " ") print(maps[8])

Со структурами данных разобрались.

Шаг 2. Выполнение очередного хода и проверка на выигрыш

Карта для игры у нас есть, отображать ее мы умеем. Теперь нужно создать две вспомогательные функции, прежде чем мы приступим к программированию основного цикла игры.

Первая функция будет рисовать на поле крестик или нолик, в зависимости от того что в нее передали. Позицию в нее так же нужно будет передавать. Вставлять переданный элемент мы будем по индексу. Индекс определим функцией index (если бы мы пронумеровали от 0 до 8 элементы в maps, то переданное значение и было бы индексом. Можете попробовать — будет на одну строчку кода меньше.)

# Сделать ход в ячейку def step_maps(step,symbol): ind = maps.index(step) maps[ind] = symbol

После каждого ходы мы должны проверять — не победил ли кто то из игроков. Для этого переберем все победные линии из списка victories и проверим нет ли там комбинации из трех крестиков или трех ноликов.

# Получить текущий результат игры def get_result(): win = "" for i in victories: if maps[i[0]] == "X" and maps[i[1]] == "X" and maps[i[2]] == "X": win = "X" if maps[i[0]] == "O" and maps[i[1]] == "O" and maps[i[2]] == "O": win = "O" return win

Эта функция вернет «X» в случае победы крестиков и «O» в случае победы ноликов.

Шаг 3. Основный игровой цикл

Ну вот мы и подошли к созданию основного игрового цикла. Нам предстоит крутиться в цикле до момента пока кто нибудь не выиграет. Игроки будут по очереди делать ходы, мы будем проверять каждый раз не победил ли кто и как только кто то побеждает — выходим из цикла и завершаем программу.

# Основная программа game_over = False player1 = True while game_over == False: # 1. Показываем карту print_maps() # 2. Спросим у играющего куда делать ход if player1 == True: symbol = "X" step = int(input("Человек 1, ваш ход: ")) else: symbol = "O" step = int(input("Человек 2, ваш ход: ")) step_maps(step,symbol) # делаем ход в указанную ячейку win = get_result() # определим победителя if win != "": game_over = True else: game_over = False player1 = not(player1) # Игра окончена. Покажем карту. Объявим победителя. print_maps() print("Победил", win)

Вот полный код программы крестики-нолики на Python для двух игроков:

# Инициализация карты maps = [1,2,3, 4,5,6, 7,8,9] # Инициализация победных линий victories = [[0,1,2], [3,4,5], [6,7,8], [0,3,6], [1,4,7], [2,5,8], [0,4,8], [2,4,6]] # Вывод карты на экран def print_maps(): print(maps[0], end = " ") print(maps[1], end = " ") print(maps[2]) print(maps[3], end = " ") print(maps[4], end = " ") print(maps[5]) print(maps[6], end = " ") print(maps[7], end = " ") print(maps[8]) # Сделать ход в ячейку def step_maps(step,symbol): ind = maps.index(step) maps[ind] = symbol # Получить текущий результат игры def get_result(): win = "" for i in victories: if maps[i[0]] == "X" and maps[i[1]] == "X" and maps[i[2]] == "X": win = "X" if maps[i[0]] == "O" and maps[i[1]] == "O" and maps[i[2]] == "O": win = "O" return win # Основная программа game_over = False player1 = True while game_over == False: # 1. Показываем карту print_maps() # 2. Спросим у играющего куда делать ход if player1 == True: symbol = "X" step = int(input("Человек 1, ваш ход: ")) else: symbol = "O" step = int(input("Человек 2, ваш ход: ")) step_maps(step,symbol) # делаем ход в указанную ячейку win = get_result() # определим победителя if win != "": game_over = True else: game_over = False player1 = not(player1) # Игра окончена. Покажем карту. Объявим победителя. print_maps() print("Победил", win)

Вот так выглядит процесс игры в крестики-нолики для 2 игроков:

1 2 3 4 5 6 7 8 9 Человек 1, ваш ход: 5 1 2 3 4 X 6 7 8 9 Человек 2, ваш ход: 1 O 2 3 4 X 6 7 8 9 Человек 1, ваш ход: 6 O 2 3 4 X X 7 8 9 Человек 2, ваш ход: 4 O 2 3 O X X 7 8 9 Человек 1, ваш ход: 3 O 2 X O X X 7 8 9 Человек 2, ваш ход: 7 O 2 X O X X O 8 9 Победил O

Шаг 4. Добавление алгоритма для искусственного интеллекта в игре крестики-нолики

А вот теперь мы подобрались к самому интересному моменту в программировании. Нам нужно создать искусственный интеллект, который всегда будет выигрывать или сводить игру к ничьей. На самом деле в игре крестики-нолики такой алгоритм написать совсем не сложно.

Для написания такого алгоритма нам понадобится вспомогательная функция, которая будет проверять все победные линии в игре и подсчитывать в них количество крестиков и ноликов. Если функция находит такую линию, то она возвращает позицию на этой линии куда нужно сделать ход. Например мы будем отслеживать линии где противник поставил два крестика и обязательно поставим нолик, что бы не дать ему выиграть. Вот эта функция:

#Искусственный интеллект: поиск линии с нужным количеством X и O на победных линиях def check_line(sum_O,sum_X): step = "" for line in victories: o = 0 x = 0 for j in range(0,3): if maps[line[j]] == "O": o = o + 1 if maps[line[j]] == "X": x = x + 1 if o == sum_O and x == sum_X: for j in range(0,3): if maps[line[j]] != "O" and maps[line[j]] != "X": step = maps[line[j]] return step

А сейчас мы напишем функцию для поиска очередного лучшего хода для искусственного интеллекта. Запрограммируем такой алгоритм для каждого хода (компьютер играет ноликами):

  1. Если этим ходом можем выиграть — выигрываем (уже 2 нолика стоят на одной из линий). Иначе идем к шагу 2.
  2. Если можем помешать выиграть человеку — мешаем ( у человека уже 2 крестика на линии — ставим на нее нолик). Иначе идем к шагу 3.
  3. Если на линии одна наша фигура — ставим вторую. Если пока ни одной нашей фигуры — идем к шагу 4.
  4. Ставим нолик в центр. Если центр занят идем к шагу 5.
  5. Ставим в левый верхний угол.

А вот так все это выглядит в программе на Python:

#Искусственный интеллект: выбор хода def AI(): step = "" # 1) если на какой либо из победных линий 2 свои фигуры и 0 чужих - ставим step = check_line(2,0) # 2) если на какой либо из победных линий 2 чужие фигуры и 0 своих - ставим if step == "": step = check_line(0,2) # 3) если 1 фигура своя и 0 чужих - ставим if step == "": step = check_line(1,0) # 4) центр пуст, то занимаем центр if step == "": if maps[4] != "X" and maps[4] != "O": step = 5 # 5) если центр занят, то занимаем первую ячейку if step == "": if maps[0] != "X" and maps[0] != "O": step = 1 return step

Немного перепишем и основной цикл игры. Теперь вместо человека 2 ход будет делать компьютер. Компьютер каждый раз будет говорить куда делает ход. Если компьютер не дает ответ, значит наметилась ничья — завершаем партию и объявляем ничью. Вот таким станет основной цикл игры, когда мы перепишем программу крестики-нолики под игру против компьютера:

# Основная программа game_over = False human = True while game_over == False: # 1. Показываем карту print_maps() # 2. Спросим у играющего куда делать ход if human == True: symbol = "X" step = int(input("Человек, ваш ход: ")) else: print("Компьютер делает ход: ") symbol = "O" step = AI() # 3. Если компьютер нашел куда сделать ход, то играем. Если нет, то ничья. if step != "": step_maps(step,symbol) # делаем ход в указанную ячейку win = get_result() # определим победителя if win != "": game_over = True else: game_over = False else: print("Ничья!") game_over = True win = "дружба" human = not(human) # Игра окончена. Покажем карту. Объявим победителя. print_maps() print("Победил", win)

Готовая программа для игры в крестики нолики против компьютера на Python

Вот готовая программа для для игры против искусственного интеллекта.

# Инициализация карты maps = [1,2,3, 4,5,6, 7,8,9] # Инициализация победных линий victories = [[0,1,2], [3,4,5], [6,7,8], [0,3,6], [1,4,7], [2,5,8], [0,4,8], [2,4,6]] # Вывод карты на экран def print_maps(): print(maps[0], end = " ") print(maps[1], end = " ") print(maps[2]) print(maps[3], end = " ") print(maps[4], end = " ") print(maps[5]) print(maps[6], end = " ") print(maps[7], end = " ") print(maps[8]) # Сделать ход в ячейку def step_maps(step,symbol): ind = maps.index(step) maps[ind] = symbol # Получить текущий результат игры def get_result(): win = "" for i in victories: if maps[i[0]] == "X" and maps[i[1]] == "X" and maps[i[2]] == "X": win = "X" if maps[i[0]] == "O" and maps[i[1]] == "O" and maps[i[2]] == "O": win = "O" return win #Искусственный интеллект: поиск линии с нужным количеством X и O на победных линиях def check_line(sum_O,sum_X): step = "" for line in victories: o = 0 x = 0 for j in range(0,3): if maps[line[j]] == "O": o = o + 1 if maps[line[j]] == "X": x = x + 1 if o == sum_O and x == sum_X: for j in range(0,3): if maps[line[j]] != "O" and maps[line[j]] != "X": step = maps[line[j]] return step #Искусственный интеллект: выбор хода def AI(): step = "" # 1) если на какой либо из победных линий 2 свои фигуры и 0 чужих - ставим step = check_line(2,0) # 2) если на какой либо из победных линий 2 чужие фигуры и 0 своих - ставим if step == "": step = check_line(0,2) # 3) если 1 фигура своя и 0 чужих - ставим if step == "": step = check_line(1,0) # 4) центр пуст, то занимаем центр if step == "": if maps[4] != "X" and maps[4] != "O": step = 5 # 5) если центр занят, то занимаем первую ячейку if step == "": if maps[0] != "X" and maps[0] != "O": step = 1 return step # Основная программа game_over = False human = True while game_over == False: # 1. Показываем карту print_maps() # 2. Спросим у играющего куда делать ход if human == True: symbol = "X" step = int(input("Человек, ваш ход: ")) else: print("Компьютер делает ход: ") symbol = "O" step = AI() # 3. Если компьютер нашел куда сделать ход, то играем. Если нет, то ничья. if step != "": step_maps(step,symbol) # делаем ход в указанную ячейку win = get_result() # определим победителя if win != "": game_over = True else: game_over = False else: print("Ничья!") game_over = True win = "дружба" human = not(human) # Игра окончена. Покажем карту. Объявим победителя. print_maps() print("Победил", win)

Вот пример игрового процессе. В этой игре победил компьютер:

1 2 3 4 5 6 7 8 9 Человек, ваш ход: 1 X 2 3 4 5 6 7 8 9 Компьютер делает ход: X 2 3 4 O 6 7 8 9 Человек, ваш ход: 2 X X 3 4 O 6 7 8 9 Компьютер делает ход: X X O 4 O 6 7 8 9 Человек, ваш ход: 4 X X O X O 6 7 8 9 Компьютер делает ход: X X O X O 6 O 8 9 Победил O

Вы можете прямо сейчас поиграть в крестики нолики против компьютера или друг против друга. Просто скопируйте текст программы на этой странице и вставьте его в поле программы в этом онлайн эмуляторе Python: https://replit.com/languages/python3 или тут https://www.onlinegdb.com/online_python_compiler

Домашнее задание

У нас получилась довольно беспощадная программа. Ее искусственный интеллект победить не возможно. Человек либо проигрывает, либо играет в ничью. Подумайте как можно дать человеку иногда выигрывать? Возможно вы захотите создать несколько уровней. Например в первом искусственный интеллект очень слаб, дальше он умнет. Или у вас будет на выбор несколько режимов игры на выбор: слабый ИИ, средний и непобедимый.

В общем ваша задача немного ослабить искусственный интеллект в нашей игре крестики-нолики. Сделать его чуть более человечным.

Крестики-нолики на Python

Статьи

Автор Admin На чтение 5 мин Просмотров 7.5к. Опубликовано 09.11.2022

Введение

В статье напишем игру «Крестики-нолики» на Python.

Крестики-нолики — логическая игра между двумя соперниками на квадратном поле 3×3 клетки, или бо́льшего размера. Один из игроков играет за «крестики», а второй за «нолики».

Рисуем игровое поле

Начнём с того, что нарисуем само игровое поле для игры.

Для начала сгенерируем список с числами от одного, до 9:

board = list(range(1, 10))

Создадим функцию draw_board(), аргументом которой будет board:

def draw_board(board): print("-" * 13) for i in range(3): print("|", board[0 + i * 3], "|", board[1 + i * 3], "|", board[2 + i * 3], "|") print("-" * 13)

В функции выводим первую строку состоящую из 13 символов «тире», после чего, в цикле прорисовываем остальные края поля.

При вызове функции будет следующий вывод:

Принимаем ввод пользователя

Теперь нам нужно создать функцию для приёма ввода.

Создадим функцию take_input() с аргументом player_token:

def take_input(player_token): valid = False while not valid: player_answer = input("Куда поставим " + player_token + "? ") try: player_answer = int(player_answer) except ValueError: print("Некорректный ввод. Вы уверены, что ввели число?") continue if 1 

Внутри функции сначала задаётся переменная valid, которая равняется False, после чего идёт цикл while, который не закончится, пока valid не примет значение True. В цикле производится ввод пользователем определённой клетки, в которую будет ставиться крестик, либо нолик. Если же пользователь ввёл, а какой-либо другой символ, выведется ошибка.

Далее в условии проверяется, занята ли введённая клетка. Если клетка занята, то выведется соответствующая ошибка, если же введено число не в диапазоне от 1, до 10 — будет так же выведено соответствующее сообщение.

Проверка, выиграл ли игрок

Создадим функцию check_win(), в которой будем проверять, выиграл ли игрок. Аргументом функции будет board:

def check_win(board): win_coord = ((0, 1, 2), (3, 4, 5), (6, 7, 8), (0, 3, 6), (1, 4, 7), (2, 5, 8), (0, 4, 8), (2, 4, 6)) for each in win_coord: if board[each[0]] == board[each[1]] == board[each[2]]: return board[each[0]] return False

Внутри функции создаётся кортеж win_coord, в котором хранятся победные комбинации. В цикле производится проверка на победу игрока, если он побеждает, то выводится сообщение о победе, если же нет — возвращается False, и игра продолжается.

Создание главной функции

Теперь создадим функцию main() с аргументом board:

def main(board): counter = 0 win = False while not win: draw_board(board) if counter % 2 == 0: take_input("X") else: take_input("O") counter += 1 tmp = check_win(board) if tmp: print(tmp, "выиграл!") win = True break if counter == 9: print("Ничья!") break draw_board(board)

Внутри функции, после обозначения переменных, создаётся цикл, который закончится после победы одного из игроков, или ничьей. Внутри цикла проводится проверка, какой игрок сходил, после чего вызывается функция take_input() с соответствующим символом игрока. Далее идёт проверка, какой игрок выиграл, или вышла ничья.

Итоговый код игры «Крестики-нолики» на Python

board = list(range(1, 10)) def draw_board(board): print("-" * 13) for i in range(3): print("|", board[0 + i * 3], "|", board[1 + i * 3], "|", board[2 + i * 3], "|") print("-" * 13) def take_input(player_token): valid = False while not valid: player_answer = input("Куда поставим " + player_token + "? ") try: player_answer = int(player_answer) except ValueError: print("Некорректный ввод. Вы уверены, что ввели число?") continue if 1  

Заключение

В статье мы с Вами написали игру «Крестики-нолики» на Python! Надеюсь Вам понравилась статья, желаю удачи и успехов! ��

ushchent / Tic tac toe in Jupyter Notebook

Clone via HTTPS Clone with Git or checkout with SVN using the repository’s web address.

Learn more about clone URLs

Крестики-нолики на питоне

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

# Простейшее и наименее совершенное решение игры в крестики-нолики
# по заданию Milestone Project 1 из Complete Python Bootcamp,
# см. https://github.com/jmportilla/Complete-Python-Bootcamp
game_matrix = [[None, None, None], [None, None, None], [None, None, None]]
game_is_on = True
while game_is_on:
# Крестик - латинская буква X, нолик - латинская буква O
# Ходы принимаются в формате [0][0] = "X" или [2][1] = "О"
move = input()
exec("game_matrix" + move)
for row in game_matrix:
print(row)
reference_matrix = [
game_matrix[0],
game_matrix[1],
game_matrix[2],
[i[0] for i in game_matrix],
[i[1] for i in game_matrix],
[i[2] for i in game_matrix],
[game_matrix[0][0], game_matrix[1][1], game_matrix[2][2]],
[game_matrix[0][2], game_matrix[1][1], game_matrix[2][0]]
]
for item in reference_matrix:
result = list(set(item))
if len(result) == 1 and result[0] != None:
print("Game over!")
game_is_on = False
break

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *