Construir un Tic-Tac-Toe con Pygame

PythonPythonBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

Este proyecto te guiará a través de los pasos para crear un juego de Tres en Raya utilizando Pygame. El Tres en Raya es un juego para dos jugadores donde el objetivo es obtener tres de tus símbolos en línea, ya sea horizontal, vertical o diagonalmente. En este proyecto, aprenderás cómo configurar la ventana del juego, dibujar el tablero de juego, manejar los movimientos de los jugadores y la IA, y determinar al ganador. Al final de este proyecto, tendrás un juego de Tres en Raya completamente funcional contra un oponente de IA.

👀 Vista previa

Tic-Tac-Toe Using Pygame

🎯 Tareas

En este proyecto, aprenderás:

  • Cómo crear los archivos del proyecto e importar las bibliotecas necesarias
  • Cómo inicializar PyGame y configurar la ventana del juego
  • Cómo definir los símbolos, los colores y el estado del juego
  • Cómo definir las propiedades de los botones y crear funciones auxiliares
  • Cómo crear el bucle principal del juego e implementar las funciones auxiliares
  • Cómo completar el código restante dentro del bucle principal del juego

🏆 Logros

Después de completar este proyecto, podrás:

  • Utilizar Pygame para crear un juego gráfico
  • Dibujar gráficos en una ventana utilizando Pygame
  • Manejar la entrada del usuario y actualizar el estado del juego
  • Implementar la lógica del juego, como comprobar la condición de victoria
  • Crear un bucle de juego para mantener el juego en ejecución

Crear los archivos del proyecto

Para comenzar, crea un nuevo archivo llamado tic_tac_toe.py. Abre el archivo en tu editor de texto preferido.

cd ~/proyecto
touch tic_tac_toe.py
✨ Revisar Solución y Practicar

Importar las bibliotecas necesarias

En tic_tac_toe.py, importa las bibliotecas necesarias: pygame y random. Estas bibliotecas se utilizarán para manejar los gráficos del juego y generar movimientos aleatorios de la IA, respectivamente.

import pygame
import random

Instala la biblioteca pygame con el siguiente comando:

sudo pip install pygame
✨ Revisar Solución y Practicar

Inicializar PyGame y configurar la ventana del juego

En tic_tac_toe.py, inicializa PyGame usando pygame.init(). Luego, configura la ventana del juego definiendo el ancho y alto de la ventana, el color de fondo, el color de las líneas y el tamaño de las celdas. Además, crea una ventana de PyGame con el ancho y alto especificados y establece el título de la ventana.

pygame.init()

ANCHO = 600
ALTO = 600
COLOR_FONDO = (40, 40, 40)
COLOR_LINEA = (70, 70, 70)
TAMANO_CELDA = ANCHO // 3

ventana = pygame.display.set_mode((ANCHO, ALTO))
pygame.display.set_caption("Tres en Raya")
✨ Revisar Solución y Practicar

Definir los símbolos y los colores

En tic_tac_toe.py, define los símbolos y los colores para el jugador y la IA. Estos símbolos y colores se utilizarán para dibujar los movimientos del jugador y la IA en el tablero de juego.

SIMBOLO_JUGADOR = "X"
SIMBOLO_IA = "O"
COLOR_JUGADOR = (0, 255, 0)
COLOR_IA = (255, 0, 0)
COLOR_VACIO = (0, 0, 0)
✨ Revisar Solución y Practicar

Definir el estado del juego

En tic_tac_toe.py, define el estado inicial del juego. Esto incluye el tablero de juego, el turno actual (ya sea "jugador" o "ia"), una bandera que indica si el juego ha terminado y el ganador del juego.

tablero = [["" for _ in range(3)] for _ in range(3)]
turno = "jugador"
juego_terminado = False
ganador = None
✨ Revisar Solución y Practicar

Definir las propiedades del botón

En tic_tac_toe.py, define las propiedades del botón de reinicio, incluyendo el ancho del botón, el alto, el color, el color del texto y el tamaño de la fuente. Además, crea un objeto reset_button_rect usando la clase pygame.Rect para representar la posición y el tamaño del botón.

ANCHO_BOTON = 200
ALTO_BOTON = 50
COLOR_BOTON = (50, 50, 50)
COLOR_TEXTO_BOTON = (255, 255, 255)
FUENTE_BOTON = pygame.font.Font(None, 30)

reset_button_rect = pygame.Rect(
    (ANCHO - ANCHO_BOTON) // 2,
    (ALTO - ALTO_BOTON) // 2,
    ANCHO_BOTON,
    ALTO_BOTON,
)
✨ Revisar Solución y Practicar

Crear funciones auxiliares

