diff --git a/frontend/textbooks/physics_10_ch1.html b/frontend/textbooks/physics_10_ch1.html index ca7e5e8..1c25f5f 100644 --- a/frontend/textbooks/physics_10_ch1.html +++ b/frontend/textbooks/physics_10_ch1.html @@ -670,34 +670,620 @@ function wireReadBtn(paraId){ function build_p1(){ const box = document.getElementById('p1-body'); let html = ''; + + /* THEORY 1 — положения МКТ */ html += makeCard('theory', "Основные положения МКТ", "§1", ` -

Основные положения МКТ — этот параграф в разработке (Phase 1+).

-

Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.

-

- Phase 0: создан скелет учебника. Phase 1+: наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019). -

+

Молекулярно-кинетическая теория (МКТ) объясняет строение и свойства веществ на основе движения и взаимодействия частиц (атомов, молекул, ионов).

+

Три основных положения МКТ:

+
    +
  1. Вещество состоит из частиц. Молекулы и атомы имеют размер около $10^{-10}$ м.
  2. +
  3. Частицы движутся непрерывно и хаотически. Это движение называется тепловым.
  4. +
  5. Частицы взаимодействуют между собой: на малых расстояниях — отталкиваются, на больших — притягиваются.
  6. +
+

Все макроскопические свойства (температура, давление, плотность, теплопроводность и т. д.) объясняются микроскопическими процессами.

`); + + /* THEORY 2 — опытные подтверждения */ + html += makeCard('rule', "Опытные подтверждения МКТ", "§1", ` +

Броуновское движение (Р. Броун, 1827): хаотическое движение мелких частиц (например, пыльцы в воде) под действием ударов молекул. Чем меньше частица и выше температура — тем интенсивнее движение.

+

Диффузия — самопроизвольное перемешивание веществ за счёт движения молекул. Скорость диффузии возрастает с температурой.

+

Сжимаемость газов и тепловое расширение тел — также прямое следствие движения и взаимодействия молекул.

+ `); + + /* THEORY 3 — размеры и числа */ + html += makeCard('example', "Размеры и количество молекул", "§1", ` + +

Пример: если выпить стакан воды (200 мл) и подождать долгое время, в любом другом стакане воды через некоторое время будут несколько молекул из выпитого — настолько их много в любом веществе.

+ `); + + /* INTERACTIVE 1 — Симуляция броуновского движения */ + html += `
+
ИНТЕРАКТИВ 1
Симуляция броуновского движения
+
Оранжевая «броуновская» частица среди синих молекул газа. Меняй температуру — наблюдай хаотическое движение.
+
+ +
+
+ +
+
+ + +
+
+ Чем выше $T$, тем сильнее удары молекул, тем хаотичнее движется броуновская частица. Жёлтый след показывает её траекторию. +
+
`; + + /* INTERACTIVE 2 — DnD сортер: положение МКТ ↔ опыт */ + html += `
+
ИНТЕРАКТИВ 2
Положение МКТ ↔ опыт
+
Перетащи каждое явление в соответствующее положение МКТ.
+
6 явлений — 3 положения
+
+
+
1. Вещество из частиц
+
2. Частицы движутся
+
3. Частицы взаимодействуют
+
+
+
+
`; + + /* INTERACTIVE 3 — Квикфайр: Верно/Неверно */ + html += `
+
ИНТЕРАКТИВ 3
Проверь знания МКТ
+
8 утверждений. Выбери «Верно» или «Неверно». Допуск ошибок — 1.
+
Задача 1 / 8Очки: 0 / 8
+
+
+
+
+
`; + + /* INTERACTIVE 4 — тренажёр чисел */ + html += `
+
ИНТЕРАКТИВ 4
Тренажёр: размеры и числа
+
5 задач на число Авогадро, размеры молекул, моли. Допуск $\\pm 5\\%$. Используй $N_A = 6 \\cdot 10^{23}$.
+
Задача 1 / 5Очки: 0 / 5
+
+
+ ответ = + + + +
+
+
`; + html += secNav(null, 'p2'); html += readButton('p1'); + box.innerHTML = html; renderMath(box); + + /* IV1 — Броуновское движение */ + (function(){ + const svg = document.getElementById('p1-iv1-svg'); + const tInp = document.getElementById('p1-iv1-T'); + const tLab = document.getElementById('p1-iv1-tL'); + const btnPause = document.getElementById('p1-iv1-pause'); + const btnReset = document.getElementById('p1-iv1-reset'); + const W = 420, H = 320; + const baseSpeed = 80; + const tempChanges = new Set(); + let _xpDone = false; + let raf = null, lastT = 0, paused = false; + let sim = null; + let brown = null; + let trail = []; + + function makeSim(){ + sim = PHYS.createGasSim({W, H, N: 50, speed: baseSpeed, r: 3}); + brown = { x: W/2, y: H/2, vx: 0, vy: 0, r: 12 }; + trail = []; + // initial temp + applyTemp(+tInp.value); + } + function applyTemp(T){ + // baseSpeed соответствует T0=300 К; scale = sqrt(T/T0) + const targetScale = Math.sqrt(T/300); + // компенсируем текущую среднюю скорость + let curAvg = 0; + for(const p of sim.particles){ curAvg += Math.hypot(p.vx, p.vy); } + curAvg /= sim.particles.length; + const targetAvg = baseSpeed * targetScale; + if(curAvg > 0.01) sim.setSpeed(targetAvg / curAvg); + } + function frame(t){ + raf = requestAnimationFrame(frame); + if(!lastT){ lastT = t; return; } + let dt = (t - lastT) / 1000; + lastT = t; + if(paused){ render(); return; } + if(dt > 0.06) dt = 0.06; + sim.step(dt); + + // обновляем броуновскую частицу: суммируем импульс от ближних молекул + let fx = 0, fy = 0; + const R = brown.r + 4; + for(const p of sim.particles){ + const dx = brown.x - p.x, dy = brown.y - p.y; + const d2 = dx*dx + dy*dy; + if(d2 < R*R && d2 > 1){ + const d = Math.sqrt(d2); + const f = (R - d) / R; + fx += dx/d * f * 60; + fy += dy/d * f * 60; + } + } + // демпфирование + импульс + brown.vx = brown.vx * 0.88 + fx * dt; + brown.vy = brown.vy * 0.88 + fy * dt; + brown.x += brown.vx * dt; + brown.y += brown.vy * dt; + // отражение от стенок + if(brown.x < brown.r){ brown.x = brown.r; brown.vx = -brown.vx*0.6; } + if(brown.x > W - brown.r){ brown.x = W - brown.r; brown.vx = -brown.vx*0.6; } + if(brown.y < brown.r){ brown.y = brown.r; brown.vy = -brown.vy*0.6; } + if(brown.y > H - brown.r){ brown.y = H - brown.r; brown.vy = -brown.vy*0.6; } + + trail.push({x: brown.x, y: brown.y}); + if(trail.length > 60) trail.shift(); + render(); + } + function render(){ + let g = ''; + // фон тёмный (уже в SVG), молекулы синие + g += sim.render('#60a5fa'); + // след броуновской — polyline с убывающей opacity + if(trail.length > 1){ + for(let i = 1; i < trail.length; i++){ + const op = i / trail.length; + g += ``; + } + } + // броуновская частица — оранжевая + g += ``; + svg.innerHTML = g; + } + + makeSim(); + raf = requestAnimationFrame(frame); + + tInp.addEventListener('input', () => { + const T = +tInp.value; + tLab.textContent = T; + applyTemp(T); + tempChanges.add(T); + if(!_xpDone && tempChanges.size >= 4){ + _xpDone = true; + addXp(10, 'p1-iv1'); + bumpProgress('p1', 15); + } + }); + btnPause.addEventListener('click', () => { + paused = !paused; + btnPause.textContent = paused ? 'Продолжить' : 'Пауза'; + }); + btnReset.addEventListener('click', () => { + makeSim(); + trail = []; + }); + // cleanup при потере фокуса (минимизируем нагрузку) + document.addEventListener('visibilitychange', () => { + if(document.hidden && raf){ cancelAnimationFrame(raf); raf = null; lastT = 0; } + else if(!document.hidden && !raf){ raf = requestAnimationFrame(frame); } + }); + })(); + + /* IV2 — DnD: положение ↔ опыт */ + (function(){ + const items = [ + { id:'q1', cat:'c2', html:'Запах духов распространяется в комнате' }, + { id:'q2', cat:'c2', html:'Пыльца хаотично движется в воде' }, + { id:'q3', cat:'c1', html:'Воздух сжимается в насосе' }, + { id:'q4', cat:'c3', html:'Капля воды растекается по стеклу' }, + { id:'q5', cat:'c1', html:'Стальной шарик падает в воде медленнее, чем в воздухе' }, + { id:'q6', cat:'c2', html:'Газ заполняет весь сосуд' }, + ]; + const sorter = setupSorter({ + poolId:'p1-iv2-pool', + scopeSelector:'#p1-iv2', + items: items, + cats:['c1','c2','c3'], + columnLayout:false, + }); + document.getElementById('p1-iv2-check').addEventListener('click', ()=>{ + const fb = document.getElementById('p1-iv2-fb'); + const placedCount = items.filter(it => sorter.placed[it.id]).length; + const correct = items.filter(it => sorter.placed[it.id] === it.cat).length; + if(placedCount < items.length){ feedback(fb, false, '✗ Размести все 6 явлений.'); return; } + if(correct === items.length){ feedback(fb, true, '✓ Все 6 верно! +10 XP'); addXp(10,'p1-iv2'); bumpProgress('p1', 15); } + else feedback(fb, false, '✗ Правильно ' + correct + ' из 6. Попробуй ещё.'); + }); + document.getElementById('p1-iv2-reset').addEventListener('click', ()=>{ sorter.reset(); document.getElementById('p1-iv2-fb').style.display = 'none'; }); + })(); + + /* IV3 — квикфайр Верно/Неверно */ + (function(){ + const Q = [ + { q:'Молекулы вещества движутся хаотически.', ans:true, why:'Тепловое движение — это хаотическое движение молекул.' }, + { q:'При нагревании молекулы движутся медленнее.', ans:false, why:'Наоборот — при нагревании движение усиливается.' }, + { q:'Атомы можно увидеть в обычный световой микроскоп.', ans:false, why:'Размер атома $\\sim 10^{-10}$ м — нужен электронный микроскоп.' }, + { q:'Между молекулами действуют только силы притяжения.', ans:false, why:'На малых расстояниях — отталкивание, на больших — притяжение.' }, + { q:'Размер молекулы порядка $10^{-10}$ м.', ans:true, why:'Это типичный размер молекулы (≈ 1 ангстрем).' }, + { q:'Броуновское движение объясняется ударами молекул жидкости.', ans:true, why:'Хаотические удары молекул заставляют двигаться броуновские частицы.' }, + { q:'Диффузия в газах происходит быстрее, чем в жидкостях.', ans:true, why:'В газах молекулы движутся свободнее и быстрее.' }, + { q:'В 1 моль любого вещества одинаковое число молекул — $N_A$.', ans:true, why:'$N_A = 6{,}022 \\cdot 10^{23}$ — число Авогадро.' }, + ]; + let i = 0, score = 0; + const qEl = document.getElementById('p1-iv3-q'); + const oEl = document.getElementById('p1-iv3-opts'); + const fb = document.getElementById('p1-iv3-fb'); + const iEl = document.getElementById('p1-iv3-i'); + const sEl = document.getElementById('p1-iv3-s'); + + function show(){ + if(i >= Q.length){ + qEl.innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length; + oEl.innerHTML = ''; + if(score === Q.length){ addXp(15, 'p1-iv3'); bumpProgress('p1', 25); } + else if(score >= 5){ addXp(8, 'p1-iv3'); bumpProgress('p1', 15); } + return; + } + iEl.textContent = (i+1); + sEl.textContent = score; + const item = Q[i]; + qEl.innerHTML = item.q; + oEl.innerHTML = ''; + fb.style.display = 'none'; + renderMath(qEl); + oEl.querySelectorAll('button').forEach(b => { + b.addEventListener('click', () => { + const v = b.dataset.v === '1'; + if(v === item.ans){ score++; feedback(fb, true, '✓ Верно! ' + item.why + ' Дальше ▶'); } + else feedback(fb, false, '✗ Неверно. ' + item.why + ' Дальше ▶'); + sEl.textContent = score; + oEl.querySelectorAll('button').forEach(x => x.disabled = true); + i++; + setTimeout(show, 1400); + }); + }); + } + document.getElementById('p1-iv3-restart').addEventListener('click', () => { i = 0; score = 0; show(); }); + show(); + })(); + + /* IV4 — тренажёр чисел */ + (function(){ + const Q = [ + { q:'В стакане воды $2{,}4 \\cdot 10^{24}$ молекул. Сколько это молей? ($N_A = 6 \\cdot 10^{23}$)', ans:4, hint:'$\\nu = N/N_A = 2{,}4 \\cdot 10^{24} / 6 \\cdot 10^{23} = 4$' }, + { q:'В 18 г воды ($M = 18$ г/моль) сколько моль?', ans:1, hint:'$\\nu = m/M = 18/18 = 1$ моль' }, + { q:'В 1 кг водорода ($M = 2$ г/моль) сколько моль?', ans:500, hint:'$\\nu = 1000/2 = 500$ моль' }, + { q:'В 3 моль газа сколько молекул? Введи число $X$ для ответа $X \\cdot 10^{23}$', ans:18, hint:'$N = 3 \\cdot 6 \\cdot 10^{23} = 18 \\cdot 10^{23}$' }, + { q:'Размер молекулы $\\sim 10^{-10}$ м. Сколько молекул в ряд поместится на $1$ мм? Введи порядок: $10^X$, $X = ?$', ans:7, hint:'$10^{-3}/10^{-10} = 10^{7}$' }, + ]; + let i = 0, score = 0; + function show(){ + if(i >= Q.length){ + document.getElementById('p1-iv4-q').innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length; + if(score === Q.length){ addXp(15, 'p1-iv4'); bumpProgress('p1', 25); } + else if(score >= 3){ addXp(8, 'p1-iv4'); bumpProgress('p1', 15); } + return; + } + document.getElementById('p1-iv4-i').textContent = (i+1); + document.getElementById('p1-iv4-s').textContent = score; + document.getElementById('p1-iv4-q').innerHTML = Q[i].q; + document.getElementById('p1-iv4-ans').value = ''; + renderMath(document.getElementById('p1-iv4-q')); + document.getElementById('p1-iv4-fb').style.display = 'none'; + } + function go(){ + if(i >= Q.length) return; + const fb = document.getElementById('p1-iv4-fb'); + const raw = document.getElementById('p1-iv4-ans').value.replace(',', '.'); + const ans = parseFloat(raw); + if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; } + const tol = Math.max(0.05 * Math.abs(Q[i].ans), 0.05); + if(Math.abs(ans - Q[i].ans) < tol){ score++; feedback(fb, true, '✓ Верно! '+Q[i].hint+'. Дальше ▶'); } + else feedback(fb, false, '✗ Неверно. Ответ: $'+Q[i].ans+'$. '+Q[i].hint+'. Дальше ▶'); + document.getElementById('p1-iv4-s').textContent = score; + i++; + setTimeout(show, 1500); + } + document.getElementById('p1-iv4-go').addEventListener('click', go); + document.getElementById('p1-iv4-ans').addEventListener('keydown', e => { if(e.key === 'Enter') go(); }); + document.getElementById('p1-iv4-start').addEventListener('click', () => { i = 0; score = 0; show(); }); + show(); + })(); + wireReadBtn('p1'); } function build_p2(){ const box = document.getElementById('p2-body'); let html = ''; - html += makeCard('theory', "Масса и размеры молекул. Количество вещества", "§2", ` -

Масса и размеры молекул. Количество вещества — этот параграф в разработке (Phase 1+).

-

Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.

-

- Phase 0: создан скелет учебника. Phase 1+: наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019). -

+ + /* THEORY 1 — количество вещества */ + html += makeCard('theory', "Количество вещества и моль", "§2", ` +

Количество вещества $\\nu$ (греч. «ню») — физическая величина, равная числу частиц вещества, делённому на число Авогадро:

+

$$\\nu = \\dfrac{N}{N_A}$$

+

Единица: моль. Один моль — количество вещества, содержащее столько же частиц, сколько атомов в $12$ г углерода-12.

+

Число Авогадро: $N_A = 6{,}022 \\cdot 10^{23}$ моль$^{-1}$.

`); + + /* THEORY 2 — молярная масса */ + html += makeCard('rule', "Молярная масса. Связь с массой", "§2", ` +

Молярная масса $M$ — масса одного моля вещества:

+

$$M = m_0 \\cdot N_A$$

+

где $m_0$ — масса одной молекулы. Единица СИ — кг/моль, привычная — г/моль.

+

Связь количества вещества с массой:

+

$$\\nu = \\dfrac{m}{M} = \\dfrac{N}{N_A}$$

+

Относительная молекулярная масса $M_r$ — безразмерна: $M_r = M$ (в г/моль). Например, $M_r(\\text{H}_2\\text{O}) = 18$, $M(\\text{H}_2\\text{O}) = 18$ г/моль $= 0{,}018$ кг/моль.

+ `); + + /* THEORY 3 — масса молекулы */ + html += makeCard('example', "Масса одной молекулы и концентрация", "§2", ` +

Зная молярную массу и число Авогадро, найдём массу одной молекулы:

+

$$m_0 = \\dfrac{M}{N_A}$$

+

Примеры:

+ +

Концентрация молекул $n$ — число молекул в единице объёма:

+

$$n = \\dfrac{N}{V}$$

+

Единица: $\\text{м}^{-3}$.

+ `); + + /* INTERACTIVE 1 — калькулятор Авогадро */ + html += `
+
ИНТЕРАКТИВ 1
Калькулятор Авогадро
+
Введи массу $m$ (г) и молярную массу $M$ (г/моль) — получи количество вещества $\\nu$, число молекул $N$ и массу одной молекулы $m_0$.
+
+ + +
+
+ Эталон: + +
+
+ +
+
+ +
`; + + /* INTERACTIVE 2 — DnD сортер: вещество ↔ молярная масса */ + html += `
+
ИНТЕРАКТИВ 2
Сопоставь массу с веществом
+
Перетащи каждое вещество в ящик с его молярной массой.
+
6 веществ — 6 значений
+
+
+
2 г/моль
+
16 г/моль
+
18 г/моль
+
28 г/моль
+
32 г/моль
+
44 г/моль
+
+
+ +
`; + + /* INTERACTIVE 3 — квикфайр «Что больше?» */ + html += `
+
ИНТЕРАКТИВ 3
Что больше?
+
6 вопросов «что больше» — выбери первое или второе.
+
Задача 1 / 6Очки: 0 / 6
+
+
+ +
+
`; + + /* INTERACTIVE 4 — тренажёр количества вещества */ + html += `
+
ИНТЕРАКТИВ 4
Тренажёр: количество вещества
+
6 задач на $\\nu = m/M$ и $N = \\nu N_A$. Допуск $\\pm 5\\%$. Используй $N_A = 6 \\cdot 10^{23}$.
+
Задача 1 / 6Очки: 0 / 6
+
+
+ ответ = + + + +
+ +
`; + html += secNav('p1', 'p3'); html += readButton('p2'); + box.innerHTML = html; renderMath(box); + + /* IV1 — калькулятор Авогадро */ + (function(){ + const mI = document.getElementById('p2-iv1-m'); + const MI = document.getElementById('p2-iv1-M'); + const sel = document.getElementById('p2-iv1-preset'); + const out = document.getElementById('p2-iv1-out'); + const fb = document.getElementById('p2-iv1-fb'); + const go = document.getElementById('p2-iv1-go'); + const used = new Set(); + let _done = false; + const NA = 6e23; + + function calc(){ + const m = parseFloat(mI.value); + const M = parseFloat(MI.value); + if(!isFinite(m) || m <= 0){ feedback(fb, false, '✗ Введи положительную массу.'); return; } + if(!isFinite(M) || M <= 0){ feedback(fb, false, '✗ Введи положительную молярную массу.'); return; } + const nu = m / M; + const N = nu * NA; + // m0 в кг: m0 = M(кг/моль) / N_A = M*1e-3 / N_A + const m0 = (M * 1e-3) / NA; + const NstrExp = Math.floor(Math.log10(N)); + const NstrCoef = N / Math.pow(10, NstrExp); + const m0Exp = Math.floor(Math.log10(m0)); + const m0Coef = m0 / Math.pow(10, m0Exp); + + out.innerHTML = + '
Количество вещества: $\\nu = \\dfrac{m}{M} = \\dfrac{'+(+m.toFixed(3))+'}{'+(+M.toFixed(3))+'} \\approx '+(+nu.toFixed(4))+'$ моль
' + + '
Число молекул: $N = \\nu \\cdot N_A = '+(+nu.toFixed(4))+' \\cdot 6 \\cdot 10^{23} \\approx '+(+NstrCoef.toFixed(3))+' \\cdot 10^{'+NstrExp+'}$
' + + '
Масса одной молекулы: $m_0 = \\dfrac{M}{N_A} \\approx '+(+m0Coef.toFixed(3))+' \\cdot 10^{'+m0Exp+'}$ кг
'; + renderMath(out); + feedback(fb, true, '✓ Вычислено.'); + used.add((+M.toFixed(2))+':'+(+m.toFixed(2))); + if(!_done && used.size >= 4){ _done = true; addXp(10, 'p2-iv1'); bumpProgress('p2', 15); } + } + sel.addEventListener('change', () => { + if(sel.value){ MI.value = sel.value; } + }); + go.addEventListener('click', calc); + mI.addEventListener('keydown', e => { if(e.key === 'Enter') calc(); }); + MI.addEventListener('keydown', e => { if(e.key === 'Enter') calc(); }); + })(); + + /* IV2 — DnD: вещество ↔ молярная масса */ + (function(){ + const items = [ + { id:'w1', cat:'m18', html:'Вода H$_2$O' }, + { id:'w2', cat:'m44', html:'Углекислый газ CO$_2$' }, + { id:'w3', cat:'m32', html:'Кислород O$_2$' }, + { id:'w4', cat:'m28', html:'Азот N$_2$' }, + { id:'w5', cat:'m2', html:'Водород H$_2$' }, + { id:'w6', cat:'m16', html:'Метан CH$_4$' }, + ]; + const sorter = setupSorter({ + poolId:'p2-iv2-pool', + scopeSelector:'#p2-iv2', + items: items, + cats:['m2','m16','m18','m28','m32','m44'], + columnLayout:false, + }); + document.getElementById('p2-iv2-check').addEventListener('click', ()=>{ + const fb = document.getElementById('p2-iv2-fb'); + const placedCount = items.filter(it => sorter.placed[it.id]).length; + const correct = items.filter(it => sorter.placed[it.id] === it.cat).length; + if(placedCount < items.length){ feedback(fb, false, '✗ Размести все 6 веществ.'); return; } + if(correct === items.length){ feedback(fb, true, '✓ Все 6 верно! +10 XP'); addXp(10,'p2-iv2'); bumpProgress('p2', 15); } + else feedback(fb, false, '✗ Правильно ' + correct + ' из 6. Попробуй ещё.'); + }); + document.getElementById('p2-iv2-reset').addEventListener('click', ()=>{ sorter.reset(); document.getElementById('p2-iv2-fb').style.display = 'none'; }); + })(); + + /* IV3 — квикфайр «Что больше?» */ + (function(){ + const Q = [ + { q:'Что весит больше: $1$ моль воды (M=18) или $1$ моль водорода (M=2)?', a:'1 моль воды (18 г)', b:'1 моль водорода (2 г)', ans:0, why:'Молярная масса воды 18 г/моль > 2 г/моль.' }, + { q:'Что больше по массе: $36$ г воды или $1$ моль воды (M=18)?', a:'36 г воды', b:'1 моль воды (18 г)', ans:0, why:'36 г = 2 моль воды > 1 моль (18 г).' }, + { q:'Что весит больше: $N_A$ молекул кислорода (M=32) или $2 N_A$ молекул водорода (M=2)?', a:'$N_A$ молекул O$_2$ (32 г)', b:'$2 N_A$ молекул H$_2$ (4 г)', ans:0, why:'32 г > 4 г.' }, + { q:'Что больше по массе: $1$ моль CO$_2$ (M=44) или $1$ кг воды?', a:'1 моль CO$_2$ (44 г)', b:'1 кг воды (1000 г)', ans:1, why:'1000 г > 44 г.' }, + { q:'Что больше по числу частиц: $10^{23}$ молекул железа или $10^{22}$ молекул свинца?', a:'$10^{23}$ молекул Fe', b:'$10^{22}$ молекул Pb', ans:0, why:'$10^{23} > 10^{22}$ в 10 раз.' }, + { q:'Что больше по массе: $5$ моль H$_2$ (M=2) или $1$ моль O$_2$ (M=32)?', a:'5 моль H$_2$ (10 г)', b:'1 моль O$_2$ (32 г)', ans:1, why:'$5 \\cdot 2 = 10$ г против $32$ г.' }, + ]; + let i = 0, score = 0; + const qEl = document.getElementById('p2-iv3-q'); + const oEl = document.getElementById('p2-iv3-opts'); + const fb = document.getElementById('p2-iv3-fb'); + const iEl = document.getElementById('p2-iv3-i'); + const sEl = document.getElementById('p2-iv3-s'); + + function show(){ + if(i >= Q.length){ + qEl.innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length; + oEl.innerHTML = ''; + if(score === Q.length){ addXp(15, 'p2-iv3'); bumpProgress('p2', 25); } + else if(score >= 4){ addXp(8, 'p2-iv3'); bumpProgress('p2', 15); } + return; + } + iEl.textContent = (i+1); + sEl.textContent = score; + const item = Q[i]; + qEl.innerHTML = item.q; + oEl.innerHTML = ''; + fb.style.display = 'none'; + renderMath(qEl); renderMath(oEl); + oEl.querySelectorAll('button').forEach(b => { + b.addEventListener('click', () => { + const v = +b.dataset.v; + if(v === item.ans){ score++; feedback(fb, true, '✓ Верно! ' + item.why + ' Дальше ▶'); } + else feedback(fb, false, '✗ Неверно. ' + item.why + ' Дальше ▶'); + sEl.textContent = score; + oEl.querySelectorAll('button').forEach(x => x.disabled = true); + i++; + setTimeout(show, 1500); + }); + }); + } + document.getElementById('p2-iv3-restart').addEventListener('click', () => { i = 0; score = 0; show(); }); + show(); + })(); + + /* IV4 — тренажёр количества вещества */ + (function(){ + const Q = [ + { q:'В 36 г воды (M=18 г/моль) сколько моль?', ans:2, hint:'$\\nu = m/M = 36/18 = 2$ моль' }, + { q:'В 88 г углекислого газа (M=44 г/моль) сколько моль?', ans:2, hint:'$\\nu = 88/44 = 2$ моль' }, + { q:'Сколько молекул в 1 моль вещества? Введи показатель $X$ для $6 \\cdot 10^X$', ans:23, hint:'$N_A = 6 \\cdot 10^{23}$' }, + { q:'M = 64 г/моль. Сколько моль в 32 г этого вещества?', ans:0.5, hint:'$\\nu = 32/64 = 0{,}5$ моль' }, + { q:'Сколько грамм в 3 моль воды (M=18 г/моль)?', ans:54, hint:'$m = \\nu M = 3 \\cdot 18 = 54$ г' }, + { q:'В 36 г воды сколько молекул? Введи $X$ для ответа $X \\cdot 10^{23}$', ans:12, hint:'$\\nu = 2$ моль, $N = 2 \\cdot 6 \\cdot 10^{23} = 12 \\cdot 10^{23}$' }, + ]; + let i = 0, score = 0; + function show(){ + if(i >= Q.length){ + document.getElementById('p2-iv4-q').innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length; + if(score === Q.length){ addXp(15, 'p2-iv4'); bumpProgress('p2', 25); } + else if(score >= 4){ addXp(8, 'p2-iv4'); bumpProgress('p2', 15); } + return; + } + document.getElementById('p2-iv4-i').textContent = (i+1); + document.getElementById('p2-iv4-s').textContent = score; + document.getElementById('p2-iv4-q').innerHTML = Q[i].q; + document.getElementById('p2-iv4-ans').value = ''; + renderMath(document.getElementById('p2-iv4-q')); + document.getElementById('p2-iv4-fb').style.display = 'none'; + } + function go(){ + if(i >= Q.length) return; + const fb = document.getElementById('p2-iv4-fb'); + const raw = document.getElementById('p2-iv4-ans').value.replace(',', '.'); + const ans = parseFloat(raw); + if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; } + const tol = Math.max(0.05 * Math.abs(Q[i].ans), 0.05); + if(Math.abs(ans - Q[i].ans) < tol){ score++; feedback(fb, true, '✓ Верно! '+Q[i].hint+'. Дальше ▶'); } + else feedback(fb, false, '✗ Неверно. Ответ: $'+Q[i].ans+'$. '+Q[i].hint+'. Дальше ▶'); + document.getElementById('p2-iv4-s').textContent = score; + i++; + setTimeout(show, 1500); + } + document.getElementById('p2-iv4-go').addEventListener('click', go); + document.getElementById('p2-iv4-ans').addEventListener('keydown', e => { if(e.key === 'Enter') go(); }); + document.getElementById('p2-iv4-start').addEventListener('click', () => { i = 0; score = 0; show(); }); + show(); + })(); + wireReadBtn('p2'); }