Use this file to discover all available pages before exploring further.
Beyond the algorithmic puzzles, the Area Juegos section of the course produced four additional browser-based projects that cover a wide range of JavaScript concepts — from classic game logic and combinatorial backtracking to DOM manipulation, event-driven programming, and CSS animation. Each project runs entirely in the browser: no build tools, no frameworks, just plain HTML, CSS, and vanilla JavaScript.
Rock-Paper-Scissors
Player vs. computer with modular arithmetic win detection and dynamic CSS feedback.
Knight's Tour
Visit all 64 squares of a chessboard exactly once using recursive backtracking with 8-directional L-shaped moves.
Avatar Game
Avatar: The Last Airbender–themed combat game with character selection, attack buttons, and dynamic result messages.
Web Viva Login Form
Animated login UI with a CSS gradient background, floating squares, and JavaScript form validation.
A clean player-vs-computer implementation of the classic game. The player clicks one of three buttons (✊ Piedra, ✋ Papel, ✌️ Tijera), the computer picks at random, and the winner is determined instantly with a visual CSS class applied to the game container.
Choices are mapped to integers — 1 = Piedra, 2 = Papel, 3 = Tijera — and the win condition uses a single modular-arithmetic expression that avoids a verbose chain of if-else comparisons:
juego.js — core game logic
function jugar(eleccionUsuario) { // 1 = piedra, 2 = papel, 3 = tijera let jugador = eleccionUsuario; let pc = aleatorio(1, 3); // computer picks randomly let textoJugador = document.getElementById("eleccion-jugador"); let textoPC = document.getElementById("eleccion-pc"); let textoResultado = document.getElementById("resultado-final"); let container = document.querySelector(".game-container"); const opcionesTexto = { 1: "✊ Piedra", 2: "✋ Papel", 3: "✌️ Tijera", }; textoJugador.innerText = "Tu elección: " + opcionesTexto[jugador]; textoPC.innerText = "Elección PC: " + opcionesTexto[pc]; let estado = ""; let mensaje = ""; if (jugador === pc) { estado = "empate"; mensaje = "¡EMPATE! 🤝"; } else if ((jugador - pc + 3) % 3 === 1) { // Modular arithmetic: player beats computer when (jugador - pc + 3) % 3 === 1 // 1-3+3=1 → Piedra beats Tijera ✓ // 2-1+3=4 → 4%3=1 → Papel beats Piedra ✓ // 3-2+3=4 → 4%3=1 → Tijera beats Papel ✓ estado = "ganaste"; mensaje = "¡GANASTE! 🎉"; } else { estado = "perdiste"; mensaje = "PERDISTE ❌"; } textoResultado.innerText = mensaje; textoResultado.className = estado; // Apply win/lose/draw CSS class to the container for visual feedback container.className = "game-container " + estado;}
The Knight’s Tour asks: can a chess knight visit every square on an 8×8 board exactly once? The answer is yes — and this project solves it using recursive backtracking starting from position (0, 0).
A knight always moves in an “L”: two squares in one direction, one in the perpendicular. All eight possible deltas are pre-encoded as parallel dx/dy arrays:
saltoDelCaballo.js — movement vectors
const N = 8;// dx = row offset, dy = column offset for each of the 8 knight movesconst dx = [ 2, 1, -1, -2, -2, -1, 1, 2];const dy = [ 1, 2, 2, 1, -1, -2, -2, -1];
The board is an N×N matrix initialised to -1 (unvisited). A move is valid only if the target cell is within bounds and has not been visited yet:
saltoDelCaballo.js — board setup and move validation
function crearTablero() { const tablero = []; for (let i = 0; i < N; i++) { tablero.push(new Array(N).fill(-1)); } return tablero;}function esValido(x, y, tablero) { return ( x >= 0 && y >= 0 && // not out-of-bounds (top / left) x < N && y < N && // not out-of-bounds (bottom / right) tablero[x][y] === -1 // cell not yet visited );}
salto() records the current move number in the board cell, recurses to the next step, and resets to -1 if that path leads to a dead end:
saltoDelCaballo.js — recursive backtracking
function salto(x, y, paso, tablero) { // Base case: all N*N squares visited if (paso === N * N) return true; for (let i = 0; i < 8; i++) { const nx = x + dx[i]; const ny = y + dy[i]; if (esValido(nx, ny, tablero)) { tablero[nx][ny] = paso; // mark this step if (salto(nx, ny, paso + 1, tablero)) { return true; // solution found — propagate up } tablero[nx][ny] = -1; // backtrack — unmark the cell } } return false; // no valid move from this position}
The knight starts at (0, 0) with step 0 pre-marked, and salto is first called with paso = 1. The solution is printed to the console as a numbered grid showing the visit order of each cell, with execution time measured using Date.now().
Inspired by Avatar: The Last Airbender, this game pits the player’s chosen character against a randomly selected computer opponent in a combat system that mirrors Rock-Paper-Scissors.
Rather than toggling a pre-existing element, each round appends a new <p> to the #mensajes section using createElement and appendChild, building a running combat log:
avatar.js — dynamic message log
function crearMensaje(resultado) { let seccionMensaje = document.getElementById("mensajes"); let parrafo = document.createElement("p"); parrafo.innerHTML = "Tu personaje atacó con " + ataqueJugador + ", el personaje enemigo atacó con " + ataqueEnemigo + " - " + resultado; seccionMensaje.appendChild(parrafo);}
The player picks a character via radio buttons and clicks Seleccionar. The seleccionarPersonajeJugador() function reads which radio is checked, updates the display, and immediately triggers seleccionarPersonajeEnemigo() to assign a random opponent. The whole game is bootstrapped via a window load event:
avatar.js — player and enemy selection
function seleccionarPersonajeJugador() { const spanPersonajeJugador = document.getElementById("personaje-jugador"); if (inputZuko.checked) spanPersonajeJugador.innerHTML = "Zuko"; else if (inputAang.checked) spanPersonajeJugador.innerHTML = "Aang"; else if (inputKatara.checked) spanPersonajeJugador.innerHTML = "Katara"; else if (inputToph.checked) spanPersonajeJugador.innerHTML = "Toph"; else { alert("No seleccionaste ningún personaje"); return; } seleccionarPersonajeEnemigo(); // random enemy assigned immediately}function seleccionarPersonajeEnemigo() { const personajeAleatorio = aleatorio(1, 4); const spanPersonajeEnemigo = document.getElementById("personaje-enemigo"); switch (personajeAleatorio) { case 1: spanPersonajeEnemigo.innerHTML = "Zuko"; break; case 2: spanPersonajeEnemigo.innerHTML = "Aang"; break; case 3: spanPersonajeEnemigo.innerHTML = "Katara"; break; case 4: spanPersonajeEnemigo.innerHTML = "Toph"; break; }}// Entry point — wire up all event listeners once the page is fully loadedwindow.addEventListener("load", iniciarJuego);
This project showcases a visually animated login UI — the focus here is on CSS effects combined with JavaScript form validation. The page features a gradient background, five floating animated squares, and a centered login card.
The visual effect is created with .color divs for the gradient backdrop and .square divs (with CSS custom property --i) for the floating animation. All squares are siblings of the main .container:
The JavaScript intercepts the form’s submit event, prevents the default page reload, and checks hard-coded credentials. A successful login navigates to exito.html; a failed attempt shows an error message that auto-hides after 3 seconds:
codigo.js — login validation with timed error feedback
document.addEventListener("DOMContentLoaded", function () { const loginForm = document.querySelector("form"); const mensajeError = document.getElementById("mensaje-error"); loginForm.addEventListener("submit", function (event) { event.preventDefault(); // stop the browser from reloading the page const inputs = loginForm.querySelectorAll("input"); const usuario = inputs[0].value; const password = inputs[1].value; if (usuario === "admin" && password === "1234") { window.location.href = "exito.html"; // redirect on success } else { mensajeError.classList.remove("hidden"); // show error banner setTimeout(() => { mensajeError.classList.add("hidden"); // auto-hide after 3 s }, 3000); } });});
The hidden CSS class toggling pattern keeps the logic clean — the error element always exists in the DOM, and visibility is controlled purely through class names.
All four projects are self-contained and require no server or build step. Open each project’s index.html directly in your browser (via File → Open or by double-clicking in your file manager) and everything will work out of the box. For the Knight’s Tour (saltoDelCaballo.js), open your browser’s DevTools console to see the solved board grid printed as output.