import time import tkinter as tk from tkinter import messagebox import threading import random class TicTacToe: def __init__(self, parent): """ Inicializa el juego de Tic Tac Toe. Args: parent (tk.Frame): Frame donde se colocará el juego. """ self.parent = parent self.board = [""] * 9 # Tablero de 3x3 representado como una lista self.current_player = "X" # Jugador inicial self.vs_computer = False # Modo jugador vs máquina # Etiqueta para el título title = tk.Label(self.parent, text="Tic Tac Toe", font=("Helvetica", 16, "bold")) title.pack(pady=10) # Botón para alternar entre modos self.mode_button = tk.Button(self.parent, text="Modo: Jugador vs Jugador", command=self.toggle_mode) self.mode_button.pack(pady=5) # Crear el tablero self.buttons = [] self.board_frame = tk.Frame(self.parent) self.board_frame.pack() for i in range(9): button = tk.Button( self.board_frame, text="", font=("Helvetica", 20), width=5, height=2, command=self.create_button_command(i) # Aquí usamos la función auxiliar ) button.grid(row=i // 3, column=i % 3) self.buttons.append(button) # Etiqueta para el estado del juego self.status_label = tk.Label(self.parent, text="Turno: X", font=("Helvetica", 12)) self.status_label.pack(pady=5) def toggle_mode(self): """Alterna entre los modos Jugador vs Jugador y Jugador vs Máquina.""" self.vs_computer = not self.vs_computer mode_text = "Modo: Jugador vs Máquina" if self.vs_computer else "Modo: Jugador vs Jugador" self.mode_button.config(text=mode_text) self.reset_game() def reset_game(self): """Reinicia el tablero y el estado del juego.""" self.board = [""] * 9 self.current_player = "X" for button in self.buttons: button.config(text="", state=tk.NORMAL) self.status_label.config(text="Turno: X") def make_move(self, index): """Realiza un movimiento en el tablero.""" if self.board[index] == "": self.board[index] = self.current_player self.buttons[index].config(text=self.current_player) # Verificar si hay un ganador winner = self.check_winner() if winner: self.end_game(f"¡Ganador: {winner}!") return elif "" not in self.board: self.end_game("¡Empate!") return # Cambiar de jugador self.current_player = "O" if self.current_player == "X" else "X" self.status_label.config(text=f"Turno: {self.current_player}") # Si está en modo Jugador vs Máquina y es el turno de la máquina if self.vs_computer and self.current_player == "O": threading.Thread(target=self.computer_move).start() def computer_move(self): """Simula el movimiento de la máquina.""" self.status_label.config(text="Turno: Máquina (O)") available_moves = [i for i, v in enumerate(self.board) if v == ""] move = random.choice(available_moves) def delayed_move(): time.sleep(1) # Simular el tiempo de "pensar" self.make_move(move) threading.Thread(target=delayed_move).start() def check_winner(self): """Verifica si hay un ganador.""" winning_combinations = [ (0, 1, 2), (3, 4, 5), (6, 7, 8), # Filas (0, 3, 6), (1, 4, 7), (2, 5, 8), # Columnas (0, 4, 8), (2, 4, 6) # Diagonales ] for a, b, c in winning_combinations: if self.board[a] == self.board[b] == self.board[c] and self.board[a] != "": return self.board[a] return None def end_game(self, message): """Finaliza el juego mostrando un mensaje.""" messagebox.showinfo("Fin del Juego", message) self.reset_game() def create_button_command(self, index): """Crea un comando para un botón con un índice específico.""" def command(): self.make_move(index) return command