Untitled
17 hours ago in Plain Text
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Pizarra de División Mágica</title>
<style>
:root {
--celda: 75px;
--turquesa: #00796b;
--fondo-pizarra: #ffffff;
--azul-edu: #1976d2;
--naranja-edu: #f57c00;
--texto: #263238;
--fuente-numeros: 'Courier New', monospace;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: var(--turquesa);
display: flex;
justify-content: center;
padding: 30px 10px;
margin: 0;
}
#pizarra {
background: var(--fondo-pizarra);
padding: 40px;
border-radius: 30px;
box-shadow: 0 25px 70px rgba(0,0,0,0.5);
width: 95%;
max-width: 1150px;
min-height: 750px;
display: flex;
flex-direction: column;
border: 10px solid rgba(255,255,255,0.3);
box-sizing: border-box;
}
#instrucciones {
background: var(--azul-edu);
color: white;
padding: 25px;
border-radius: 20px;
text-align: center;
font-size: 30px;
margin-bottom: 40px;
font-weight: bold;
box-shadow: 0 6px 15px rgba(0,0,0,0.2);
min-height: 40px;
}
.fase-inicio { text-align: center; margin-top: 120px; }
.input-grande {
font-size: 55px; padding: 20px; width: 450px; text-align: center;
border: 6px solid var(--azul-edu); border-radius: 25px; outline: none;
color: var(--texto); box-shadow: 0 10px 25px rgba(0,0,0,0.1);
}
#contenedor-principal { display: none; grid-template-columns: 1fr 320px; gap: 50px; }
#tablero-division { display: grid; grid-template-columns: auto auto; justify-content: flex-end; }
.col-izq { display: flex; flex-direction: column; align-items: flex-end; border-right: 5px solid #e0e0e0; padding-right: 35px; }
.col-der { display: flex; flex-direction: column; align-items: flex-start; padding-left: 35px; }
.fila { display: flex; height: var(--celda); }
.celda {
width: var(--celda); height: var(--celda); display: flex; justify-content: center;
align-items: center; font-size: 55px; position: relative; font-weight: bold;
font-family: var(--fuente-numeros); color: var(--texto);
}
.celda-coma { width: 15px; height: var(--celda); display: flex; justify-content: center; align-items: center; font-size: 55px; position: relative; overflow: visible; font-weight: bold; color: #e74c3c; }
#divisor-box { border-left: 8px solid #333; border-bottom: 8px solid #333; padding: 10px 30px; display: flex; height: var(--celda); align-items: center; font-size: 60px; font-family: var(--fuente-numeros); font-weight: bold; }
#cociente-box { padding: 15px 30px; display: flex; height: var(--celda); align-items: center; font-size: 60px; color: var(--azul-edu); font-family: var(--fuente-numeros); font-weight: bold; }
#panel-preguntas { background: #fdfefe; border: 5px dashed #bdc3c7; border-radius: 25px; padding: 30px; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 200px; }
.caja-v { width: 65px; height: 75px; font-size: 50px; text-align: center; border: 5px solid var(--naranja-edu); outline: none; background: #fffbe6; border-radius: 12px; }
.caja-v.grande { width: 220px; }
.comita-arqueo { position: absolute; top: -45px; color: #e74c3c; font-size: 75px; font-weight: bold; }
.digito-rojo { color: #e74c3c; font-weight: bold; }
#btn-restaurar {
display: none; margin: 50px auto 20px auto; padding: 25px 60px; font-size: 32px;
background: #27ae60; color: white; border: none; border-radius: 25px; cursor: pointer;
font-weight: bold; box-shadow: 0 10px 0 #1e8449; transition: all 0.1s; text-transform: uppercase;
}
</style>
</head>
<body>
<div id="pizarra">
<div id="instrucciones">Escribe el dividendo para empezar</div>
<div id="fase-setup" class="fase-inicio">
<input type="text" id="input-datos" class="input-grande" autocomplete="off">
</div>
<div id="contenedor-principal">
<div id="tablero-division">
<div class="col-izq">
<div id="fila-dividendo" class="fila"></div>
<div id="area-restos"></div>
</div>
<div class="col-der">
<div id="divisor-box"></div>
<div id="cociente-box"></div>
</div>
</div>
<div id="panel-preguntas"></div>
</div>
<button id="btn-restaurar" onclick="restaurar()">Nueva División</button>
</div>
<script>
let st = {};
function resetState() {
st = { fase: "DNDO", dndoO: "", dsorO: "", dndoL: "", dsorL: "", factor: 1, idx: 0, restoAct: "", restoNecArr: [], digRestoIdx: 0, filaAct: null, comaP: false, cerosFaltan: 0 };
}
const inputDat = document.getElementById("input-datos");
const info = document.getElementById("instrucciones");
const panelPreguntas = document.getElementById("panel-preguntas");
inputDat.focus();
inputDat.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
const v = inputDat.value.trim();
if (!v) return;
if (st.fase === "DNDO") {
st.dndoO = v.replace(".", ",");
st.fase = "DSOR"; inputDat.value = "";
info.innerText = "Ahora escribe el divisor";
} else if (st.fase === "DSOR") {
st.dsorO = v.replace(".", ",");
arrancarPizarra();
}
}
});
function arrancarPizarra() {
document.getElementById("fase-setup").style.display = "none";
document.getElementById("contenedor-principal").style.display = "grid";
dibujarFila(document.getElementById("fila-dividendo"), st.dndoO);
document.getElementById("divisor-box").innerText = st.dsorO;
let decs = st.dsorO.includes(",") ? st.dsorO.split(",")[1].length : 0;
st.factor = Math.pow(10, decs);
if (st.factor > 1) {
st.fase = "MULTI";
info.innerText = "¿Por cuánto multiplicas para quitar la coma?";
crearCaja(panelPreguntas, true);
} else { limpiarNumeros(); }
}
function limpiarNumeros() {
let nDndo = parseFloat(st.dndoO.replace(",", "."));
let nDsor = parseFloat(st.dsorO.replace(",", "."));
let dndoFinalStr = (nDndo * st.factor).toLocaleString('es-ES', {useGrouping:false}).replace(".", ",");
st.dsorL = (nDsor * st.factor).toString();
document.getElementById("divisor-box").innerText = st.dsorL;
let dndoBase = st.dndoO.replace(",", "");
dibujarFila(document.getElementById("fila-dividendo"), dndoBase);
st.cerosFaltan = dndoFinalStr.replace(",", "").length - dndoBase.length;
if (st.cerosFaltan > 0) {
st.fase = "ANADIR_CEROS";
info.innerText = "Añade los ceros necesarios al dividendo";
crearCeldaConCaja();
} else { finalizarLimpieza(dndoFinalStr); }
}
function crearCeldaConCaja() {
const nuevaCelda = document.createElement("div");
nuevaCelda.className = "celda";
document.getElementById("fila-dividendo").appendChild(nuevaCelda);
crearCaja(nuevaCelda);
}
function finalizarLimpieza(valor) {
st.dndoL = valor;
st.fase = "ARQUEO";
info.innerText = "¿Cuántas cifras separas?";
panelPreguntas.innerHTML = "";
crearCaja(panelPreguntas);
}
function dibujarFila(cont, num) {
cont.innerHTML = "";
for (let char of num) {
const d = document.createElement("div");
d.className = (char === ",") ? "celda-coma" : "celda";
d.innerText = char;
cont.appendChild(d);
}
}
function crearCaja(cont, esp = false) {
const c = document.createElement("input");
c.className = "caja-v" + (esp ? " grande" : "");
c.onkeydown = (e) => { if (e.key === "Enter") validar(c); };
cont.appendChild(c); c.focus();
}
function validar(caja) {
const v = caja.value.trim();
const dndoSinC = st.dndoL ? st.dndoL.replace(",", "") : "";
if (st.fase === "MULTI") {
if (v == st.factor) { caja.remove(); limpiarNumeros(); } else caja.value = "";
}
else if (st.fase === "ANADIR_CEROS") {
if (v === "0") {
const p = caja.parentElement; p.innerText = "0"; p.classList.add("digito-rojo");
st.cerosFaltan--;
if (st.cerosFaltan > 0) { crearCeldaConCaja(); }
else {
let res = ""; document.getElementById("fila-dividendo").childNodes.forEach(n => res += n.innerText);
finalizarLimpieza(res);
}
} else caja.value = "";
}
else if (st.fase === "ARQUEO") {
let i = 1;
while (parseInt(dndoSinC.substring(0, i)) < parseInt(st.dsorL) && i < dndoSinC.length) i++;
if (v == i) {
caja.remove(); st.idx = i;
st.restoAct = dndoSinC.substring(0, i);
ponerArqueo(i); pedirCociente();
} else caja.value = "";
}
else if (st.fase === "COCI") {
const qCorrecto = Math.floor(parseInt(st.restoAct) / parseInt(st.dsorL));
if (v == qCorrecto) {
caja.replaceWith(crearTexto(v));
// Lógica corregida: si es 0 y no hay más cifras, termina.
if (v == "0" && st.idx >= dndoSinC.length) {
finalizarOperacion();
} else {
let rStr = (parseInt(st.restoAct) % parseInt(st.dsorL)).toString().padStart(st.dsorL.length, '0');
st.restoNecArr = rStr.split('').reverse();
st.fase = "RESTO"; st.digRestoIdx = 0;
info.innerText = "Calcula el resto dígito a dígito";
nuevaFilaResto();
}
} else caja.value = "";
}
else if (st.fase === "RESTO") {
if (v == st.restoNecArr[st.digRestoIdx]) {
caja.replaceWith(crearTexto(v));
st.digRestoIdx++;
if (st.digRestoIdx < st.dsorL.length) {
crearCaja(st.filaAct.children[encontrarIndiceReal(st.idx - 1 - st.digRestoIdx)]);
} else { chequearSiguiente(); }
} else caja.value = "";
}
else if (st.fase === "BAJAR") {
if (v == dndoSinC[st.idx]) {
caja.replaceWith(crearTexto(v, "digito-rojo"));
st.restoAct = (parseInt(st.restoAct) % parseInt(st.dsorL)).toString() + v;
st.idx++; pedirCociente();
} else caja.value = "";
}
else if (st.fase === "COMA") {
if (v === ",") {
caja.replaceWith(crearTexto(","));
st.comaP = true; chequearSiguiente();
} else caja.value = "";
}
}
function encontrarIndiceReal(idxNum) {
let count = 0;
for (let i = 0; i < st.dndoL.length; i++) {
if (st.dndoL[i] !== ",") {
if (count === idxNum) return i;
count++;
}
}
return -1;
}
function chequearSiguiente() {
const dStr = st.dndoL.replace(",", "");
if (st.idx < dStr.length) {
if (st.dndoL[encontrarIndiceReal(st.idx)-1] === "," && !st.comaP) {
st.fase = "COMA"; info.innerText = "Pon la coma en el cociente";
crearCaja(document.getElementById("cociente-box"));
} else {
st.fase = "BAJAR"; info.innerText = "Baja la cifra siguiente";
crearCaja(st.filaAct.children[encontrarIndiceReal(st.idx)]);
}
} else {
finalizarOperacion();
}
}
function finalizarOperacion() {
info.innerText = "¡ENHORABUENA! HAS COMPLETADO LA DIVISIÓN";
document.getElementById("btn-restaurar").style.display = "block";
}
function pedirCociente() {
st.fase = "COCI"; info.innerText = "Busca la cifra del cociente";
crearCaja(document.getElementById("cociente-box"));
}
function nuevaFilaResto() {
st.filaAct = document.createElement("div");
st.filaAct.className = "fila";
for (let i = 0; i < st.dndoL.length; i++) {
const c = document.createElement("div");
c.className = (st.dndoL[i] === ",") ? "celda-coma" : "celda";
st.filaAct.appendChild(c);
}
document.getElementById("area-restos").appendChild(st.filaAct);
crearCaja(st.filaAct.children[encontrarIndiceReal(st.idx - 1)]);
}
function crearTexto(t, cl = "") {
const s = document.createElement("span"); s.innerText = t;
if (cl) s.className = cl; return s;
}
function ponerArqueo(n) {
let idx = encontrarIndiceReal(n-1);
const celda = document.getElementById("fila-dividendo").children[idx];
const a = document.createElement("span");
a.className = "comita-arqueo"; a.innerText = "'";
celda.appendChild(a);
}
function restaurar() {
resetState();
document.getElementById("btn-restaurar").style.display = "none";
document.getElementById("contenedor-principal").style.display = "none";
document.getElementById("fase-setup").style.display = "block";
document.getElementById("area-restos").innerHTML = "";
document.getElementById("cociente-box").innerHTML = "";
document.getElementById("fila-dividendo").innerHTML = "";
panelPreguntas.innerHTML = "";
info.innerText = "Escribe el dividendo para empezar";
inputDat.value = "";
inputDat.focus();
}
resetState();
</script>
</body>
</html>