const SEG = { a:0, b:1, c:2, d:3, e:4, f:5, g:6 }; const segNames = ["a","b","c","d","e","f","g"]; function maskFromSegments(list){ let m = 0; for(const s of list) m |= (1 << SEG[s]); return m; } const DIGIT_MASK = [ maskFromSegments(["a","b","c","d","e","f"]), maskFromSegments(["b","c"]), maskFromSegments(["a","b","d","e","g"]), maskFromSegments(["a","b","c","d","g"]), maskFromSegments(["b","c","f","g"]), maskFromSegments(["a","c","d","f","g"]), maskFromSegments(["a","c","d","e","f","g"]), maskFromSegments(["a","b","c"]), maskFromSegments(["a","b","c","d","e","f","g"]), maskFromSegments(["a","b","c","d","f","g"]) ]; const MASK_TO_DIGIT = new Map(DIGIT_MASK.map((m,d)=>[m,d])); function removableTargetsFromDigit(d){ const start = DIGIT_MASK[d]; const res = []; for(let t=0;t<=9;t++){ const target = DIGIT_MASK[t]; if((target & start) === target){ const removed = popcount(start ^ target); res.push({to:t, removed}); } } return res; } function popcount(x){ x = x >>> 0; let c = 0; while(x){ x &= (x-1); c++; } return c; } function randInt(min, max){ // inclusive return Math.floor(Math.random() * (max - min + 1)) + min; } function pick(arr){ return arr[randInt(0, arr.length-1)]; } let level = 1; let targetRemove = 2; let current = null; let solution = null; let removedSoFar = 0; let removedSet = new Set(); const elEq = document.getElementById("equation"); const elRemovedGrid = document.getElementById("removedGrid"); const elRemovedCount = document.getElementById("removedCount"); const elPileCount = document.getElementById("pileCount"); const elLvl = document.getElementById("lvl"); const elTarget = document.getElementById("target"); const elGoalN = document.getElementById("goalN"); const elTruthDot = document.getElementById("truthDot"); const elTruthText = document.getElementById("truthText"); const elHint = document.getElementById("hint"); document.getElementById("btnNew").addEventListener("click", () => { level++; generateLevel(); }); document.getElementById("btnReset").addEventListener("click", () => { resetPlayState(); renderEquation(); updateTruthUI(); }); function segmentsFromMask(mask){ const set = new Set(); for(let i=0;i<7;i++){ if(mask & (1< { if(removedSet.has(key)) return; if(removedSoFar >= targetRemove) return; removedSet.add(key); removedSoFar++; seg.classList.add("removed"); const clone = document.createElement("div"); clone.className = "removedSeg"; clone.style.background = color; elRemovedGrid.appendChild(clone); syncRemovedCounts(); updateTruthUI(); if(removedSoFar === targetRemove){ if(equationIsTrue()){ elHint.innerHTML = "Solved! You removed exactly the target and made the equation true. Click New level."; } else { elHint.innerHTML = " Not solved. You used all removals but the equation isn’t true. Click Reset level to try again."; } } }); digit.appendChild(seg); } return digit; } function renderEquation(){ elEq.innerHTML = ""; const colors = [ "linear-gradient(180deg,#ff6b6b,#d64545)", "linear-gradient(180deg,#6bcBff,#3a7bd5)", "linear-gradient(180deg,#6bffb3,#1fae63)" ]; const g1 = document.createElement("div"); g1.className = "group"; g1.appendChild(renderDigit(current.A, 0, colors[0])); const plus = document.createElement("div"); plus.className = "symbol"; plus.textContent = "+"; const g2 = document.createElement("div"); g2.className = "group"; g2.appendChild(renderDigit(current.B, 1, colors[1])); const eq = document.createElement("div"); eq.className = "symbol"; eq.textContent = "="; const g3 = document.createElement("div"); g3.className = "group"; g3.appendChild(renderDigit(current.C, 2, colors[2])); elEq.appendChild(g1); elEq.appendChild(plus); elEq.appendChild(g2); elEq.appendChild(eq); elEq.appendChild(g3); updateTruthUI(); } function generateLevel(){ resetPlayState(); targetRemove = Math.min(2 + Math.floor(Math.log2(level + 1)), 6); let tries = 0; while(true){ tries++; if(tries > 5000){ targetRemove = Math.max(2, targetRemove - 1); tries = 0; } const As = randInt(0, 9); const Bs = randInt(0, 9); const Cs = As + Bs; if(Cs < 0 || Cs > 9) continue; const Achoices = superDigits(As); const Bchoices = superDigits(Bs); const Cchoices = superDigits(Cs); const Ashow = pick(Achoices); const Bshow = pick(Bchoices); const Cshow = pick(Cchoices); const need = popcount(DIGIT_MASK[Ashow] ^ DIGIT_MASK[As]) + popcount(DIGIT_MASK[Bshow] ^ DIGIT_MASK[Bs]) + popcount(DIGIT_MASK[Cshow] ^ DIGIT_MASK[Cs]); if(need !== targetRemove) continue; const shownTrue = (Ashow + Bshow) === Cshow; if(shownTrue) continue; solution = { A: As, B: Bs, C: Cs }; current = { A: Ashow, B: Bshow, C: Cshow }; break; } elLvl.textContent = String(level); elTarget.textContent = String(targetRemove); elGoalN.textContent = String(targetRemove); elHint.innerHTML = `Level ${level}: Make the equation true by removing ${targetRemove} match(es). ` + `You can only remove sticks (click them).`; renderEquation(); syncRemovedCounts(); updateTruthUI(); } function superDigits(baseDigit){ const base = DIGIT_MASK[baseDigit]; const res = []; for(let d=0; d<=9; d++){ const m = DIGIT_MASK[d]; if((m & base) === base){ res.push(d); } } return res; } generateLevel();