El Gato
// Este script se ejecutará cuando el DOM esté completamente cargado.
document.addEventListener(‘DOMContentLoaded’, () => {
console.log(‘DOMContentLoaded fired. Attempting to inject Tic-Tac-Toe game.’);
// 1. Define el HTML del juego como una cadena
const gameContainerHTML = `
`;
// 2. Define los estilos CSS del juego como una cadena
const gameStyles = `
/* Estilos personalizados para el contenedor del juego y sus elementos */
#tic-tac-toe-container {
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
background-color: #ffffff;
border-radius: 15px;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
max-width: 90%;
box-sizing: border-box;
font-family: ‘Inter’, sans-serif;
}
#game-board {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
gap: 5px;
border: 5px solid #333;
border-radius: 10px;
background-color: #333;
}
.cell {
width: 100px;
height: 100px;
background-color: #eee;
display: flex;
justify-content: center;
align-items: center;
font-size: 3em;
font-weight: bold;
cursor: pointer;
user-select: none;
border-radius: 5px;
transition: background-color 0.2s ease;
}
.cell:hover {
background-color: #ddd;
}
.cell.x-player {
color: #007bff;
}
.cell.o-player {
color: #dc3545;
}
#game-status {
margin-top: 20px;
font-size: 1.5em;
font-weight: bold;
color: #333;
min-height: 1.8em;
}
#restart-button {
margin-top: 20px;
padding: 12px 25px;
font-size: 1.1em;
font-weight: bold;
background-color: #28a745;
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
transition: background-color 0.3s ease, transform 0.2s ease;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
#restart-button:hover {
background-color: #218838;
transform: translateY(-2px);
}
#restart-button:active {
background-color: #1e7e34;
transform: translateY(0);
}
/* Ajustes responsivos para pantallas más pequeñas */
@media (max-width: 400px) {
#game-board {
grid-template-columns: repeat(3, 80px);
grid-template-rows: repeat(3, 80px);
}
.cell {
width: 80px;
height: 80px;
font-size: 2.5em;
}
#game-status {
font-size: 1.2em;
}
#restart-button {
padding: 10px 20px;
font-size: 1em;
}
}
`;
// 3. Inyecta Tailwind CSS (si no está ya cargado por el tema)
// Es importante que Tailwind se cargue antes de tus estilos personalizados.
if (!document.querySelector(‘script[src*=»cdn.tailwindcss.com»]’)) {
const tailwindScript = document.createElement(‘script’);
tailwindScript.src = ‘https://cdn.tailwindcss.com’;
document.head.appendChild(tailwindScript);
console.log(‘Tailwind CSS CDN script injected.’);
} else {
console.log(‘Tailwind CSS CDN script already present.’);
}
// 4. Inyecta los estilos personalizados del juego
const styleTag = document.createElement(‘style’);
styleTag.textContent = gameStyles;
document.head.appendChild(styleTag);
console.log(‘Game custom styles injected.’);
// 5. Inyecta el HTML del juego en el marcador de posición
const placeholder = document.getElementById(‘tic-tac-toe-placeholder’);
if (placeholder) {
placeholder.innerHTML = gameContainerHTML;
console.log(‘Game HTML injected into placeholder.’);
} else {
// Si no se encuentra el marcador de posición, lo añadimos al cuerpo.
// Esto puede no ser ideal para el diseño, pero asegura que el juego aparezca.
document.body.insertAdjacentHTML(‘beforeend’, gameContainerHTML);
console.warn(‘No se encontró el elemento #tic-tac-toe-placeholder. El juego se añadió al final del body. Considera añadir en tu contenido de WordPress para un mejor control del diseño.’);
}
// Ahora, obtenemos las referencias a los elementos del DOM después de que han sido inyectados.
const gameBoard = document.getElementById(‘game-board’);
const gameStatus = document.getElementById(‘game-status’);
const restartButton = document.getElementById(‘restart-button’);
// Variables de estado del juego
let board = [», », », », », », », », »]; // Representa el tablero 3×3
let currentPlayer = ‘X’; // ‘X’ o ‘O’
let gameActive = true; // Verdadero si el juego está en curso, falso si se ganó o empató
// Condiciones de victoria (índices de las celdas que forman una victoria)
const winConditions = [
[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
];
// Función para inicializar o reiniciar el juego
function initializeGame() {
console.log(‘Initializing game…’);
board = [», », », », », », », », »]; // Limpiar el tablero
currentPlayer = ‘X’; // X comienza
gameActive = true; // Juego activo
gameStatus.textContent = `Turno de ${currentPlayer}`; // Actualizar mensaje de estado
renderBoard(); // Dibujar el tablero vacío
console.log(‘Game initialized and board rendered.’);
}
// Función para renderizar el tablero en el DOM
function renderBoard() {
console.log(‘Rendering board…’);
if (!gameBoard) {
console.error(‘Error: gameBoard element not found in renderBoard(). Cannot render board.’);
return;
}
gameBoard.innerHTML = »; // Limpiar celdas existentes
board.forEach((cell, index) => {
const cellElement = document.createElement(‘div’);
cellElement.classList.add(‘cell’, ‘flex’, ‘justify-center’, ‘items-center’, ‘font-bold’, ‘cursor-pointer’, ‘select-none’);
cellElement.dataset.index = index; // Almacenar índice en atributo de datos
cellElement.textContent = cell; // Mostrar X, O, o vacío
// Añadir clase específica del jugador si la celda no está vacía
if (cell === ‘X’) {
cellElement.classList.add(‘x-player’);
} else if (cell === ‘O’) {
cellElement.classList.add(‘o-player’);
}
cellElement.addEventListener(‘click’, handleCellClick); // Añadir listener de clic
gameBoard.appendChild(cellElement);
});
console.log(‘Board cells appended.’);
}
// Función para manejar el clic en una celda
function handleCellClick(event) {
const clickedCell = event.target;
const clickedCellIndex = parseInt(clickedCell.dataset.index);
// Si la celda ya está llena o el juego no está activo, no hacer nada
if (board[clickedCellIndex] !== » || !gameActive) {
return;
}
// Actualizar tablero y mostrar la marca del jugador
board[clickedCellIndex] = currentPlayer;
clickedCell.textContent = currentPlayer;
if (currentPlayer === ‘X’) {
clickedCell.classList.add(‘x-player’);
} else {
clickedCell.classList.add(‘o-player’);
}
checkGameStatus(); // Comprobar si el juego se ganó o empató
}
// Función para comprobar el estado del juego (victoria o empate)
function checkGameStatus() {
let roundWon = false;
// Comprobar todas las condiciones de victoria
for (let i = 0; i < winConditions.length; i++) {
const winCondition = winConditions[i];
const a = board[winCondition[0]];
const b = board[winCondition[1]];
const c = board[winCondition[2]];
// Si alguna celda en la condición está vacía, continuar
if (a === '' || b === '' || c === '') {
continue;
}
// Si todas las celdas en la condición son iguales, es una victoria
if (a === b && b === c) {
roundWon = true;
break;
}
}
if (roundWon) {
gameStatus.textContent = `¡El jugador ${currentPlayer} ha ganado!`;
gameActive = false; // Terminar el juego
return;
}
// Comprobar si hay un empate (si todas las celdas están llenas y nadie ganó)
const roundDraw = !board.includes(''); // Verdadero si no hay celdas vacías
if (roundDraw) {
gameStatus.textContent = '¡Es un empate!';
gameActive = false; // Terminar el juego
return;
}
// Si no hay victoria ni empate, cambiar al siguiente jugador
currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
gameStatus.textContent = `Turno de ${currentPlayer}`;
}
// Añadir listener para el botón de reiniciar (después de obtener su referencia)
if (restartButton) {
restartButton.addEventListener('click', initializeGame);
} else {
console.error('Error: restartButton element not found after injection.');
}
// Inicializar el juego solo si todos los elementos necesarios se encuentran
if (gameBoard && gameStatus && restartButton) {
initializeGame();
} else {
console.error('One or more game elements not found after injection. Game cannot be initialized.');
}
});
