diff --git a/frontend/textbooks/geometry_11_ch4.html b/frontend/textbooks/geometry_11_ch4.html index 111e503..978a60a 100644 --- a/frontend/textbooks/geometry_11_ch4.html +++ b/frontend/textbooks/geometry_11_ch4.html @@ -400,7 +400,7 @@ function buildParaSelector(){ } const BUILT=new Set(); -const BUILDERS = { p8:()=>buildStub('p8'), p9:()=>buildStub('p9'), p10:()=>buildStub('p10'), p11:()=>buildStub('p11'), final4:()=>buildStub('final4') }; +const BUILDERS = { p8:()=>buildP8(), p9:()=>buildP9(), p10:()=>buildStub('p10'), p11:()=>buildStub('p11'), final4:()=>buildStub('final4') }; function ensureBuilt(id){ if(BUILT.has(id)) return; const fn=BUILDERS[id]; if(fn){ fn(); BUILT.add(id); } } function goTo(id){ STATE.current=id; ensureBuilt(id); @@ -415,16 +415,16 @@ function goTo(id){ } const SIDEBARS = { - p8:{title:"Шпаргалка § 8", rows:[["Тема", "Геометрические фигуры и их свойства"],["Формула","планиметрия"]]}, - p9:{title:"Шпаргалка § 9", rows:[["Тема", "Геометрические величины"],["Формула","площади, объёмы"]]}, + p8:{title:"Шпаргалка § 8", rows:[["Сумма углов $\\triangle$","$180°$"],["Пифагор","$a^2+b^2=c^2$"],["Синусов","$\\dfrac{a}{\\sin A}=2R$"],["Косинусов","$c^2=a^2+b^2-2ab\\cos C$"],["Длина окр.","$C=2\\pi R$"],["$S$ круга","$\\pi R^2$"]]}, + p9:{title:"Шпаргалка § 9", rows:[["$S_\\triangle$","$\\frac{1}{2}ab\\sin C$"],["Герон","$\\sqrt{p(p-a)(p-b)(p-c)}$"],["$S$ трап.","$\\frac{a+b}{2}h$"],["$V$ призмы","$S_{осн}h$"],["$V$ пир.","$\\frac{1}{3}S_{осн}h$"],["$V$ шара","$\\frac{4}{3}\\pi R^3$"]]}, p10:{title:"Шпаргалка § 10", rows:[["Тема", "Координаты и векторы"],["Формула","3D: $\\\\vec{a}=(x;y;z)$"]]}, p11:{title:"Шпаргалка § 11", rows:[["Тема", "Геометрические построения"],["Формула","циркуль и линейка"]]}, final4:{title:"Финал раздела 4", rows:[["§ 8–§ 11","теория раздела 4"],["Награда","+50 XP"]]} }; const TIPS=[ - {sec:'p8',html:"§ 8 «Геометрические фигуры и их свойства» — содержание в разработке. планиметрия"}, - {sec:'p9',html:"§ 9 «Геометрические величины» — содержание в разработке. площади, объёмы"}, + {sec:'p8',html:"§ 8: обзор планиметрии. Теоремы Пифагора, синусов, косинусов; виды треугольников и четырёхугольников; окружность."}, + {sec:'p9',html:"§ 9: площади плоских фигур и объёмы тел. Формулы Герона, $S=\\frac{1}{2}ab\\sin C$, $V=\\frac{1}{3}S_{осн}h$, шар."}, {sec:'p10',html:"§ 10 «Координаты и векторы» — содержание в разработке. 3D: $\\\\\\\\vec{a}=(x;y;z)$"}, {sec:'p11',html:"§ 11 «Геометрические построения» — содержание в разработке. циркуль и линейка"}, {sec:'final4',html:"Финал раздела 4 — интегрированные задачи по разделу."} @@ -708,6 +708,489 @@ function buildStub(id){ wireReadBtn(id); } +/* ===== §8 «Геометрические фигуры и их свойства» (повторение планиметрии) ===== */ + +function buildP8(){ + const box = document.getElementById('p8-body'); + if(!box) return; + let html = ''; + + /* === ТЕОРИЯ === */ + + html += makeCard('theory', 'Треугольники и четырёхугольники', '§ 8.1', + '

Треугольник. Сумма углов любого треугольника равна $180°$. Виды по углам: остроугольный, прямоугольный, тупоугольный. По сторонам: разносторонний, равнобедренный, равносторонний.

' + + '

Замечательные точки треугольника: центроид $G$ (точка пересечения медиан, делит каждую медиану $2{:}1$ от вершины), ортоцентр $H$ (пересечение высот), центр описанной окружности $O$ (пересечение серединных перпендикуляров), центр вписанной окружности $I$ (пересечение биссектрис).

' + + '

Прямоугольный треугольник: теорема Пифагора $a^2 + b^2 = c^2$. Тригонометрия острого угла $A$:

' + + '

$\\sin A = \\dfrac{a}{c},\\quad \\cos A = \\dfrac{b}{c},\\quad \\tan A = \\dfrac{a}{b}$

' + + '

Теорема синусов (для любого треугольника):

' + + '

$\\dfrac{a}{\\sin A} = \\dfrac{b}{\\sin B} = \\dfrac{c}{\\sin C} = 2R$

' + + '

Теорема косинусов:

' + + '

$c^2 = a^2 + b^2 - 2ab\\cos C$

' + + '

Четырёхугольники. Сумма углов выпуклого четырёхугольника равна $360°$. Иерархия: параллелограмм $\\supset$ прямоугольник, ромб $\\supset$ квадрат. У параллелограмма противоположные стороны равны и параллельны, диагонали точкой пересечения делятся пополам.

' + + '

Трапеция: две параллельные стороны (основания) разной длины. Средняя линия $m = \\dfrac{a+b}{2}$.

'); + + html += makeCard('example', 'Окружность и её свойства', '§ 8.2', + '

Окружность. Длина окружности: $C = 2\\pi R$. Длина дуги в $\\alpha$ градусов: $\\ell = \\dfrac{\\pi R \\alpha}{180°}$.

' + + '

Круг: площадь $S = \\pi R^2$. Площадь сектора с центральным углом $\\alpha$: $S_{сект} = \\dfrac{\\pi R^2 \\alpha}{360°}$.

' + + '

Вписанный угол. Угол, вершина которого лежит на окружности, а стороны — хорды, равен половине центрального угла, опирающегося на ту же дугу. Все вписанные углы, опирающиеся на один диаметр, прямые (теорема Фалеса).

' + + '

Касательная. Прямая, имеющая с окружностью ровно одну общую точку. Касательная перпендикулярна радиусу, проведённому в точку касания. Отрезки касательных из одной внешней точки равны.

' + + '

Вписанная и описанная окружности треугольника:

' + + '

$r = \\dfrac{S}{p},\\qquad R = \\dfrac{abc}{4S}$

' + + '

где $p = \\dfrac{a+b+c}{2}$ — полупериметр, $S$ — площадь треугольника.

' + + '
Пример: треугольник $a=3$, $b=4$, $c=5$
' + + '

Прямоугольный (так как $3^2+4^2=5^2$). $S = \\frac{1}{2}\\cdot 3 \\cdot 4 = 6$. $p = 6$.

' + + '

$r = S/p = 6/6 = 1$. $R = (3\\cdot 4\\cdot 5)/(4\\cdot 6) = 60/24 = 2{,}5$ (= $c/2$ — гипотенуза диаметр).

' + + '
'); + + /* === ИНТЕРАКТИВ 1 — Квикфайр === */ + html += '
' + + '
квикфайр · 8 вопросов
Какая теорема нужна?
' + + '
Для каждой ситуации выбери теорему: Пифагор, синусов или косинусов. После 8 верных — +10 XP.
' + + '
' + + '
Верно: 0 / 8
' + + '
'; + + /* === ИНТЕРАКТИВ 2 — DnD сортер === */ + html += '
' + + '
сортер
Тип четырёхугольника
' + + '
Перетащи описание в нужный ящик. После всех верных — +15 XP.
' + + '
6 описаний → 4 типа
' + + '
' + + '
' + + '
Квадрат
' + + '
Ромб
' + + '
Прям-к / Парал-м
' + + '
Трапеция
' + + '
' + + '
' + + '
' + + '
'; + + /* === ИНТЕРАКТИВ 3 — Тренажёр повторения === */ + html += '
' + + '
тренажёр · 5 задач
Повторение планиметрии
' + + '
Введи числовой ответ. Допуск $\\pm 0{,}05$. Для $\\pi$ используй $3{,}14$.
' + + '
' + + '
Решено: 0 / 5
' + + '
'; + + html += secNavFor('p8'); + html += readButton('p8'); + + box.innerHTML = html; + renderMath(box); + + /* IV1 — Квикфайр */ + (function(){ + const tasks = [ + { q:'В прямоугольном треугольнике даны оба катета. Найти гипотенузу.', a:'pyth' }, + { q:'В произвольном треугольнике даны две стороны и угол между ними. Найти третью сторону.', a:'cos' }, + { q:'Дана сторона и противолежащий ей угол. Найти радиус описанной окружности.', a:'sin' }, + { q:'В треугольнике даны все три стороны. Найти один из углов.', a:'cos' }, + { q:'Даны два угла и сторона. Найти другую сторону.', a:'sin' }, + { q:'В прямоугольном треугольнике даны катет и гипотенуза. Найти второй катет.', a:'pyth' }, + { q:'Даны две стороны и угол между ними. Найти третью сторону.', a:'cos' }, + { q:'Сторона и противолежащий угол в произвольном треугольнике. Найти радиус $R$.', a:'sin' } + ]; + const LABELS = {pyth:'Пифагор', sin:'Синусов', cos:'Косинусов'}; + const area = document.getElementById('p8-iv1-area'); + const scoreEl = document.getElementById('p8-iv1-score'); + const solved = new Set(); + let xpGiven = false; + + area.innerHTML = tasks.map(function(t, i){ + return '
' + + '
Вопрос '+(i+1)+'. '+t.q+'
' + + '
' + + '' + + '' + + '' + + '
' + + '
' + + '
'; + }).join(''); + renderMath(area); + + area.querySelectorAll('button[data-i]').forEach(function(b){ + b.addEventListener('click', function(){ + const i = +b.dataset.i, v = b.dataset.v, t = tasks[i]; + const fb = document.getElementById('p8-iv1-fb-'+i); + if(v === t.a){ + feedback(fb, true, '✓ Верно — теорема '+LABELS[t.a]+'!'); + if(!solved.has(i)){ + solved.add(i); + scoreEl.textContent = solved.size; + if(solved.size === tasks.length && !xpGiven){ + xpGiven = true; + addXp(10, 'p8-iv1'); + bumpProgress('p8', 20); + } + } + } else { + feedback(fb, false, '✗ Неверно. Подумай: что дано — прямоуг. $\\triangle$? Угол между двумя сторонами? Сторона + противолежащий угол?'); + } + }); + }); + })(); + + /* IV2 — DnD сортер */ + (function(){ + const items = [ + { id:'q1', html:'4 стороны равны, все углы прямые', cat:'square' }, + { id:'q2', html:'4 стороны равны, углы не обязательно прямые', cat:'rhomb' }, + { id:'q3', html:'Противоположные стороны равны и параллельны', cat:'rect' }, + { id:'q4', html:'2 параллельные стороны (основания) разной длины', cat:'trap' }, + { id:'q5', html:'4 угла по $90°$, противоположные стороны равны', cat:'rect' }, + { id:'q6', html:'Все 4 угла $90°$ и все стороны равны', cat:'square' } + ]; + const sorter = setupSorter({ + poolId:'p8-iv2-pool', + scopeSelector:'#p8-iv2', + items: items, + cats: ['square','rhomb','rect','trap'] + }); + let xpGiven = false; + document.getElementById('p8-iv2-check').addEventListener('click', function(){ + const fb = document.getElementById('p8-iv2-fb'); + let correct = 0; + items.forEach(function(it){ if(sorter.placed[it.id] === it.cat) correct++; }); + if(correct === items.length){ + feedback(fb, true, '✓ Все 6 правильно! +15 XP'); + if(!xpGiven){ + xpGiven = true; + addXp(15, 'p8-iv2'); + bumpProgress('p8', 30); + } + } else { + feedback(fb, false, '✗ Правильно: '+correct+' из '+items.length+'. Попробуй ещё раз.'); + } + }); + document.getElementById('p8-iv2-reset').addEventListener('click', function(){ + sorter.reset(); + const fb = document.getElementById('p8-iv2-fb'); fb.style.display = 'none'; + }); + })(); + + /* IV3 — Тренажёр повторения */ + (function(){ + const tasks = [ + { q:'Треугольник со сторонами 3, 4, 5. Какой угол (в градусах) лежит против стороны 5?', a:90, tol:0.05 }, + { q:'В прямоугольном треугольнике катеты 6 и 8. Найди гипотенузу.', a:10, tol:0.05 }, + { q:'Чему равна сумма углов выпуклого 5-угольника (в градусах)?', a:540, tol:0.05 }, + { q:'В круге $R=6$. Длина окружности ($\\pi\\approx 3{,}14$)?', a:37.68, tol:0.05 }, + { q:'Треугольник со сторонами 7, 8, 9. Найди площадь по формуле Герона (точность 0,01).', a:26.83, tol:0.05 } + ]; + const list = document.getElementById('p8-iv3-list'); + const scoreEl = document.getElementById('p8-iv3-score'); + const solved = new Set(); + let xpGiven = false; + + list.innerHTML = tasks.map(function(t, i){ + return '
' + + '
Задача '+(i+1)+'. '+t.q+'
' + + '
' + + '' + + '' + + '
' + + '
' + + '
'; + }).join(''); + renderMath(list); + + list.querySelectorAll('button[data-i]').forEach(function(b){ + b.addEventListener('click', function(){ + const i = +b.dataset.i, t = tasks[i]; + const inp = document.getElementById('p8-iv3-inp-'+i); + const fb = document.getElementById('p8-iv3-fb-'+i); + const raw = (inp.value || '').replace(',', '.').trim(); + const val = parseFloat(raw); + if(!isFinite(val)){ feedback(fb, false, '✗ Введи число'); return; } + if(Math.abs(val - t.a) <= t.tol){ + feedback(fb, true, '✓ Верно!'); + if(!solved.has(i)){ + solved.add(i); + scoreEl.textContent = solved.size; + if(solved.size === tasks.length && !xpGiven){ + xpGiven = true; + addXp(15, 'p8-iv3'); + bumpProgress('p8', 30); + setTimeout(function(){ achievement('p8_done'); }, 400); + } + } + } else { + feedback(fb, false, '✗ Не точно. Пересчитай аккуратно.'); + } + }); + }); + })(); + + wireReadBtn('p8'); +} + +/* ===== §9 «Геометрические величины» (площади + объёмы — обзор) ===== */ + +function buildP9(){ + const box = document.getElementById('p9-body'); + if(!box) return; + let html = ''; + + /* === ТЕОРИЯ === */ + + html += makeCard('theory', 'Площади плоских фигур', '§ 9.1', + '

Треугольник. Несколько эквивалентных формул:

' + + '

$S = \\dfrac{1}{2} a h_a = \\dfrac{1}{2} a b \\sin C = \\sqrt{p(p-a)(p-b)(p-c)} = \\dfrac{abc}{4R} = p r$

' + + '

где $p = \\dfrac{a+b+c}{2}$, $R$ — описанная, $r$ — вписанная окружности.

' + + '

Четырёхугольники:

' + + '' + + '

Круг и сектор:

' + + '

$S_{круг} = \\pi R^2,\\qquad S_{сект} = \\dfrac{\\pi R^2 \\alpha}{360°}$

'); + + html += makeCard('example', 'Объёмы тел в пространстве', '§ 9.2', + '

Сводная таблица формул объёмов (повторение §§ 1–6):

' + + '' + + '

Ключевая идея. Объёмы «остроконечных» тел (пирамида, конус) в 3 раза меньше объёма «призменных» аналогов с той же основой и высотой: $V_{пир} = \\frac{1}{3} V_{призмы}$, $V_{конус} = \\frac{1}{3} V_{цил}$.

' + + '
Пример сравнения: $R=3$, $h=4$
' + + '' + + '
'); + + /* === ИНТЕРАКТИВ 1 — Универсальный калькулятор === */ + html += '
' + + '
калькулятор
$S$ и $V$ — универсальный
' + + '
Выбери фигуру, введи параметры. После 5 разных фигур — +10 XP.
' + + '
' + + '' + + '
' + + '
' + + '
' + + '
Выбери фигуру и параметры, затем нажми «Вычислить».
' + + '
Фигур изучено: 0 / 5
' + + '
'; + + /* === ИНТЕРАКТИВ 2 — Тренажёр площадей === */ + html += '
' + + '
тренажёр площадей · 6 задач
Найди площадь $S$
' + + '
Введи числовой ответ. Допуск $\\pm 0{,}05$. Для $\\pi$ используй $3{,}14$.
' + + '
' + + '
Решено: 0 / 6
' + + '
'; + + /* === ИНТЕРАКТИВ 3 — Тренажёр объёмов === */ + html += '
' + + '
тренажёр объёмов · 6 задач
Найди объём $V$
' + + '
Введи числовой ответ. Допуск $\\pm 0{,}05$. Для $\\pi$ используй $3{,}14$.
' + + '
' + + '
Решено: 0 / 6
' + + '
'; + + html += secNavFor('p9'); + html += readButton('p9'); + + box.innerHTML = html; + renderMath(box); + + /* IV1 — Универсальный калькулятор */ + (function(){ + const PI = 3.14; + /* Спецификация полей: { key, label, defValue } */ + const SPEC = { + rect: { name:'Прямоугольник', fields:[['a','$a$',5],['b','$b$',8]], calc:p=>({fx:'S = a\\cdot b = '+p.a+'\\cdot '+p.b+' = '+(p.a*p.b).toFixed(2), val:p.a*p.b, unit:'S'}) }, + tri: { name:'Треугольник', fields:[['a','$a$',5],['b','$b$',8],['C','$C°$',30]], calc:p=>{const v=0.5*p.a*p.b*Math.sin(p.C*Math.PI/180); return {fx:'S = \\tfrac{1}{2}ab\\sin C = \\tfrac{1}{2}\\cdot '+p.a+'\\cdot '+p.b+'\\cdot \\sin '+p.C+'° = '+v.toFixed(2), val:v, unit:'S'};} }, + par: { name:'Параллелограмм', fields:[['a','$a$',6],['b','$b$',10],['A','$\\alpha°$',30]], calc:p=>{const v=p.a*p.b*Math.sin(p.A*Math.PI/180); return {fx:'S = ab\\sin\\alpha = '+p.a+'\\cdot '+p.b+'\\cdot \\sin '+p.A+'° = '+v.toFixed(2), val:v, unit:'S'};} }, + rhomb: { name:'Ромб', fields:[['d1','$d_1$',6],['d2','$d_2$',8]], calc:p=>({fx:'S = \\tfrac{1}{2}d_1 d_2 = \\tfrac{1}{2}\\cdot '+p.d1+'\\cdot '+p.d2+' = '+(0.5*p.d1*p.d2).toFixed(2), val:0.5*p.d1*p.d2, unit:'S'}) }, + trap: { name:'Трапеция', fields:[['a','$a$',4],['b','$b$',8],['h','$h$',5]], calc:p=>({fx:'S = \\tfrac{a+b}{2}\\cdot h = \\tfrac{'+p.a+'+'+p.b+'}{2}\\cdot '+p.h+' = '+(0.5*(p.a+p.b)*p.h).toFixed(2), val:0.5*(p.a+p.b)*p.h, unit:'S'}) }, + circ: { name:'Круг', fields:[['R','$R$',4]], calc:p=>({fx:'S = \\pi R^2 \\approx 3{,}14\\cdot '+p.R+'^2 = '+(PI*p.R*p.R).toFixed(2), val:PI*p.R*p.R, unit:'S'}) }, + prism: { name:'Призма', fields:[['So','$S_{осн}$',12],['h','$h$',5]], calc:p=>({fx:'V = S_{осн}\\cdot h = '+p.So+'\\cdot '+p.h+' = '+(p.So*p.h).toFixed(2), val:p.So*p.h, unit:'V'}) }, + cyl: { name:'Цилиндр', fields:[['R','$R$',3],['h','$h$',5]], calc:p=>({fx:'V = \\pi R^2 h \\approx 3{,}14\\cdot '+p.R+'^2\\cdot '+p.h+' = '+(PI*p.R*p.R*p.h).toFixed(2), val:PI*p.R*p.R*p.h, unit:'V'}) }, + pyr: { name:'Пирамида', fields:[['So','$S_{осн}$',24],['h','$h$',5]], calc:p=>({fx:'V = \\tfrac{1}{3}S_{осн}h = \\tfrac{1}{3}\\cdot '+p.So+'\\cdot '+p.h+' = '+(p.So*p.h/3).toFixed(2), val:p.So*p.h/3, unit:'V'}) }, + cone: { name:'Конус', fields:[['R','$R$',6],['h','$h$',5]], calc:p=>({fx:'V = \\tfrac{1}{3}\\pi R^2 h \\approx \\tfrac{1}{3}\\cdot 3{,}14\\cdot '+p.R+'^2\\cdot '+p.h+' = '+(PI*p.R*p.R*p.h/3).toFixed(2), val:PI*p.R*p.R*p.h/3, unit:'V'}) }, + sph: { name:'Шар', fields:[['R','$R$',3]], calc:p=>({fx:'V = \\tfrac{4}{3}\\pi R^3 \\approx \\tfrac{4}{3}\\cdot 3{,}14\\cdot '+p.R+'^3 = '+(4*PI*p.R*p.R*p.R/3).toFixed(2), val:4*PI*p.R*p.R*p.R/3, unit:'V'}) } + }; + const sel = document.getElementById('p9-iv1-fig'); + const fields = document.getElementById('p9-iv1-fields'); + const out = document.getElementById('p9-iv1-out'); + const oCnt = document.getElementById('p9-iv1-cnt'); + const seen = new Set(); + let xpGiven = false; + + function renderFields(){ + const sp = SPEC[sel.value]; + fields.innerHTML = sp.fields.map(function(f){ + return ''; + }).join(''); + renderMath(fields); + } + sel.addEventListener('change', function(){ renderFields(); out.innerHTML = 'Параметры обновлены. Нажми «Вычислить».'; }); + renderFields(); + + document.getElementById('p9-iv1-calc').addEventListener('click', function(){ + const key = sel.value; + const sp = SPEC[key]; + const p = {}; + let bad = false; + sp.fields.forEach(function(f){ + const el = document.getElementById('p9-iv1-f-'+f[0]); + const raw = (el.value || '').replace(',', '.').trim(); + const v = parseFloat(raw); + if(!isFinite(v) || v <= 0){ bad = true; } + p[f[0]] = v; + }); + if(bad){ out.innerHTML = 'Введи положительные числа во все поля.'; return; } + const r = sp.calc(p); + out.innerHTML = '

'+sp.name+'

' + + '

$$ '+r.fx+' $$

' + + '

Ответ: $'+r.unit+' \\approx '+r.val.toFixed(2)+'$

'; + renderMath(out); + seen.add(key); + oCnt.textContent = seen.size; + if(seen.size >= 5 && !xpGiven){ + xpGiven = true; + addXp(10, 'p9-iv1'); + bumpProgress('p9', 20); + } + }); + })(); + + /* IV2 — Тренажёр площадей */ + (function(){ + const tasks = [ + { q:'Прямоугольник $5 \\times 8$. Найди площадь.', a:40, tol:0.05 }, + { q:'Круг $R=4$. Найди площадь ($\\pi\\approx 3{,}14$).', a:50.24, tol:0.05 }, + { q:'Треугольник со сторонами 5, 12, 13. Найди площадь.', a:30, tol:0.05 }, + { q:'Трапеция: основания 4 и 8, высота 5. Найди площадь.', a:30, tol:0.05 }, + { q:'Параллелограмм со сторонами 6 и 10, угол $30°$. Площадь?', a:30, tol:0.05 }, + { q:'Ромб с диагоналями 6 и 8. Площадь?', a:24, tol:0.05 } + ]; + const list = document.getElementById('p9-iv2-list'); + const scoreEl = document.getElementById('p9-iv2-score'); + const solved = new Set(); + let xpGiven = false; + + list.innerHTML = tasks.map(function(t, i){ + return '
' + + '
Задача '+(i+1)+'. '+t.q+'
' + + '
' + + '' + + '' + + '
' + + '
' + + '
'; + }).join(''); + renderMath(list); + + list.querySelectorAll('button[data-i]').forEach(function(b){ + b.addEventListener('click', function(){ + const i = +b.dataset.i, t = tasks[i]; + const inp = document.getElementById('p9-iv2-inp-'+i); + const fb = document.getElementById('p9-iv2-fb-'+i); + const raw = (inp.value || '').replace(',', '.').trim(); + const val = parseFloat(raw); + if(!isFinite(val)){ feedback(fb, false, '✗ Введи число'); return; } + if(Math.abs(val - t.a) <= t.tol){ + feedback(fb, true, '✓ Верно!'); + if(!solved.has(i)){ + solved.add(i); + scoreEl.textContent = solved.size; + if(solved.size === tasks.length && !xpGiven){ + xpGiven = true; + addXp(15, 'p9-iv2'); + bumpProgress('p9', 30); + } + } + } else { + feedback(fb, false, '✗ Не точно. Пересчитай аккуратно.'); + } + }); + }); + })(); + + /* IV3 — Тренажёр объёмов */ + (function(){ + const tasks = [ + { q:'Куб со стороной 4. Найди $V$.', a:64, tol:0.05 }, + { q:'Прямоугольный параллелепипед $3\\times 4\\times 5$. Найди $V$.', a:60, tol:0.05 }, + { q:'Цилиндр $R=3$, $h=5$. Найди $V$ ($\\pi\\approx 3{,}14$).', a:141.3, tol:0.05 }, + { q:'Пирамида: $S_{осн}=24$, $h=5$. Найди $V$.', a:40, tol:0.05 }, + { q:'Конус $R=6$, $h=5$. Найди $V$ ($\\pi\\approx 3{,}14$).', a:188.4, tol:0.05 }, + { q:'Шар $R=3$. Найди $V$ ($\\pi\\approx 3{,}14$).', a:113.04, tol:0.05 } + ]; + const list = document.getElementById('p9-iv3-list'); + const scoreEl = document.getElementById('p9-iv3-score'); + const solved = new Set(); + let xpGiven = false; + + list.innerHTML = tasks.map(function(t, i){ + return '
' + + '
Задача '+(i+1)+'. '+t.q+'
' + + '
' + + '' + + '' + + '
' + + '
' + + '
'; + }).join(''); + renderMath(list); + + list.querySelectorAll('button[data-i]').forEach(function(b){ + b.addEventListener('click', function(){ + const i = +b.dataset.i, t = tasks[i]; + const inp = document.getElementById('p9-iv3-inp-'+i); + const fb = document.getElementById('p9-iv3-fb-'+i); + const raw = (inp.value || '').replace(',', '.').trim(); + const val = parseFloat(raw); + if(!isFinite(val)){ feedback(fb, false, '✗ Введи число'); return; } + if(Math.abs(val - t.a) <= t.tol){ + feedback(fb, true, '✓ Верно!'); + if(!solved.has(i)){ + solved.add(i); + scoreEl.textContent = solved.size; + if(solved.size === tasks.length && !xpGiven){ + xpGiven = true; + addXp(15, 'p9-iv3'); + bumpProgress('p9', 30); + setTimeout(function(){ achievement('p9_done'); }, 400); + } + } + } else { + feedback(fb, false, '✗ Не точно. Пересчитай аккуратно.'); + } + }); + }); + })(); + + wireReadBtn('p9'); +} + /* ===== Search ===== */ const SEARCH_INDEX = (function(){ const arr=[];