Создание игры "Крестики-нолики" с использованием Pygame

PythonBeginner
Практиковаться сейчас

Введение

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

👀 Предпросмотр

Tic-Tac-Toe Using Pygame

🎯 Задачи

В этом проекте вы научитесь:

  • Создавать файлы проекта и импортировать необходимые библиотеки
  • Инициализировать PyGame и настроить игровое окно
  • Определять символы, цвета и игровое состояние
  • Определять свойства кнопок и создавать вспомогательные функции
  • Создавать главный игровой цикл и реализовывать вспомогательные функции
  • Заполнять оставшийся код внутри главного игрового цикла

🏆 Достижения

После завершения этого проекта вы сможете:

  • Использовать Pygame для создания графической игры
  • Рисовать графику на окне с использованием Pygame
  • Обрабатывать ввод пользователя и обновлять игровое состояние
  • Реализовывать игровую логику, такую как проверка условия победы
  • Создавать игровой цикл для поддержания работы игры

Создайте файлы проекта

Для начала создайте новый файл с именем tic_tac_toe.py. Откройте файл в своем предпочитаемом текстовом редакторе.

cd ~/project
touch tic_tac_toe.py

Импортируйте необходимые библиотеки

В tic_tac_toe.py импортируйте необходимые библиотеки: pygame и random. Эти библиотеки будут использоваться для обработки игровой графики и генерации случайных ходов ИИ соответственно.

import pygame
import random

Установите библиотеку pygame с помощью следующей команды:

sudo pip install pygame

Инициализируйте PyGame и настройте игровое окно

В tic_tac_toe.py инициализируйте PyGame с использованием pygame.init(). Затем настройте игровое окно, определив ширину и высоту окна, цвет фона, цвет линий и размер ячейки. Также создайте окно PyGame с указанной шириной и высотой и задайте заголовок окна.

pygame.init()

WIDTH = 600
HEIGHT = 600
BACKGROUND_COLOR = (40, 40, 40)
LINE_COLOR = (70, 70, 70)
CELL_SIZE = WIDTH // 3

win = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Tic-Tac-Toe")

Определите символы и цвета

В tic_tac_toe.py определите символы и цвета для игрока и ИИ. Эти символы и цвета будут использоваться для рисования ходов игрока и ИИ на игровой доске.

PLAYER_SYMBOL = "X"
AI_SYMBOL = "O"
PLAYER_COLOR = (0, 255, 0)
AI_COLOR = (255, 0, 0)
EMPTY_COLOR = (0, 0, 0)

Определите состояние игры

В tic_tac_toe.py определите начальное состояние игры. Это включает игровую доску, текущий ход (либо "игрок", либо "ии"), флаг, указывающий, закончена ли игра, и победителя игры.

board = [["" for _ in range(3)] for _ in range(3)]
turn = "player"
game_over = False
winner = None

Определите свойства кнопок

В tic_tac_toe.py определите свойства для кнопки сброса, включая ширину кнопки, высоту, цвет, цвет текста и размер шрифта. Также создайте объект reset_button_rect с использованием класса pygame.Rect, чтобы представить позицию и размер кнопки.

BUTTON_WIDTH = 200
BUTTON_HEIGHT = 50
BUTTON_COLOR = (50, 50, 50)
BUTTON_TEXT_COLOR = (255, 255, 255)
BUTTON_FONT = pygame.font.Font(None, 30)

reset_button_rect = pygame.Rect(
    (WIDTH - BUTTON_WIDTH) // 2,
    (HEIGHT - BUTTON_HEIGHT) // 2,
    BUTTON_WIDTH,
    BUTTON_HEIGHT,
)

Создайте вспомогательные функции

