diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..331d387 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +.git +Dockerfile diff --git a/css/piedra-papel-tijera.css b/css/piedra-papel-tijera.css index 26be4a6..227e140 100644 --- a/css/piedra-papel-tijera.css +++ b/css/piedra-papel-tijera.css @@ -142,6 +142,53 @@ body { margin-bottom: 1rem; } +.game-btn { + font-size: 2.5rem; + padding: 10px; + border: var(--borde); /* Usamos tu variable de borde */ + border-radius: 50%; + background: var(--color-secundario); + color: var(--color-texto); + cursor: pointer; + transition: transform var(--transicion), background var(--transicion), box-shadow var(--transicion); + width: 80px; + height: 80px; + display: flex; + align-items: center; + justify-content: center; + margin: 0.3rem; +} + +.game-btn:hover { + transform: scale(1.15); + box-shadow: 0 0 10px var(--color-acento); + background: var(--color-fondo); +} + +/* Clase que añade el JS al hacer click */ +.game-btn.seleccionada { + box-shadow: 0 0 20px var(--color-acento); + transform: scale(1.2); + border-color: var(--color-acento); +} + +.game-btn-pc { + font-size: 2.5rem; + opacity: 0.3; + width: 80px; + height: 80px; + display: flex; + align-items: center; + justify-content: center; + transition: opacity 0.3s ease, transform 0.3s ease; +} + +/* Clase para resaltar la elección del PC */ +.pc-elegido { + opacity: 1; + transform: scale(1.2); +} + /* Imágenes */ .btn-img { width: 70px; @@ -175,6 +222,95 @@ body { margin-top: 1rem; } +/* ── Mapa SVG interactivo ─────────────────────────────────── */ +.mapa-svg { + width: 90%; + max-width: 320px; + margin-top: 1rem; + overflow: visible; +} + +/* Líneas de conexión */ +.conexion { + stroke: var(--color-primario); + stroke-width: 1.5; + opacity: 0.3; + transition: stroke 0.25s, stroke-width 0.25s, opacity 0.25s; +} + +/* Nodos: círculo base */ +.nodo circle { + fill: var(--color-secundario); + stroke: var(--color-primario); + stroke-width: 2; + transition: fill 0.25s, stroke 0.25s, filter 0.25s, opacity 0.25s; +} + +.nodo-emoji { + font-size: 20px; + pointer-events: none; + user-select: none; +} + +.nodo-label { + font-size: 10px; + fill: var(--color-texto); + font-family: var(--fuente-base); + pointer-events: none; + transition: opacity 0.25s, fill 0.25s; +} + +/* ── Estados al pasar el ratón sobre un botón ─────────────── */ + +/* Atenúa todas las conexiones cuando el mapa está activo */ +.mapa-activo .conexion { + opacity: 0.1; +} + +/* Resalta las conexiones activas (las del botón en hover) */ +.mapa-activo .conexion.conexion-activa { + stroke: var(--color-acento); + stroke-width: 2.5; + opacity: 1; +} + +/* Nodo origen (la opción sobre la que se hace hover) */ +.nodo.nodo-origen circle { + stroke: var(--color-acento); + stroke-width: 3; +} + +/* Nodos vencidos: se iluminan en dorado */ +.nodo.nodo-vencido circle { + fill: var(--color-acento); + stroke: var(--color-acento); + filter: drop-shadow(0 0 7px var(--color-acento)); +} + +.nodo.nodo-vencido .nodo-label { + fill: var(--color-acento); + font-weight: 700; + opacity: 1; +} + +/* El resto de nodos se atenúa */ +.mapa-activo .nodo:not(.nodo-vencido):not(.nodo-origen) circle { + opacity: 0.35; +} +.mapa-activo .nodo:not(.nodo-vencido):not(.nodo-origen) .nodo-label { + opacity: 0.35; +} + +/* Texto de pista debajo del mapa */ +.mapa-hint-texto { + font-size: 0.8rem; + color: var(--color-acento); + font-weight: 600; + min-height: 1.2rem; + margin-top: 0.4rem; + transition: opacity 0.25s; +} + /* Texto */ .grande { font-size: 1.2rem; diff --git a/css/style.css b/css/style.css index a7441ec..6151c48 100644 --- a/css/style.css +++ b/css/style.css @@ -421,6 +421,7 @@ a:hover { text-decoration: underline; } color: var(--text-muted); } +<<<<<<< HEAD .md-body table { border-collapse: collapse; width: 100%; margin: 1rem 0 1.2rem; font-size: .88rem; } .md-body th { background: #2d2d2d; color: var(--accent-2); text-align: left; padding: .55rem .8rem; border: 1px solid var(--border); } .md-body td { padding: .45rem .8rem; border: 1px solid var(--border); } @@ -667,6 +668,18 @@ a:hover { text-decoration: underline; } margin-left: auto; margin-right: auto; padding: 2rem 1.5rem; +======= +#countdown { + font-size: 1.2rem; + color: var(--color-acento); + font-weight: bold; +} + +/* Footer */ +footer { + border-top: 1px solid var(--color-borde); + color: var(--color-acento); +>>>>>>> 0504d24833e730c5367d475ac407b45970029627 } .quiz-header { margin-bottom: 2rem; text-align: center; } diff --git a/js/codigo.js b/js/codigo.js index 734f814..7b33332 100644 --- a/js/codigo.js +++ b/js/codigo.js @@ -12,16 +12,55 @@ function calcularEdad(fechaNacimiento) { const fechaNacimientoAndrea = "2001-01-14"; const edadAndrea = calcularEdad(fechaNacimientoAndrea); -document.getElementById("edad-andrea").textContent = edadAndrea; +if (document.getElementById("edad-andrea")) document.getElementById("edad-andrea").textContent = edadAndrea; const fechaNacimientoGemelos = "2004-11-24"; const edadGemelos = calcularEdad(fechaNacimientoGemelos); -document.getElementById("edad-gemelos").textContent = edadGemelos; +if (document.getElementById("edad-gemelos")) document.getElementById("edad-gemelos").textContent = edadGemelos; const fechaPandemia = "2020-03-11"; const edadPandemia = calcularEdad(fechaPandemia); -document.getElementById("edad-pandemia").textContent = edadPandemia; +if (document.getElementById("edad-pandemia")) document.getElementById("edad-pandemia").textContent = edadPandemia; // añade el año actual al pie de página -document.getElementById("anio").textContent = new Date().getFullYear(); +if (document.getElementById("anio")) document.getElementById("anio").textContent = new Date().getFullYear(); +// PROYECTOS + +/** + * Script para la cuenta atrás del examen TAI AGE + * Fecha: 23 de mayo de 2026 + */ + +document.addEventListener('DOMContentLoaded', () => { + // Definimos la fecha objetivo (23 de mayo de 2026 a las 09:00) + const examenDate = new Date("May 23, 2026 09:00:00").getTime(); + const countdownContainer = document.getElementById("countdown"); + + // Si el contenedor no existe en esta página, no ejecutamos el intervalo + if (!countdownContainer) return; + + const updateTimer = () => { + const now = new Date().getTime(); + const diff = examenDate - now; + + if (diff < 0) { + countdownContainer.innerHTML = "¡Día del examen!"; + clearInterval(timerInterval); + return; + } + + // Cálculos de tiempo + const d = Math.floor(diff / (1000 * 60 * 60 * 24)); + const h = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); + const m = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); + const s = Math.floor((diff % (1000 * 60)) / 1000); + + // Formateamos el texto + countdownContainer.innerHTML = `Examen en: ${d}d ${h}h ${m}m ${s}s`; + }; + + // Ejecutamos una vez al cargar y luego cada segundo + updateTimer(); + const timerInterval = setInterval(updateTimer, 1000); +}); \ No newline at end of file diff --git a/js/piedra.js b/js/piedra.js index a012ede..6531089 100644 --- a/js/piedra.js +++ b/js/piedra.js @@ -15,6 +15,12 @@ function inicializarDOM() { DOM.resultado = document.getElementById("resultado"); DOM.opciones = document.querySelectorAll(".btn-img"); DOM.toggleTema = document.getElementById("toggle-tema"); + + DOM.eleccionordenador = document.getElementById("eleccionordenador"); + DOM.resultado = document.getElementById("resultado"); + + DOM.opciones = document.querySelectorAll(".game-btn"); + DOM.toggleTema = document.getElementById("toggle-tema"); } function ocultarJuego() { @@ -58,33 +64,112 @@ function reproducirSonido() { } function quienGana(opcionJugador) { - const opciones = ["piedra", "papel", "tijera", "lagarto", "spock"]; - const opcionOrdenador = opciones[Math.floor(Math.random() * opciones.length)]; + // 1. Definir opciones y elección aleatoria del ordenador + const opciones = ["piedra", "papel", "tijera", "lagarto", "spock"]; + const opcionOrdenador = opciones[Math.floor(Math.random() * opciones.length)]; - DOM.eleccionjugador.textContent = opcionJugador; - DOM.eleccionordenador.textContent = opcionOrdenador; + // Diccionario de emojis para actualizar los textos de pantalla + const emojis = { + piedra: "🪨", + papel: "📄", + tijera: "✂️", + lagarto: "🦎", + spock: "🖖" + }; - const ganaJugador = - (opcionJugador === "piedra" && ["tijera", "lagarto"].includes(opcionOrdenador)) || - (opcionJugador === "papel" && ["piedra", "spock"].includes(opcionOrdenador)) || - (opcionJugador === "tijera" && ["papel", "lagarto"].includes(opcionOrdenador)) || - (opcionJugador === "lagarto" && ["papel", "spock"].includes(opcionOrdenador)) || - (opcionJugador === "spock" && ["piedra", "tijera"].includes(opcionOrdenador)); + // 2. Actualizar visualmente la elección en el DOM + DOM.eleccionjugador.textContent = `Elegiste: ${emojis[opcionJugador]}`; + DOM.eleccionordenador.textContent = `PC eligió: ${emojis[opcionOrdenador]}`; - if (opcionJugador === opcionOrdenador) { - DOM.resultado.textContent = "Empate"; - animarResultado("empate"); - } else if (ganaJugador) { - DOM.resultado.textContent = "Ganaste"; - DOM.puntosPersona.textContent = (parseInt(DOM.puntosPersona.textContent) + 1).toString(); - animarResultado("victoria"); - } else { - DOM.resultado.textContent = "Perdiste"; - DOM.puntosOrdenador.textContent = (parseInt(DOM.puntosOrdenador.textContent) + 1).toString(); - animarResultado("derrota"); + // 3. Resaltar el icono del ordenador (opcional, para dar feedback visual) + document.querySelectorAll('.game-btn-pc').forEach(el => el.classList.remove('pc-elegido')); + const pcIcono = document.getElementById(`pc-${opcionOrdenador}`); + if (pcIcono) { + pcIcono.classList.add('pc-elegido'); + } + + // 4. Lógica de victoria (Reglas extendidas de Sheldon Cooper) + // El jugador gana si su opción vence a la del ordenador + const ganaJugador = + (opcionJugador === "piedra" && (opcionOrdenador === "tijera" || opcionOrdenador === "lagarto")) || + (opcionJugador === "papel" && (opcionOrdenador === "piedra" || opcionOrdenador === "spock")) || + (opcionJugador === "tijera" && (opcionOrdenador === "papel" || opcionOrdenador === "lagarto")) || + (opcionJugador === "lagarto" && (opcionOrdenador === "papel" || opcionOrdenador === "spock")) || + (opcionJugador === "spock" && (opcionOrdenador === "piedra" || opcionOrdenador === "tijera")); + + // 5. Determinar resultado y actualizar puntuación + if (opcionJugador === opcionOrdenador) { + DOM.resultado.textContent = "¡Empate! 🤝"; + animarResultado("empate"); + } else if (ganaJugador) { + DOM.resultado.textContent = "¡Has ganado! 🏆"; + // Convertimos a número, sumamos 1 y devolvemos a texto + let puntosActuales = parseInt(DOM.puntosPersona.textContent); + DOM.puntosPersona.textContent = (puntosActuales + 1).toString(); + animarResultado("victoria"); + } else { + DOM.resultado.textContent = "Has perdido 😢"; + let puntosPC = parseInt(DOM.puntosOrdenador.textContent); + DOM.puntosOrdenador.textContent = (puntosPC + 1).toString(); + animarResultado("derrota"); + } + + // 6. Efecto de sonido + reproducirSonido(); +} + +// Reglas: qué opciones vence cada elección +const vence = { + piedra: ["tijera", "lagarto"], + papel: ["piedra", "spock"], + tijera: ["papel", "lagarto"], + lagarto: ["papel", "spock"], + spock: ["piedra", "tijera"] +}; + +const nombresMapa = { + piedra: "Piedra", papel: "Papel", tijera: "Tijera", + lagarto: "Lagarto", spock: "Spock" +}; + +function activarMapaHover(choice) { + const mapa = document.getElementById("mapa-juego"); + if (!mapa) return; + + mapa.classList.add("mapa-activo"); + + // Marcar nodo origen + const origen = document.getElementById(`nodo-${choice}`); + if (origen) origen.classList.add("nodo-origen"); + + // Marcar nodos vencidos y conexiones activas + vence[choice].forEach(beaten => { + const nodo = document.getElementById(`nodo-${beaten}`); + if (nodo) nodo.classList.add("nodo-vencido"); + }); + mapa.querySelectorAll(`.conexion[data-from="${choice}"]`) + .forEach(l => l.classList.add("conexion-activa")); + + // Texto de pista + const hint = document.getElementById("mapa-hint"); + if (hint) { + const vencidos = vence[choice].map(v => nombresMapa[v]).join(" y "); + hint.textContent = `${nombresMapa[choice]} vence a: ${vencidos}`; } +} - reproducirSonido(); +function desactivarMapaHover() { + const mapa = document.getElementById("mapa-juego"); + if (!mapa) return; + + mapa.classList.remove("mapa-activo"); + mapa.querySelectorAll(".nodo-origen, .nodo-vencido") + .forEach(n => n.classList.remove("nodo-origen", "nodo-vencido")); + mapa.querySelectorAll(".conexion-activa") + .forEach(l => l.classList.remove("conexion-activa")); + + const hint = document.getElementById("mapa-hint"); + if (hint) hint.textContent = ""; } function configurarEventos() { @@ -98,6 +183,8 @@ function configurarEventos() { op.classList.add("seleccionada"); quienGana(op.id); }); + op.addEventListener("mouseenter", () => activarMapaHover(op.dataset.choice)); + op.addEventListener("mouseleave", desactivarMapaHover); }); } diff --git a/piedra-papel-tijera.html b/piedra-papel-tijera.html index 7276174..4b54da4 100644 --- a/piedra-papel-tijera.html +++ b/piedra-papel-tijera.html @@ -4,7 +4,6 @@ Piedra · Papel · Tijera · Lagarto · Spock - @@ -27,7 +26,6 @@
-

Puntuación Jugador:

@@ -35,23 +33,79 @@
- Piedra - Papel - Tijera - Lagarto - Spock + + + + +

¿Qué eliges?

-

Resultado

- Esquema del juego + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 🖖 + Spock + + + + + 🪨 + Piedra + + + + + 🦎 + Lagarto + + + + + ✂️ + Tijera + + + + + 📄 + Papel + + + +

-

Puntuación Ordenador:

@@ -59,11 +113,11 @@
- Piedra - Papel - Tijera - Lagarto - Spock +
🪨
+
📄
+
✂️
+
🦎
+
🖖

Elección del ordenador

@@ -71,11 +125,11 @@
-