En tic_tac_toe.py, define varias funciones auxiliares que se utilizarán durante todo el juego.

  • draw_board(): Esta función dibujará el tablero de juego en la ventana.

  • draw_symbols(): Esta función dibujará los símbolos del jugador y la IA en el tablero de juego.

  • is_board_full(): Esta función comprobará si el tablero de juego está lleno.

  • is_winner(): Esta función comprobará si un jugador ha ganado el juego.

  • make_move(): Esta función hará un movimiento en el tablero de juego.

  • player_move(): Esta función manejará el movimiento del jugador.

  • ai_move(): Esta función manejará el movimiento de la IA.

  • check_game_over(): Esta función comprobará si el juego ha terminado.

  • draw_winner(): Esta función dibujará el mensaje del ganador en la ventana.

  • draw_reset_button(): Esta función dibujará el botón de reinicio en la ventana.

  • reset_game(): Esta función restablecerá el estado del juego.

## Funciones auxiliares
def draw_board():
    ## Dibuja el tablero de juego
    pass

def draw_symbols():
    ## Dibuja los símbolos del jugador y la IA en el tablero de juego
    pass

def is_board_full():
    ## Comprueba si el tablero de juego está lleno
    pass

def is_winner(symbol):
    ## Comprueba si un jugador ha ganado el juego
    pass

def make_move(x, y, symbol):
    ## Hace un movimiento en el tablero de juego
    pass

def player_move():
    ## Maneja el movimiento del jugador
    pass

def ai_move():
    ## Maneja el movimiento de la IA
    pass

def check_game_over():
    ## Comprueba si el juego ha terminado
    pass

def draw_winner():
    ## Dibuja el mensaje del ganador en la ventana
    pass

def draw_reset_button():
    ## Dibuja el botón de reinicio en la ventana
    pass

def reset_game():
    ## Restablece el estado del juego
    pass
✨ Revisar Solución y Practicar

Crear el bucle principal del juego

En tic_tac_toe.py, crea el bucle principal del juego usando un bucle while. Este bucle se ejecutará hasta que el usuario cierre la ventana del juego. Dentro del bucle del juego, maneja los eventos de entrada del usuario y actualiza el estado del juego en consecuencia.

## Bucle principal del juego
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()

## Salir del juego
pygame.quit()
✨ Revisar Solución y Practicar

Implementar las funciones auxiliares

Ahora, implementemos las funciones auxiliares que definimos anteriormente. Comencemos completando la función draw_board(). Esta función dibujará el tablero de juego en la ventana dibujando líneas verticales y horizontales usando la función pygame.draw.line().

## Funciones auxiliares
def draw_board():
    win.fill(BACKGROUND_COLOR)

    ## Dibuja líneas verticales
    for x in range(1, 3):
        pygame.draw.line(
            win, LINE_COLOR, (CELL_SIZE * x, 0), (CELL_SIZE * x, HEIGHT), 2
        )

    ## Dibuja líneas horizontales
    for y in range(1, 3):
        pygame.draw.line(win, LINE_COLOR, (0, CELL_SIZE * y), (WIDTH, CELL_SIZE * y), 2)
✨ Revisar Solución y Practicar

Implementar las funciones auxiliares restantes

A continuación, implementa las funciones auxiliares restantes: draw_symbols(), is_board_full(), is_winner(), make_move(), player_move(), ai_move(), check_game_over(), draw_winner(), draw_reset_button() y reset_game().

## Funciones auxiliares
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

En el código anterior, la función draw_symbols() dibujará los símbolos en el tablero. La función is_board_full() comprobará si el tablero está lleno. La función is_winner() comprobará si el símbolo dado ha ganado el juego. La función make_move() hará un movimiento en el tablero. La función player_move() manejará el movimiento del jugador. La función ai_move() manejará el movimiento de la IA. La función check_game_over() comprobará si el juego ha terminado. La función draw_winner() dibujará el mensaje del ganador. La función draw_reset_button() dibujará el botón de reinicio. La función reset_game() restablecerá el juego.

✨ Revisar Solución y Practicar

Completar el código restante

Finalmente, completa el código restante dentro del bucle principal del juego para llamar a las funciones auxiliares en los lugares adecuados. Esto incluye llamar a las funciones draw_board() y draw_symbols() para dibujar el tablero de juego y los símbolos, llamar a la función check_game_over() para comprobar si el juego ha terminado y llamar a las funciones draw_winner() y draw_reset_button() para dibujar el mensaje del ganador y el botón de reinicio, respectivamente.

## Bucle principal del juego
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()

## Salir del juego
pygame.quit()

Ejecuta el juego usando el siguiente comando:

python tic_tac_toe.py
Captura de pantalla del juego tic tac toe
✨ Revisar Solución y Practicar

Resumen

¡Felicidades! Has creado con éxito un juego de Tic-Tac-Toe usando Pygame. En este proyecto, aprendiste cómo configurar la ventana del juego, dibujar el tablero de juego, manejar los movimientos del jugador y la IA y determinar al ganador. También aprendiste cómo implementar funciones auxiliares para simplificar el código y hacerlo más modular.