В tic_tac_toe.py определите несколько вспомогательных функций, которые будут использоваться на протяжении всей игры.

  • draw_board(): Эта функция будет рисовать игровую доску на окне.

  • draw_symbols(): Эта функция будет рисовать символы игрока и ИИ на игровой доске.

  • is_board_full(): Эта функция будет проверять, заполнена ли игровая доска.

  • is_winner(): Эта функция будет проверять, выиграл ли игрок игру.

  • make_move(): Эта функция будет совершать ход на игровой доске.

  • player_move(): Эта функция будет обрабатывать ход игрока.

  • ai_move(): Эта функция будет обрабатывать ход ИИ.

  • check_game_over(): Эта функция будет проверять, закончена ли игра.

  • draw_winner(): Эта функция будет рисовать сообщение о победителе на окне.

  • draw_reset_button(): Эта функция будет рисовать кнопку сброса на окне.

  • reset_game(): Эта функция будет сбрасывать состояние игры.

## Вспомогательные функции
def draw_board():
    ## Рисуем игровую доску
    pass

def draw_symbols():
    ## Рисуем символы игрока и ИИ на игровой доске
    pass

def is_board_full():
    ## Проверяем, заполнена ли игровая доска
    pass

def is_winner(symbol):
    ## Проверяем, выиграл ли игрок игру
    pass

def make_move(x, y, symbol):
    ## Совершаем ход на игровой доске
    pass

def player_move():
    ## Обрабатываем ход игрока
    pass

def ai_move():
    ## Обрабатываем ход ИИ
    pass

def check_game_over():
    ## Проверяем, закончена ли игра
    pass

def draw_winner():
    ## Рисуем сообщение о победителе на окне
    pass

def draw_reset_button():
    ## Рисуем кнопку сброса на окне
    pass

def reset_game():
    ## Сбрасываем состояние игры
    pass

Создайте главный игровой цикл

В tic_tac_toe.py создайте главный игровой цикл с использованием цикла while. Этот цикл будет работать до тех пор, пока пользователь не закроет игровое окно. Внутри игрового цикла обработайте события ввода пользователя и обновите состояние игры в соответствии с ними.

## Главный игровой цикл
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if reset_button_rect.collidepoint(event.pos):
                reset_game()
            elif not game_over and turn == "player":
                player_move()

    if not game_over and turn == "ai":
        ai_move()
        check_game_over()

    draw_board()
    draw_symbols()

    if game_over:
        draw_winner()
        draw_reset_button()

    pygame.display.flip()

## Завершите игру
pygame.quit()

Реализуйте вспомогательные функции

Теперь реализуем вспомогательные функции, которые мы определили ранее. Начнем с завершения функции draw_board(). Эта функция будет рисовать игровую доску на окне, рисуя вертикальные и горизонтальные линии с использованием функции pygame.draw.line().

## Вспомогательные функции
def draw_board():
    win.fill(BACKGROUND_COLOR)

    ## Рисуем вертикальные линии
    for x in range(1, 3):
        pygame.draw.line(
            win, LINE_COLOR, (CELL_SIZE * x, 0), (CELL_SIZE * x, HEIGHT), 2
        )

    ## Рисуем горизонтальные линии
    for y in range(1, 3):
        pygame.draw.line(win, LINE_COLOR, (0, CELL_SIZE * y), (WIDTH, CELL_SIZE * y), 2)

Реализуйте оставшиеся вспомогательные функции

Далее реализуйте оставшиеся вспомогательные функции: draw_symbols(), is_board_full(), is_winner(), make_move(), player_move(), ai_move(), check_game_over(), draw_winner(), draw_reset_button() и reset_game().

