Hoy te guiaremos a través de la creación del juego «Tres en raya» en JavaScript. ¡Este juego es perfecto para practicar la programación y comprender cómo interactuar con HTML, CSS y JavaScript! ⭐

Si ya estás un poco familiarizado con la programación y quieres crear algo propio, este artículo te ayudará a entender los conceptos básicos. Y para obtener el código fuente completo, puedes ir a GitHub y ver el proyecto en acción. ¡Empecemos!
Para obtener el código fuente completo y posiblemente mejoras adicionales, echa un vistazo a nuestro GitHub.
Paso 1: Preparación de archivos 💻
Para crear un juego, necesitamos tres archivos:
HTML (index.html) - para crear la estructura de la página.
CSS (style.css) - para el diseño de la página.
JavaScript (script.js) - para escribir la lógica del juego.
HTML es responsable de la estructura, CSS añade estilo y hace que la interfaz sea agradable, y JavaScript llena el juego con lógica e interactividad. En primer lugar, vamos a echar un vistazo al archivo HTML, que crea la base de nuestro juego.
HTML: Creación de una estructura
El archivo HTML crea la base de la interfaz de usuario. Así es como se ve el código (parte del archivo index.html):
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Игра "Tic-tac-toe" | Coursme</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- окно выбора -->
<div class="select-box">
<header>Крестики-нолики</header>
<div class="content">
<div class="title">Выберите, кем вы хотите быть?</div>
<div class="options">
<button class="playerX">Игрок (X)</button>
<button class="playerO">Игрок (O)</button>
</div>
</div>
</div>
<!-- игровое поле -->
<div class="play-board">
<div class="details">
<div class="players">
<span class="Xturn">Ход X</span>
<span class="Oturn">Ход O</span>
<div class="slider"></div>
</div>
</div>
<div class="play-area">
<section>
<span class="box1"></span>
<span class="box2"></span>
<span class="box3"></span>
</section>
<section>
<span class="box4"></span>
<span class="box5"></span>
<span class="box6"></span>
</section>
<section>
<span class="box7"></span>
<span class="box8"></span>
<span class="box9"></span>
</section>
</div>
</div>
<!-- окно результата -->
<div class="result-box">
<div class="won-text"></div>
<div class="btn"><button>Играть снова</button></div>
</div>
<script src="script.js"></script>
</body>
</html>Este código HTML crea tres secciones principales:
Ventana de selección de jugador - donde el jugador elige si será X u O.
Campo de juego - la interfaz principal, donde los jugadores hacen sus movimientos.
Ventana de resultados - muestra el ganador o un empate.
Estas tres secciones forman la base de nuestro juego y hacen que la interfaz sea clara y fácil de usar.
Paso 2: Estilizar el juego 🎨
El archivo style.css es responsable de la apariencia del juego. Aquí hay algunos puntos clave:
El fondo del juego está pintado en un color púrpura agradable, lo que hace que la interfaz sea brillante y agradable.
Los botones de selección del jugador tienen una animación suave al pasar el cursor, lo que hace que la interacción con el juego sea más emocionante.
El tablero de juego está dividido en celdas, cada una de las cuales se ilumina al pasar el ratón por encima, lo que ayuda a los jugadores a comprender intuitivamente dónde pueden hacer un movimiento.
Ejemplo de código de style.css:
body{
background: #6563FF;
color: #e0e0e0;
}
.play-area section span{
display: block;
height: 90px;
width: 90px;
margin: 2px;
color: #fff;
font-size: 40px;
line-height: 80px;
text-align: center;
border-radius: 5px;
background: #1e1e1e;
}Este estilo hace que nuestro juego sea visualmente atractivo y fácil de usar. Las celdas del campo de juego están cuidadosamente diseñadas para que cada movimiento sea claramente visible y los jugadores puedan navegar fácilmente por el campo de juego.
Ahora pasemos a la parte más interesante: ¡JavaScript!
Paso 3: lógica del juego en JavaScript 🕹️
JavaScript es lo que hace que nuestro juego sea interactivo. Veamos cómo funciona nuestro archivo script.js, comenzando con una simple selección de un jugador hasta determinar el ganador.
Inicialización del juego y selección del jugador
Cuando el juego se carga, inmediatamente inicializamos algunos elementos y añadimos eventos para los botones de selección de jugador. Así es como se hace:
// selección de todos los elementos necesarios
const selectBox = document.querySelector(".select-box"),
selectBtnX = selectBox.querySelector(".options .playerX"),
selectBtnO = selectBox.querySelector(".options .playerO"),
playBoard = document.querySelector(".play-board"),
players = document.querySelector(".players"),
allBox = document.querySelectorAll("section span"),
resultBox = document.querySelector(".result-box"),
wonText = resultBox.querySelector(".won-text"),
replayBtn = resultBox.querySelector("button");
window.onload = ()=>{ // después de cargar la ventana
for (let i = 0; i < allBox.length; i++) { // añadimos el atributo onclick para todos los span disponibles
allBox[i].setAttribute("onclick", "clickedBox(this)");
}
}Aquí encontramos todos los elementos necesarios para controlar el juego y añadimos eventos de clic para cada celda del campo de juego. Esto significa que cada celda se vuelve interactiva y puede responder a las acciones del usuario.
A continuación, el jugador elige:
selectBtnX.onclick = ()=>{
selectBox.classList.add("hide"); // Ocultar la ventana de selección
playBoard.classList.add("show"); // Mostramos el campo de juego
}
selectBtnO.onclick = ()=>{
selectBox.classList.add("hide");
playBoard.classList.add("show");
players.setAttribute("class", "players active player"); // Establecer atributo para jugadores
}Este código es responsable de mostrar u ocultar las diferentes partes de la interfaz, dependiendo de qué jugador se ha seleccionado. Cuando se hace la selección, la ventana de selección desaparece y el campo de juego aparece en la pantalla.
Movimientos del jugador y del bot ➖➕
Cuando un jugador selecciona una celda en el campo de juego, queremos que aparezca un icono (X u O) en esa celda. Así es como lo implementamos:
let playerXIcon = "fas fa-times"; // nombre de la clase del icono de la cruz de FontAwesome
let playerOIcon = "far fa-circle"; // nombre de la clase de icono de círculo de FontAwesome
let playerSign = "X"; // variable global, ya que la usamos en varias funciones
let runBot = true; // variable global con un valor booleano para detener el bot cuando alguien gana o hay un empate
function clickedBox(element){
if(players.classList.contains("player")){
playerSign = "O"; // Si el jugador ha elegido O
element.innerHTML = `<i class="${playerOIcon}"></i>`;
players.classList.remove("active");
}else{
element.innerHTML = `<i class="${playerXIcon}"></i>`;
players.classList.add("active");
}
element.setAttribute("id", playerSign); // Establecemos el atributo id en span/célula con el signo del jugador seleccionado
selectWinner(); // Comprobando si hay un ganador
element.style.pointerEvents = "none"; // La celda ya no se puede seleccionar
playBoard.style.pointerEvents = "none"; // Bloqueamos el campo de juego hasta que el bot haga un movimiento
let randomTimeDelay = ((Math.random() * 1000) + 200).toFixed(); // Generamos un tiempo de retardo aleatorio
setTimeout(()=>{
bot(runBot); // Llamar a la función del bot
}, randomTimeDelay);
}Aquí el jugador selecciona una celda y esta se vuelve inaccesible para volver a seleccionarla. Luego el movimiento se cambia al bot con un ligero retraso para crear el efecto de un juego real. Por lo tanto, el juego se vuelve dinámico e interesante.
Función del bot 🤖
La función de bot selecciona automáticamente la siguiente celda disponible. El bot hace un movimiento después del jugador, y sus acciones también crean la impresión de interactuar con un oponente real:
function bot(){
let array = []; // creamos una matriz vacía... almacenaremos los índices de las celdas no seleccionadas
if(runBot){ // si runBot es verdadero
playerSign = "O"; // cambiamos playerSign a O si el jugador elige X
for (let i = 0; i < allBox.length; i++) {
if(allBox[i].childElementCount == 0){ // si la celda no contiene elementos secundarios
array.push(i); // insertamos el índice de celdas no seleccionadas en la matriz
}
}
let randomBox = array[Math.floor(Math.random() * array.length)]; // seleccionamos una celda aleatoria
if(array.length > 0){
if(players.classList.contains("player")){
playerSign = "X"; // Si el jugador elige O, el bot será X
allBox[randomBox].innerHTML = `<i class="${playerXIcon}"></i>`;
allBox[randomBox].setAttribute("id", playerSign);
players.classList.add("active");
}else{
allBox[randomBox].innerHTML = `<i class="${playerOIcon}"></i>`;
players.classList.remove("active");
allBox[randomBox].setAttribute("id", playerSign);
}
selectWinner(); // Comprobando si hay un ganador
}
allBox[randomBox].style.pointerEvents = "none"; // La celda ya no se puede seleccionar
playBoard.style.pointerEvents = "auto"; // Permitimos al jugador volver a hacer clic en la celda
playerSign = "X"; // Cambio de movimiento de vuelta al jugador
}
}La función bot() añade realismo al juego, ya que el bot hace una elección automáticamente, creando la impresión de un oponente vivo. El bot selecciona una celda disponible al azar, lo que añade un elemento de sorpresa al juego.
Determinación del ganador 🏆
Después de cada turno, debes comprobar si hay un ganador. Para ello, se utiliza la función selectWinner:
function selectWinner(){
if(checkIdSign(1,2,3,playerSign) || checkIdSign(4,5,6, playerSign) || checkIdSign(7,8,9, playerSign) || checkIdSign(1,4,7, playerSign) || checkIdSign(2,5,8, playerSign) || checkIdSign(3,6,9, playerSign) || checkIdSign(1,5,9, playerSign) || checkIdSign(3,5,7, playerSign)){
runBot = false; // Detener el bot si alguien ha ganado
setTimeout(()=>{ // Mostrar el resultado después de 700 ms
resultBox.classList.add("show");
playBoard.classList.remove("show");
}, 700);
wonText.innerHTML = `Player <p>${playerSign}</p> won the game!`;
}else{
if(getIdVal(1) != "" && getIdVal(2) != "" && getIdVal(3) != "" && getIdVal(4) != "" && getIdVal(5) != "" && getIdVal(6) != "" && getIdVal(7) != "" && getIdVal(8) != "" && getIdVal(9) != ""){
runBot = false; // Detener el bot si hay empate
setTimeout(()=>{ // Mostrar el resultado después de 700 ms
resultBox.classList.add("show");
playBoard.classList.remove("show");
}, 700);
wonText.textContent = "The match ended in a draw!";
}
}
}La función selectWinner() comprueba todas las combinaciones ganadoras posibles y determina si hay un ganador. Si todas las celdas están llenas y nadie ha ganado, el juego termina en empate. Esto hace que el juego esté completo y completa lógicamente cada ronda.
Conclusión 🚀
¡Enhorabuena! Ahora ya sabes cómo crear un sencillo juego de tres en raya usando HTML, CSS y JavaScript. Hemos pasado por todos los pasos para crear una interfaz de usuario agradable, añadir estilos y crear la lógica del juego. Ahora ya sabes cómo funcionan las interacciones entre HTML, CSS y JavaScript, y cómo pueden crear juntos una aplicación web completa.
Puedes utilizar este proyecto como base para crear juegos más complejos o incluso ampliar la funcionalidad de este juego. Por ejemplo, añadir un contador de victorias, mejorar los gráficos o hacer el juego multijugador. ¡Las posibilidades son infinitas, y todo depende de tu imaginación y creatividad!
Para obtener el código fuente completo y posiblemente mejoras adicionales, echa un vistazo a nuestro GitHub.
Si tienes alguna pregunta, no dudes en preguntar. ¡Buena suerte en la programación y que tus proyectos sean siempre tan interesantes y emocionantes! 👊🌟
