diff --git a/intermedio/ejercicios/65-timer-kickboxing/resoluciones/maria-montepeque/index.html b/intermedio/ejercicios/65-timer-kickboxing/resoluciones/maria-montepeque/index.html new file mode 100644 index 0000000..6a8aacb --- /dev/null +++ b/intermedio/ejercicios/65-timer-kickboxing/resoluciones/maria-montepeque/index.html @@ -0,0 +1,21 @@ + + + + + + Timer de rounds kickboxing + + + +
+

Timer de rounds

+

Round 1 - 3s

+
+ + + +
+
+ + + diff --git a/intermedio/ejercicios/65-timer-kickboxing/resoluciones/maria-montepeque/maria-montepeque.js b/intermedio/ejercicios/65-timer-kickboxing/resoluciones/maria-montepeque/maria-montepeque.js new file mode 100644 index 0000000..c7a774c --- /dev/null +++ b/intermedio/ejercicios/65-timer-kickboxing/resoluciones/maria-montepeque/maria-montepeque.js @@ -0,0 +1,138 @@ +// 65. Timer de rounds kickboxing - Resolucion Maria Montepeque + +const configTimer = { duracionRoundSeg: 3, duracionDescansoSeg: 2, totalRounds: 2 }; + +function esConfigValida(config) { + return ( + config && + Number.isInteger(config.duracionRoundSeg) && + config.duracionRoundSeg > 0 && + Number.isInteger(config.duracionDescansoSeg) && + config.duracionDescansoSeg > 0 && + Number.isInteger(config.totalRounds) && + config.totalRounds > 0 + ); +} + +function crearEstadoInicial(config) { + return { + faseActual: 'round', + roundActual: 1, + segundosRestantes: config.duracionRoundSeg, + corriendo: false, + finalizado: false + }; +} + +function avanzarUnSegundo(estado, config) { + if (estado.finalizado || !estado.corriendo) return estado; + + if (estado.segundosRestantes > 1) { + return { ...estado, segundosRestantes: estado.segundosRestantes - 1 }; + } + + if (estado.faseActual === 'round') { + if (estado.roundActual >= config.totalRounds) { + return { ...estado, faseActual: 'finalizado', segundosRestantes: 0, corriendo: false, finalizado: true }; + } + return { ...estado, faseActual: 'descanso', segundosRestantes: config.duracionDescansoSeg }; + } + + return { ...estado, faseActual: 'round', roundActual: estado.roundActual + 1, segundosRestantes: config.duracionRoundSeg }; +} + +function pausarTimer(estado) { + return { ...estado, corriendo: false }; +} + +function reanudarTimer(estado) { + return estado.finalizado ? estado : { ...estado, corriendo: true }; +} + +function reiniciarTimer(config) { + return crearEstadoInicial(config); +} + +function simularSegundos(config, cantidadSegundos) { + if (!esConfigValida(config)) { + return { valido: false, motivo: 'configuracion invalida (duraciones o rounds deben ser enteros positivos)' }; + } + + let estado = reanudarTimer(crearEstadoInicial(config)); + const historial = [{ ...estado }]; + + for (let i = 0; i < cantidadSegundos; i += 1) { + estado = avanzarUnSegundo(estado, config); + historial.push({ ...estado }); + } + + return { valido: true, config, historial, estadoFinal: estado }; +} + +function renderizarEstado(estado) { + if (typeof document === 'undefined') return; + const elemento = document.querySelector('#timer-estado'); + if (!elemento) return; + + elemento.textContent = estado.finalizado + ? 'Finalizado' + : `${estado.faseActual === 'round' ? 'Round' : 'Descanso'} ${estado.roundActual} - ${estado.segundosRestantes}s`; +} + +function inicializarTimer(config) { + if (typeof document === 'undefined') return; + + let estado = crearEstadoInicial(config); + let intervalo = null; + renderizarEstado(estado); + + const botonIniciar = document.querySelector('#boton-iniciar'); + const botonPausar = document.querySelector('#boton-pausar'); + const botonReiniciar = document.querySelector('#boton-reiniciar'); + + function tick() { + estado = avanzarUnSegundo(estado, config); + renderizarEstado(estado); + if (estado.finalizado && intervalo) { + clearInterval(intervalo); + intervalo = null; + } + } + + if (botonIniciar) { + botonIniciar.addEventListener('click', () => { + if (estado.finalizado) return; + estado = reanudarTimer(estado); + if (!intervalo) intervalo = setInterval(tick, 1000); + }); + } + + if (botonPausar) { + botonPausar.addEventListener('click', () => { + estado = pausarTimer(estado); + if (intervalo) { + clearInterval(intervalo); + intervalo = null; + } + }); + } + + if (botonReiniciar) { + botonReiniciar.addEventListener('click', () => { + if (intervalo) { + clearInterval(intervalo); + intervalo = null; + } + estado = reiniciarTimer(config); + renderizarEstado(estado); + }); + } +} + +console.log('Caso 1: timer de 2 rounds (3s round, 2s descanso), se simulan 8 segundos hasta finalizar'); +console.log(JSON.stringify(simularSegundos(configTimer, 8), null, 2)); + +console.log('\nCaso 2: configuracion invalida (duracion de round en 0)'); +console.log(JSON.stringify(simularSegundos({ duracionRoundSeg: 0, duracionDescansoSeg: 2, totalRounds: 2 }, 5), null, 2)); + +inicializarTimer(configTimer); diff --git a/intermedio/ejercicios/65-timer-kickboxing/resoluciones/maria-montepeque/style.css b/intermedio/ejercicios/65-timer-kickboxing/resoluciones/maria-montepeque/style.css new file mode 100644 index 0000000..57fb867 --- /dev/null +++ b/intermedio/ejercicios/65-timer-kickboxing/resoluciones/maria-montepeque/style.css @@ -0,0 +1,33 @@ +body { + font-family: sans-serif; + background-color: #10131a; + color: #eef1f7; + display: flex; + justify-content: center; + padding: 3rem; +} + +.timer-container { + text-align: center; +} + +#timer-estado { + font-size: 1.8rem; + font-weight: bold; + margin: 1rem 0; +} + +.botones { + display: flex; + gap: 0.5rem; + justify-content: center; +} + +.botones button { + padding: 0.6rem 1rem; + border-radius: 4px; + border: none; + background-color: #4c9aff; + color: #10131a; + cursor: pointer; +}