## Вспомогательные функции
def draw_symbols():
    for x in range(3):
        for y in range(3):
            symbol = board[x][y]
            if symbol == PLAYER_SYMBOL:
                color = PLAYER_COLOR
            elif symbol == AI_SYMBOL:
                color = AI_COLOR
            else:
                color = EMPTY_COLOR
            if symbol!= "":
                pygame.draw.circle(
                    win,
                    color,
                    (x * CELL_SIZE + CELL_SIZE // 2, y * CELL_SIZE + CELL_SIZE // 2),
                    CELL_SIZE // 2 - 10,
                    2,
                )

def is_board_full():
    for row in board:
        if "" in row:
            return False
    return True

def is_winner(symbol):
    for row in board:
        if all(cell == symbol for cell in row):
            return True
    for col in range(3):
        if all(board[row][col] == symbol for row in range(3)):
            return True
    if all(board[i][i] == symbol for i in range(3)):
        return True
    if all(board[i][2 - i] == symbol for i in range(3)):
        return True
    return False

def make_move(x, y, symbol):
    if board[x][y] == "":
        board[x][y] = symbol
        return True
    return False

def player_move():
    global turn
    mouse_pos = pygame.mouse.get_pos()
    cell_x = mouse_pos[0] // CELL_SIZE
    cell_y = mouse_pos[1] // CELL_SIZE

    if make_move(cell_x, cell_y, PLAYER_SYMBOL):
        turn = "ai"

def ai_move():
    global turn
    empty_cells = []
    for x in range(3):
        for y in range(3):
            if board[x][y] == "":
                empty_cells.append((x, y))

    if empty_cells:
        x, y = random.choice(empty_cells)
        make_move(x, y, AI_SYMBOL)

    turn = "player"

def check_game_over():
    global game_over, winner
    if is_winner(PLAYER_SYMBOL):
        game_over = True
        return "player"
    elif is_winner(AI_SYMBOL):
        game_over = True
        return "ai"
    elif is_board_full():
        game_over = True
        return "tie"
    return None

def draw_winner():
    font = pygame.font.Font(None, 50)
    if winner == "player":
        text = font.render("Player Wins!", True, PLAYER_COLOR)
    elif winner == "ai":
        text = font.render("AI Wins!", True, AI_COLOR)
    else:
        text = font.render("It's a Tie!", True, (255, 255, 255))
    text_rect = text.get_rect(center=(WIDTH // 2, HEIGHT // 3))
    win.blit(text, text_rect)

def draw_reset_button():
    pygame.draw.rect(win, BUTTON_COLOR, reset_button_rect)
    button_text = BUTTON_FONT.render("Reset", True, BUTTON_TEXT_COLOR)
    button_text_rect = button_text.get_rect(center=reset_button_rect.center)
    win.blit(button_text, button_text_rect)

def reset_game():
    global board, turn, game_over, winner
    board = [["" for _ in range(3)] for _ in range(3)]
    turn = "player"
    game_over = False
    winner = None

В приведенном выше коде функция draw_symbols() будет рисовать символы на доске. Функция is_board_full() будет проверять, заполнена ли доска. Функция is_winner() будет проверять, выиграл ли заданный символ игру. Функция make_move() будет совершать ход на доске. Функция player_move() будет обрабатывать ход игрока. Функция ai_move() будет обрабатывать ход ИИ. Функция check_game_over() будет проверять, закончена ли игра. Функция draw_winner() будет рисовать сообщение о победителе. Функция draw_reset_button() будет рисовать кнопку сброса. Функция reset_game() будет сбрасывать игру.

Заполните оставшийся код

Наконец, заполните оставшийся код внутри главного игрового цикла, чтобы вызывать вспомогательные функции в соответствующих местах. Это включает вызов функций draw_board() и draw_symbols() для рисования игровой доски и символов, вызов функции check_game_over() для проверки, закончена ли игра, а также вызов функций draw_winner() и draw_reset_button() для рисования сообщения о победителе и кнопки сброса соответственно.

## Главный игровой цикл
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if reset_button_rect.collidepoint(event.pos):
                reset_game()
            elif not game_over and turn == "player":
                player_move()

    if not game_over and turn == "ai":
        ai_move()
        winner = check_game_over()

    draw_board()
    draw_symbols()

    if game_over:
        draw_winner()
        draw_reset_button()

    pygame.display.flip()

## Завершите игру
pygame.quit()

Запустите игру с помощью следующей команды:

python tic_tac_toe.py

скриншот игры tic tac toe

Резюме

Поздравляем! Вы успешно создали игру "Крестики-нолики" с использованием Pygame. В этом проекте вы узнали, как настроить игровое окно, нарисовать игровую доску, обработать ходы игрока и ИИ и определить победителя. Вы также узнали, как реализовать вспомогательные функции, чтобы упростить код и сделать его более модульным.

✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться