151 lines
5.6 KiB
JavaScript
151 lines
5.6 KiB
JavaScript
// Nauka Mnożenia
|
||
;(function () {
|
||
const st = { table: null, total: 20, solved: 0, score: 0, current: null, buf: '' }
|
||
|
||
const selectScreen = document.getElementById('select-screen')
|
||
const playScreen = document.getElementById('play-screen')
|
||
const summaryScreen = document.getElementById('summary-screen')
|
||
const problemEl = document.getElementById('problem')
|
||
const answerEl = document.getElementById('answer')
|
||
const feedbackEl = document.getElementById('feedback')
|
||
let progressInner = null
|
||
const progressLabel = document.getElementById('progress-label')
|
||
const scoreLabel = document.getElementById('score-label') // This element is removed, but we might re-purpose the logic
|
||
const summaryText = document.getElementById('summary-text')
|
||
const totalInput = document.getElementById('total-input')
|
||
|
||
// table selection
|
||
document.getElementById('table-grid').addEventListener('click', e => {
|
||
const btn = e.target.closest('.table-btn')
|
||
if (!btn) return
|
||
document.querySelectorAll('.table-btn').forEach(b => b.classList.remove('active'))
|
||
btn.classList.add('active')
|
||
st.table = parseInt(btn.dataset.val, 10) // 0 = all
|
||
})
|
||
|
||
document.getElementById('start-btn').addEventListener('click', () => {
|
||
st.total = Math.max(5, Math.min(100, parseInt(totalInput.value, 10) || 20))
|
||
st.solved = 0
|
||
st.score = 0
|
||
show(playScreen)
|
||
nextProblem()
|
||
})
|
||
|
||
document.getElementById('back-btn').addEventListener('click', () => show(selectScreen))
|
||
document.getElementById('again-btn').addEventListener('click', () => {
|
||
st.solved = 0; st.score = 0; show(playScreen); nextProblem()
|
||
})
|
||
document.getElementById('change-btn').addEventListener('click', () => show(selectScreen))
|
||
|
||
// keypad
|
||
document.querySelectorAll('.key').forEach(k => {
|
||
k.addEventListener('click', () => {
|
||
const v = k.textContent.trim()
|
||
if (!/^[0-9]$/.test(v)) return
|
||
if (st.buf.length >= 6) return
|
||
st.buf += v; answerEl.textContent = st.buf
|
||
})
|
||
})
|
||
document.getElementById('clear').addEventListener('click', () => { st.buf = ''; answerEl.textContent = '' })
|
||
document.getElementById('backspace').addEventListener('click', () => { st.buf = st.buf.slice(0,-1); answerEl.textContent = st.buf || '' })
|
||
document.getElementById('submit').addEventListener('click', submit)
|
||
|
||
window.addEventListener('keydown', e => {
|
||
if (!playScreen.classList.contains('hidden')) {
|
||
if (/^[0-9]$/.test(e.key) && st.buf.length < 6) { st.buf += e.key; answerEl.textContent = st.buf }
|
||
else if (e.key === 'Backspace') { st.buf = st.buf.slice(0,-1); answerEl.textContent = st.buf || '' }
|
||
else if (e.key === 'Enter') submit()
|
||
}
|
||
})
|
||
|
||
function randInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min }
|
||
|
||
function nextProblem() {
|
||
const a = st.table || randInt(1, 10)
|
||
const b = randInt(1, 10)
|
||
st.current = { a, b, answer: a * b }
|
||
problemEl.textContent = `${a} × ${b}`
|
||
feedbackEl.textContent = ''
|
||
st.buf = ''; answerEl.textContent = ''
|
||
updateBar()
|
||
}
|
||
|
||
function submit() {
|
||
if (!st.buf.trim()) return
|
||
const given = parseInt(st.buf, 10)
|
||
st.solved++
|
||
if (given === st.current.answer) {
|
||
st.score++
|
||
feedbackEl.textContent = 'Dobrze!'
|
||
feedbackEl.classList.add('correct')
|
||
feedbackEl.classList.remove('incorrect')
|
||
} else {
|
||
feedbackEl.textContent = `Poprawna odpowiedź: ${st.current.answer}`
|
||
feedbackEl.classList.add('incorrect')
|
||
feedbackEl.classList.remove('correct')
|
||
}
|
||
feedbackEl.style.opacity = 1;
|
||
st.buf = ''; answerEl.textContent = ''
|
||
updateBar()
|
||
if (st.solved >= st.total) {
|
||
setTimeout(showSummary, 1200)
|
||
} else {
|
||
setTimeout(() => {
|
||
feedbackEl.style.opacity = 0;
|
||
setTimeout(nextProblem, 200);
|
||
}, 1000)
|
||
}
|
||
}
|
||
|
||
function updateBar() {
|
||
const pct = st.total > 0 ? Math.round((st.solved / st.total) * 100) : 0
|
||
if (!progressInner) progressInner = document.getElementById('progress-inner')
|
||
if (progressInner) progressInner.style.width = pct + '%'
|
||
progressLabel.textContent = `${st.solved}/${st.total}`
|
||
// scoreLabel is removed, so we comment this out
|
||
// scoreLabel.textContent = `✔ ${st.score}`
|
||
}
|
||
|
||
function showSummary() {
|
||
const pct = st.total > 0 ? Math.round((st.score / st.total) * 100) : 0
|
||
summaryText.textContent = `Twój wynik: ${st.score} / ${st.total} poprawnie (${pct}%)`
|
||
show(summaryScreen)
|
||
}
|
||
|
||
function show(screen) {
|
||
console.log(`Showing screen: ${screen.id}`);
|
||
[selectScreen, playScreen, summaryScreen].forEach(s => s.classList.add('hidden'))
|
||
screen.classList.remove('hidden')
|
||
if (screen === summaryScreen) {
|
||
selectScreen.classList.add('hidden');
|
||
playScreen.classList.add('hidden');
|
||
}
|
||
}
|
||
|
||
// commit SHA
|
||
document.addEventListener('DOMContentLoaded', async () => {
|
||
const el = document.getElementById('commit-sha')
|
||
if (!el) return
|
||
// Set default table selection
|
||
const defaultTableBtn = document.querySelector('.table-btn[data-val="0"]');
|
||
if(defaultTableBtn) {
|
||
defaultTableBtn.classList.add('active');
|
||
st.table = 0;
|
||
}
|
||
|
||
let sha = (window.COMMIT_SHA || '').toString().trim()
|
||
if (!sha) {
|
||
try {
|
||
// use relative path so the request works under WebViewAssetLoader or a local server
|
||
const res = await fetch('version.sha', { cache: 'no-cache' })
|
||
if (res.ok) {
|
||
const txt = await res.text()
|
||
const first = txt.split(/\r?\n/).find(l => l.trim().length > 0)
|
||
if (first) sha = first.trim()
|
||
}
|
||
} catch (e) {}
|
||
}
|
||
if (sha) el.textContent = sha.slice(0, 8)
|
||
})
|
||
})()
|