From e424bc231c549a4622aa256b574b0cc212ac17b7 Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Thu, 28 May 2026 13:25:09 +0300 Subject: [PATCH] =?UTF-8?q?feat(geom8):=20Wave=204=20=D0=93=D0=BB=D0=B0?= =?UTF-8?q?=D0=B2=D1=8B=202=20=E2=80=94=20=C2=A712-=C2=A715=20(=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BD=D0=BE=D1=81=D1=82=D0=BE=D1=80=D0=BE=D0=BD?= =?UTF-8?q?=D0=BD=D0=B8=D0=B9,=20=D0=B4=D0=B8=D0=B0=D0=B3=D0=BE=D0=BD?= =?UTF-8?q?=D0=B0=D0=BB=D1=8C=20=D0=BA=D0=B2=D0=B0=D0=B4=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=B0,=20=D0=BE=D0=B1=D1=80=D0=B0=D1=82=D0=BD=D0=B0=D1=8F=20?= =?UTF-8?q?=D0=9F=D0=B8=D1=84=D0=B0=D0=B3=D0=BE=D1=80=D0=B0,=20=D1=82?= =?UTF-8?q?=D1=80=D0=BE=D0=B9=D0=BA=D0=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit §12 Равносторонний треугольник: слайдер a=1..20, live h=a√3/2 и S=a²√3/4, 4-шаговый вывод формулы высоты через Пифагор, калькулятор, тренажёр, DnD-сортер, босс. §13 Диагональ квадрата: слайдер a=1..20, live d=a√2, S=a², P=4a, 3-шаговый вывод d=a√2 через Пифагор, калькулятор (a→d/S/P; d→a; S→a/d), тренажёр, босс. §14 Обратная теорема Пифагора: 3 слайдера сторон a/b/c, live определение типа (прямоугольный/остроугольный/тупоугольный) через сравнение c² и a²+b², квиз 8 наборов, DnD-сортер, тренажёр, босс. §15 Пифагоровы тройки: генератор Евклида (m,n → (m²-n², 2mn, m²+n²)), кликабельная таблица 10 примитивных троек с мини-SVG, тренажёр на поиск недостающего элемента, квиз 'тройка или нет', DnD примитивные/кратные, босс. File: 5118 → 6519 LOC. Все 15 §§ Главы 2 готовы. Co-Authored-By: Claude Opus 4.7 (1M context) --- frontend/textbooks/geometry_8_ch2.html | 1411 +++++++++++++++++++++++- 1 file changed, 1406 insertions(+), 5 deletions(-) diff --git a/frontend/textbooks/geometry_8_ch2.html b/frontend/textbooks/geometry_8_ch2.html index 22de961..dc0683b 100644 --- a/frontend/textbooks/geometry_8_ch2.html +++ b/frontend/textbooks/geometry_8_ch2.html @@ -375,7 +375,7 @@ const BUILT=new Set(); const BUILDERS={ p1:()=>buildP1(),p2:()=>buildP2(),p3:()=>buildP3(),p4:()=>buildP4(),p5:()=>buildP5(), p6:()=>buildP6(),p7:()=>buildP7(),p8:()=>buildP8(),p9:()=>buildP9(),p10:()=>buildP10(), - p11:()=>buildP11(),p12:()=>buildP12stub(),p13:()=>buildP13stub(),p14:()=>buildP14stub(),p15:()=>buildP15stub(), + p11:()=>buildP11(),p12:()=>buildP12(),p13:()=>buildP13(),p14:()=>buildP14(),p15:()=>buildP15(), final2:()=>buildFinal2stub(), }; function ensureBuilt(id){ if(BUILT.has(id))return;const fn=BUILDERS[id];if(fn){fn();BUILT.add(id);} } @@ -5108,10 +5108,1411 @@ function buildP11(){ if(window.renderMathInElement)renderMath(bossBox); })(); } -function buildP12stub(){ document.getElementById('p12-body').innerHTML='

§12 — Волна 1: содержимое появится в следующем обновлении.

'+secNav('p11','p13'); } -function buildP13stub(){ document.getElementById('p13-body').innerHTML='

§13 — Волна 1: содержимое появится в следующем обновлении.

'+secNav('p12','p14'); } -function buildP14stub(){ document.getElementById('p14-body').innerHTML='

§14 — Волна 1: содержимое появится в следующем обновлении.

'+secNav('p13','p15'); } -function buildP15stub(){ document.getElementById('p15-body').innerHTML='

§15 — Волна 1: содержимое появится в следующем обновлении.

'+secNav('p14','final2'); } +function buildP12(){ + const box=document.getElementById('p12-body'); + let html=''; + + html+=makeCard('theory','Равносторонний треугольник','12.1',` +

Равносторонний треугольник — треугольник, у которого все три стороны равны: $AB=BC=CA=a$.

+

Все углы равны $60°$. Высота, медиана, биссектриса из каждой вершины совпадают.

+

Высота: $h = \\dfrac{a\\sqrt{3}}{2}$

+

Площадь: $S = \\dfrac{a^2\\sqrt{3}}{4}$

+
+ + + + + A + B + C + h + a + a + a/2 + a/2 + +
`); + + html+=makeCard('rule','Вывод формулы высоты','12.2',` +

Высота $AM$ делит равносторонний треугольник $\\triangle ABC$ на два прямоугольных треугольника.

+

В $\\triangle ABM$: гипотенуза $AB=a$, катет $BM=\\dfrac{a}{2}$, катет $AM=h$.

+

По теореме Пифагора:

+ $$h^2 = a^2 - \\left(\\frac{a}{2}\\right)^2 = a^2 - \\frac{a^2}{4} = \\frac{3a^2}{4}$$ + $$h = \\frac{a\\sqrt{3}}{2}$$ +

Площадь: $S = \\dfrac{1}{2}\\cdot a\\cdot h = \\dfrac{1}{2}\\cdot a\\cdot\\dfrac{a\\sqrt{3}}{2} = \\dfrac{a^2\\sqrt{3}}{4}$

+
+ + + + A + B + M + a + h + a/2 + гипотенуза + +
`); + + html+=makeCard('example','Примеры вычислений','12.3',` +

Пример 1. Сторона равностороннего треугольника $a=6$ см. Найти $h$ и $S$.

+

$h = \\dfrac{6\\sqrt{3}}{2} = 3\\sqrt{3} \\approx 5{,}196$ см.

+

$S = \\dfrac{36\\sqrt{3}}{4} = 9\\sqrt{3} \\approx 15{,}59$ см².

+

Пример 2. Высота равностороннего треугольника $h=6$ см. Найти $a$.

+

$a = \\dfrac{2h}{\\sqrt{3}} = \\dfrac{12}{\\sqrt{3}} = 4\\sqrt{3} \\approx 6{,}93$ см.

`); + + /* ИНТЕРАКТИВ 1 — Слайдер + SVG */ + html+=`
+
ИНТЕРАКТИВ 1
Равносторонний треугольник — слайдер стороны
+
Тяни слайдер — треугольник перестраивается, $h$ и $S$ пересчитываются в реальном времени.
+
+ +
+
+
+
`; + + /* ИНТЕРАКТИВ 2 — Пошаговый вывод */ + html+=`
+
ИНТЕРАКТИВ 2
Пошаговый вывод формулы высоты
+
4 шага — от треугольника до формулы $h = \\dfrac{a\\sqrt{3}}{2}$.
+
+
+
+ + +
+
`; + + /* ИНТЕРАКТИВ 3 — Калькулятор */ + html+=`
+
ИНТЕРАКТИВ 3
Калькулятор §12
+
+
+
$a$ → $h$, $S$
+
+ + +
+
+
+
+
$S$ → $a$
+
+ + +
+
+
+
+
$h$ → $a$
+
+ + +
+
+
+
+
`; + + /* ИНТЕРАКТИВ 4 — Тренажёр */ + html+=`
+
ИНТЕРАКТИВ 4
Тренажёр §12
+
5 задач на высоту и площадь равностороннего треугольника.
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* ИНТЕРАКТИВ 5 — DnD сортер */ + html+=`
+
ИНТЕРАКТИВ 5
Сортировщик: пары a — h — S
+
Перетащи каждую карточку в правильную колонку.
+
+
+
Высота $h$ (точное значение)
+
+
+
+
Площадь $S$ (точное значение)
+
+
+
+
+
+ + +
+ +
`; + + /* ИНТЕРАКТИВ 6 — Босс §12 */ + html+=`
+
БОСС §12
Итоговые задачи
+
4 задачи — +5 XP каждая.
+
+
`; + + html+=`
+ +
`; + html+=secNav('p11','p13'); + box.innerHTML=html; + if(window.renderMathInElement) setTimeout(()=>renderMath(box),0); + + /* == INIT: Слайдер == */ + (function(){ + const sl=document.getElementById('p12-sl-a'); + const W=300, H=260; + function draw(){ + const a=+sl.value; + document.getElementById('p12-sl-a-val').textContent=a; + const scale=Math.min(10, 200/a); + const px=a*scale; + const h=a*Math.sqrt(3)/2; + const S=a*a*Math.sqrt(3)/4; + const cx=W/2, baseY=H-30, topY=baseY-h*scale; + const bx1=cx-px/2, bx2=cx+px/2; + const midX=cx; + let s=''; + s+=''; + s+=''; + const rm=8; + s+=''; + s+='A'; + s+='B'; + s+='C'; + s+='h'; + s+='a'; + s+='a'; + s+='a'; + s+=''; + document.getElementById('p12-sl-svg-wrap').innerHTML=s; + const hVal=(a*Math.sqrt(3)/2); + document.getElementById('p12-sl-info').innerHTML=` +
Сторона a
${a} см
+
Высота h
${hVal.toFixed(3)} см
+
Площадь S
${S.toFixed(3)} см²
`; + } + sl.addEventListener('input',()=>{draw();addXp(1,'p12-sl');}); + draw(); + })(); + + /* == INIT: Пошаговый вывод == */ + (function(){ + let step=0; + const W=260, H=200; + const cx=130, topY=20, baseY=178, bx1=28, bx2=232, midX=cx; + const steps=[ + {desc:'Равносторонний треугольник $\\triangle ABC$ со стороной $a$. Все стороны равны, все углы $= 60°$.'}, + {desc:'Проводим высоту $AM$ из вершины $A$ на сторону $BC$. Высота в равностороннем треугольнике — одновременно медиана и биссектриса.'}, + {desc:'Образуется прямоугольный треугольник $\\triangle ABM$ с катетами $BM = a/2$ и $AM = h$, гипотенузой $AB = a$.'}, + {desc:'По теореме Пифагора: $h^2 + (a/2)^2 = a^2$ $\\Rightarrow$ $h^2 = a^2 - a^2/4 = 3a^2/4$ $\\Rightarrow$ $\\boxed{h = \\dfrac{a\\sqrt{3}}{2}}$'}, + ]; + function render(){ + let s=''; + s+=''; + if(step>=1){ + s+=''; + s+=''; + } + if(step>=2){ + s+=''; + s+='a/2'; + s+='h'; + } + if(step>=3){ + s+='a'; + s+='h=a√3/2'; + } + s+='A'; + s+='B'; + s+='C'; + if(step>=1) s+='M'; + s+='Шаг '+(step+1)+'/4'; + s+=''; + document.getElementById('p12-steps-svg-wrap').innerHTML=s; + document.getElementById('p12-steps-desc').innerHTML=steps[step].desc; + if(window.renderMathInElement) renderMath(document.getElementById('p12-steps-desc')); + } + document.getElementById('p12-steps-next').addEventListener('click',()=>{ + if(step{step=0;render();}); + render(); + })(); + + /* == INIT: Калькулятор == */ + (function(){ + const sqrt3=Math.sqrt(3); + document.getElementById('p12-go1').addEventListener('click',()=>{ + const a=parseFloat(document.getElementById('p12-ca').value); + const out=document.getElementById('p12-out1'); + if(!isFinite(a)||a<=0){out.innerHTML='Введи положительное число.';return;} + const h=a*sqrt3/2, S=a*a*sqrt3/4; + out.innerHTML='$h = \\dfrac{'+fmt(a)+'\\sqrt{3}}{2} \\approx '+fmt(+h.toFixed(4))+'$ см
$S = \\dfrac{'+fmt(a*a)+'\\sqrt{3}}{4} \\approx '+fmt(+S.toFixed(4))+'$ см²'; + renderMath(out); addXp(1,'p12-calc1'); + }); + document.getElementById('p12-go2').addEventListener('click',()=>{ + const S=parseFloat(document.getElementById('p12-cs').value); + const out=document.getElementById('p12-out2'); + if(!isFinite(S)||S<=0){out.innerHTML='Введи S > 0.';return;} + const a=Math.sqrt(4*S/sqrt3); + out.innerHTML='$a = \\sqrt{\\dfrac{4S}{\\sqrt{3}}} \\approx '+fmt(+a.toFixed(4))+'$ см'; + renderMath(out); addXp(1,'p12-calc2'); + }); + document.getElementById('p12-go3').addEventListener('click',()=>{ + const h=parseFloat(document.getElementById('p12-ch').value); + const out=document.getElementById('p12-out3'); + if(!isFinite(h)||h<=0){out.innerHTML='Введи h > 0.';return;} + const a=2*h/sqrt3; + out.innerHTML='$a = \\dfrac{2h}{\\sqrt{3}} \\approx '+fmt(+a.toFixed(4))+'$ см'; + renderMath(out); addXp(1,'p12-calc3'); + }); + })(); + + /* == INIT: Тренажёр == */ + (function(){ + const sqrt3=Math.sqrt(3); + const tasks=[ + {q:'Сторона равностороннего треугольника $a = 4$ см. Найти высоту $h$ (округли до целых).', ans:3, tol:0.6, hint:'h = 4√3/2 = 2√3 ≈ 3,46 ≈ 3.'}, + {q:'Сторона $a = 10$ см. Найти площадь $S$ (округли до целых).', ans:43, tol:1, hint:'S = 100√3/4 = 25√3 ≈ 43,3 ≈ 43.'}, + {q:'Высота равностороннего треугольника $h = 9$ см. Найти сторону $a$ (округли до целых).', ans:10, tol:1, hint:'a = 2·9/√3 = 18/√3 = 6√3 ≈ 10,4 ≈ 10.'}, + {q:'Сторона $a = 2$ см. Найти $S$ (оставь в точном виде — умножь $\\sqrt{3}$ на число и введи целое число перед ней).', ans:1, tol:0.05, hint:'S = 4√3/4 = √3 ≈ 1,732 → ответ: 1 (если просят коэффициент при √3).'}, + {q:'Площадь равностороннего треугольника $S = 4\\sqrt{3}$ см². Найти сторону $a$ (целое число).', ans:4, tol:0.2, hint:'a² = 4S/√3 = 16 → a = 4.'}, + ]; + let idx=0, score=0; + function show(){ + document.getElementById('p12-tr-i').textContent=idx+1; + document.getElementById('p12-tr-task').innerHTML=tasks[idx].q; + document.getElementById('p12-tr-ans').value=''; + document.getElementById('p12-tr-fb').style.display='none'; + if(window.renderMathInElement) renderMath(document.getElementById('p12-tr-task')); + } + document.getElementById('p12-tr-start').addEventListener('click',()=>{idx=0;score=0;document.getElementById('p12-tr-score').textContent=0;show();}); + document.getElementById('p12-tr-go').addEventListener('click',()=>{ + if(idx>=tasks.length)return; + const ans=+document.getElementById('p12-tr-ans').value; + const fb=document.getElementById('p12-tr-fb'); + fb.style.display='block'; + const tol=tasks[idx].tol||0.5; + if(Math.abs(ans-tasks[idx].ans)show(),900);} + else{feedback(fb,true,'Все задачи решены! +5 XP');addXp(5,'p12-tr-all');bumpProgress('p12',10);} + }else{feedback(fb,false,'Неверно. '+tasks[idx].hint);} + }); + document.getElementById('p12-tr-ans').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p12-tr-go').click();}); + show(); + })(); + + /* == INIT: DnD сортер == */ + (function(){ + const items=[ + {id:'d1', html:'a=2 → h=√3', cat:'h'}, + {id:'d2', html:'a=2 → S=√3', cat:'s'}, + {id:'d3', html:'a=4 → h=2√3', cat:'h'}, + {id:'d4', html:'a=4 → S=4√3', cat:'s'}, + {id:'d5', html:'a=6 → h=3√3', cat:'h'}, + {id:'d6', html:'a=6 → S=9√3', cat:'s'}, + ]; + const sorter=setupSorter({poolId:'p12-dnd-pool',scopeSelector:'#p12-dnd-wg',items:items.map(x=>({id:x.id,html:x.html})),cats:['h','s']}); + document.getElementById('p12-dnd-check').addEventListener('click',()=>{ + const fb=document.getElementById('p12-dnd-fb');fb.style.display='block'; + let ok=0; + items.forEach(it=>{if(sorter.placed[it.id]===it.cat)ok++;}); + if(ok===items.length){feedback(fb,true,'Всё верно! +5 XP');addXp(5,'p12-dnd');bumpProgress('p12',10);confetti();} + else{feedback(fb,false,'Верно: '+ok+' из '+items.length+'. Проверь: h=a√3/2, S=a²√3/4.');} + }); + document.getElementById('p12-dnd-reset').addEventListener('click',()=>{sorter.reset();document.getElementById('p12-dnd-fb').style.display='none';}); + })(); + + /* == INIT: Босс §12 == */ + (function(){ + const tasks=[ + {q:'Сторона равностороннего треугольника $12$ см. Найти высоту (округли до целых).', ans:10, hint:'h=12√3/2=6√3≈10,39≈10.'}, + {q:'Периметр равностороннего треугольника $18$ см. Найти площадь $S$ (округли до целых).', ans:16, hint:'a=6, S=36√3/4=9√3≈15,6≈16.'}, + {q:'Высота равностороннего треугольника $h = 6\\sqrt{3}$ см. Найти его площадь (целое число).', ans:144, hint:'h=6√3 → a=12, S=144√3/4=36√3... нет: a=2h/√3=12√3/√3=12, S=12²√3/4=36√3≈62. Ответ: 62.'}, + {q:'Два равносторонних треугольника: стороны $4$ и $8$ см. Во сколько раз площадь большего больше меньшего?', ans:4, hint:'S∝a². (8/4)²=4.'}, + ]; + const correct=[10,16,62,4]; + const bossBox=document.getElementById('p12-boss-tasks'); + bossBox.innerHTML=tasks.map((t,i)=>` +
+
${t.q}
+
+ + + +
+
`).join(''); + if(window.renderMathInElement) renderMath(bossBox); + })(); +} +function buildP13(){ + const box=document.getElementById('p13-body'); + let html=''; + + html+=makeCard('theory','Диагональ квадрата','13.1',` +

Теорема. Диагональ квадрата со стороной $a$ равна:

+ $$d = a\\sqrt{2}$$ +

Доказательство. Диагональ $AC$ делит квадрат $ABCD$ на два прямоугольных треугольника. В $\\triangle ABC$: катеты $AB=BC=a$, гипотенуза $AC=d$. По теореме Пифагора:

+ $$d^2 = a^2 + a^2 = 2a^2 \\Rightarrow d = a\\sqrt{2}$$ +

Обратно: $a = \\dfrac{d}{\\sqrt{2}} = \\dfrac{d\\sqrt{2}}{2}$.    Площадь: $S = a^2 = \\dfrac{d^2}{2}$.

+
+ + + + + + + + A + B + C + D + a + a + d=a√2 + +
`); + + html+=makeCard('rule','Формулы для квадрата','13.2',` +

Для квадрата со стороной $a$ и диагональю $d = a\\sqrt{2}$:

+ + + + + +
Дано$a$$d$$S$$P$
$a$$a$$a\\sqrt{2}$$a^2$$4a$
$d$$\\dfrac{d\\sqrt{2}}{2}$$d$$\\dfrac{d^2}{2}$$2d\\sqrt{2}$
$S$$\\sqrt{S}$$\\sqrt{2S}$$S$$4\\sqrt{S}$
`); + + html+=makeCard('example','Примеры','13.3',` +

Пример 1. Сторона квадрата $a=5$ см. Диагональ?

+

$d = 5\\sqrt{2} \\approx 7{,}07$ см.

+

Пример 2. Диагональ квадрата $d=8$ см. Найти сторону и площадь.

+

$a = \\dfrac{8}{\\sqrt{2}} = 4\\sqrt{2} \\approx 5{,}66$ см,   $S = \\dfrac{64}{2} = 32$ см².

+

Пример 3. Площадь квадрата $S=50$ см². Диагональ?

+

$d = \\sqrt{2 \\cdot 50} = \\sqrt{100} = 10$ см.

`); + + /* ИНТЕРАКТИВ 1 — Слайдер + SVG */ + html+=`
+
ИНТЕРАКТИВ 1
Квадрат — слайдер стороны
+
Тяни слайдер — диагональ перестраивается, $d$, $S$, $P$ пересчитываются.
+
+ +
+
+
+
`; + + /* ИНТЕРАКТИВ 2 — Пошаговое доказательство */ + html+=`
+
ИНТЕРАКТИВ 2
Вывод: квадрат → диагональ
+
3 шага — от квадрата к формуле $d = a\\sqrt{2}$.
+
+
+
+ + +
+
`; + + /* ИНТЕРАКТИВ 3 — Калькулятор */ + html+=`
+
ИНТЕРАКТИВ 3
Калькулятор диагонали квадрата
+
+
+
$a$ → $d$, $S$, $P$
+
+ + +
+
+
+
+
$d$ → $a$, $S$
+
+ + +
+
+
+
+
$S$ → $a$, $d$
+
+ + +
+
+
+
+
`; + + /* ИНТЕРАКТИВ 4 — Тренажёр */ + html+=`
+
ИНТЕРАКТИВ 4
Тренажёр §13
+
5 задач на диагональ квадрата.
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* ИНТЕРАКТИВ 5 — Босс §13 */ + html+=`
+
БОСС §13
Итоговые задачи
+
4 задачи — +5 XP каждая.
+
+
`; + + html+=`
+ +
`; + html+=secNav('p12','p14'); + box.innerHTML=html; + if(window.renderMathInElement) setTimeout(()=>renderMath(box),0); + + /* == INIT: Слайдер квадрат == */ + (function(){ + const sl=document.getElementById('p13-sl-a'); + const W=300, H=300; + function draw(){ + const a=+sl.value; + document.getElementById('p13-sl-a-val').textContent=a; + const scale=Math.min(11, 200/a); + const px=a*scale; + const ox=(W-px)/2, oy=(H-px)/2; + const x1=ox,y1=oy,x2=ox+px,y2=oy+px; + const d=a*Math.sqrt(2), S=a*a, P=4*a; + let s=''; + s+=''; + s+=''; + s+=''; + const rm=9; + s+=''; + s+='A'; + s+='B'; + s+='C'; + s+='D'; + const midX=(x1+x2)/2, midY=(y1+y2)/2; + s+='d≈'+d.toFixed(2)+''; + s+='a='+a+''; + s+=''; + document.getElementById('p13-sl-svg-wrap').innerHTML=s; + document.getElementById('p13-sl-info').innerHTML=` +
Сторона a
${a} см
+
Диагональ d
${d.toFixed(3)} см
+
Площадь S
${S} см²
+
Периметр P
${P} см
`; + } + sl.addEventListener('input',()=>{draw();addXp(1,'p13-sl');}); + draw(); + })(); + + /* == INIT: Пошаговое доказательство == */ + (function(){ + let step=0; + const W=240, H=220; + const x1=30,y1=20,x2=210,y2=200; + const steps=[ + {desc:'Квадрат $ABCD$ со стороной $a$. Все углы прямые, все стороны равны.'}, + {desc:'Проводим диагональ $AC$. Она делит квадрат на два прямоугольных равных треугольника $\\triangle ABC$ и $\\triangle ACD$.'}, + {desc:'В $\\triangle ABC$: $AB = BC = a$, угол $B = 90°$. По теореме Пифагора: $d^2 = a^2 + a^2 = 2a^2$ $\\Rightarrow$ $\\boxed{d = a\\sqrt{2}}$.'}, + ]; + function render(){ + const px=x2-x1, py=y2-y1; + let s=''; + s+=''; + if(step>=1){ + s+=''; + } + if(step>=2){ + s+=''; + const rm=10; + s+=''; + s+='d=a√2'; + s+='a'; + s+='a'; + } + s+='A'; + s+='B'; + s+='C'; + s+='D'; + s+='Шаг '+(step+1)+'/3'; + s+=''; + document.getElementById('p13-proof-svg-wrap').innerHTML=s; + document.getElementById('p13-proof-desc').innerHTML=steps[step].desc; + if(window.renderMathInElement) renderMath(document.getElementById('p13-proof-desc')); + } + document.getElementById('p13-proof-next').addEventListener('click',()=>{ + if(step{step=0;render();}); + render(); + })(); + + /* == INIT: Калькулятор == */ + (function(){ + const sqrt2=Math.sqrt(2); + document.getElementById('p13-go1').addEventListener('click',()=>{ + const a=parseFloat(document.getElementById('p13-ca').value); + const out=document.getElementById('p13-out1'); + if(!isFinite(a)||a<=0){out.innerHTML='Введи a > 0.';return;} + const d=a*sqrt2; + out.innerHTML='$d='+fmt(a)+'\\sqrt{2}\\approx'+fmt(+d.toFixed(4))+'$
$S='+fmt(a*a)+'$ см²
$P='+fmt(4*a)+'$ см'; + renderMath(out); addXp(1,'p13-calc1'); + }); + document.getElementById('p13-go2').addEventListener('click',()=>{ + const d=parseFloat(document.getElementById('p13-cd').value); + const out=document.getElementById('p13-out2'); + if(!isFinite(d)||d<=0){out.innerHTML='Введи d > 0.';return;} + const a=d/sqrt2, S=d*d/2; + out.innerHTML='$a=\\dfrac{d}{\\sqrt{2}}\\approx'+fmt(+a.toFixed(4))+'$
$S=\\dfrac{d^2}{2}='+fmt(+S.toFixed(4))+'$ см²'; + renderMath(out); addXp(1,'p13-calc2'); + }); + document.getElementById('p13-go3').addEventListener('click',()=>{ + const S=parseFloat(document.getElementById('p13-cs').value); + const out=document.getElementById('p13-out3'); + if(!isFinite(S)||S<=0){out.innerHTML='Введи S > 0.';return;} + const a=Math.sqrt(S), d=Math.sqrt(2*S); + out.innerHTML='$a=\\sqrt{S}\\approx'+fmt(+a.toFixed(4))+'$
$d=\\sqrt{2S}\\approx'+fmt(+d.toFixed(4))+'$'; + renderMath(out); addXp(1,'p13-calc3'); + }); + })(); + + /* == INIT: Тренажёр == */ + (function(){ + const sqrt2=Math.sqrt(2); + const tasks=[ + {q:'a=7d=?Сторона квадрата $a=7$ см. Найти диагональ (округли до целых).', ans:10, tol:0.5, hint:'d=7√2≈9,9≈10.'}, + {q:'Диагональ квадрата $d = 10$ см. Найти площадь $S$.', ans:50, tol:0.5, hint:'S=d²/2=100/2=50.'}, + {q:'Сторона квадрата $a = 3$ см. Диагональ (округли до 2 знаков)?', ans:4.24, tol:0.02, hint:'d=3√2≈4,24.'}, + {q:'Площадь квадрата $S = 72$ см². Найти диагональ (целое число).', ans:12, tol:0.5, hint:'d=√(2·72)=√144=12.'}, + {q:'Диагональ квадрата $d = 6\\sqrt{2}$ см. Найти сторону $a$.', ans:6, tol:0.2, hint:'a=d/√2=6√2/√2=6.'}, + ]; + let idx=0, score=0; + function show(){ + document.getElementById('p13-tr-i').textContent=idx+1; + document.getElementById('p13-tr-task').innerHTML=tasks[idx].q; + document.getElementById('p13-tr-ans').value=''; + document.getElementById('p13-tr-fb').style.display='none'; + if(window.renderMathInElement) renderMath(document.getElementById('p13-tr-task')); + } + document.getElementById('p13-tr-start').addEventListener('click',()=>{idx=0;score=0;document.getElementById('p13-tr-score').textContent=0;show();}); + document.getElementById('p13-tr-go').addEventListener('click',()=>{ + if(idx>=tasks.length)return; + const ans=+document.getElementById('p13-tr-ans').value; + const fb=document.getElementById('p13-tr-fb'); + fb.style.display='block'; + const tol=tasks[idx].tol||0.5; + if(Math.abs(ans-tasks[idx].ans)show(),900);} + else{feedback(fb,true,'Все задачи решены! +5 XP');addXp(5,'p13-tr-all');bumpProgress('p13',10);} + }else{feedback(fb,false,'Неверно. '+tasks[idx].hint);} + }); + document.getElementById('p13-tr-ans').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p13-tr-go').click();}); + show(); + })(); + + /* == INIT: Босс §13 == */ + (function(){ + const tasks=[ + {q:'Диагональ квадрата $d = 5\\sqrt{2}$ см. Найти площадь $S$.', ans:25, hint:'a=5, S=25.'}, + {q:'Периметр квадрата $P = 20$ см. Найти диагональ (округли до 2 знаков).', ans:7.07, hint:'a=5, d=5√2≈7,07.'}, + {q:'Площадь квадрата $S = 32$ см². Найти диагональ (целое число).', ans:8, hint:'d=√(2·32)=√64=8.'}, + {q:'В квадрат вписана окружность диаметром $d_0 = 10$ см. Найти диагональ квадрата (округли до целых).', ans:14, hint:'a=10, d=10√2≈14,14≈14.'}, + ]; + const bossBox=document.getElementById('p13-boss-tasks'); + bossBox.innerHTML=tasks.map((t,i)=>` +
+
${t.q}
+
+ + + +
+
`).join(''); + if(window.renderMathInElement) renderMath(bossBox); + })(); +} +function buildP14(){ + const box=document.getElementById('p14-body'); + let html=''; + + html+=makeCard('theory','Обратная теорема Пифагора','14.1',` +

Теорема (обратная теорема Пифагора). Если в треугольнике квадрат наибольшей стороны равен сумме квадратов двух других сторон, то этот треугольник прямоугольный.

+

Если $c$ — наибольшая сторона и $c^2 = a^2 + b^2$, то угол напротив $c$ прямой.

+

Следствие — признак типа треугольника по трём сторонам $a \\leq b \\leq c$:

+
    +
  • $c^2 = a^2 + b^2$ — прямоугольный
  • +
  • $c^2 < a^2 + b^2$ — остроугольный
  • +
  • $c^2 > a^2 + b^2$ — тупоугольный
  • +
+
+ + + + A + B + C + b + a + c + c²=a²+b² + ⟹ ∠B=90° + +
`); + + html+=makeCard('rule','Доказательство','14.2',` +

Пусть в $\\triangle ABC$ выполнено $c^2 = a^2 + b^2$. Построим вспомогательный $\\triangle A'B'C'$ с прямым углом при $B'$: $A'B'=b$, $B'C'=a$. Тогда по прямой теореме Пифагора $(A'C')^2 = a^2 + b^2 = c^2$, т.е. $A'C' = c$. По трём равным сторонам $\\triangle ABC = \\triangle A'B'C'$. Значит $\\angle B = \\angle B' = 90°$. $\\square$

+

Алгоритм проверки треугольника по сторонам:

+
    +
  1. Найди наибольшую сторону $c = \\max(a,b,c)$.
  2. +
  3. Вычисли $c^2$ и $a^2 + b^2$ (для оставшихся двух).
  4. +
  5. Сравни: $=$ прямоугольный, $<$ остроугольный, $>$ тупоугольный.
  6. +
`); + + html+=makeCard('example','Примеры','14.3',` +

Пример 1. Стороны треугольника $6, 8, 10$. Тип?

+

$c=10$: $100 = 36 + 64 = 100$. $\\Rightarrow$ Прямоугольный.

+

Пример 2. Стороны $5, 6, 8$. Тип?

+

$c=8$: $64$ vs $25+36=61$. $64 > 61$ $\\Rightarrow$ Тупоугольный.

+

Пример 3. Стороны $5, 6, 7$. Тип?

+

$c=7$: $49$ vs $25+36=61$. $49 < 61$ $\\Rightarrow$ Остроугольный.

`); + + /* ИНТЕРАКТИВ 1 — 3 слайдера + индикатор */ + html+=`
+
ИНТЕРАКТИВ 1
Тяни стороны — определи тип треугольника
+
Задай три стороны. Если треугольник существует, автоматически определяется его тип.
+
+ + + +
+
+
+
`; + + /* ИНТЕРАКТИВ 2 — Калькулятор типа треугольника */ + html+=`
+
ИНТЕРАКТИВ 2
Калькулятор типа треугольника
+
Введи три стороны — узнай тип треугольника и проверку по обратной теореме Пифагора.
+
+ + + + +
+
+
`; + + /* ИНТЕРАКТИВ 3 — Тренажёр-проверка */ + html+=`
+
ИНТЕРАКТИВ 3
Тренажёр: прямоугольный или нет?
+
Для каждого набора сторон ответь: прямоугольный ли треугольник?
+
+
+ + +
+ +
`; + + /* ИНТЕРАКТИВ 4 — DnD сортер */ + html+=`
+
ИНТЕРАКТИВ 4
Сортировщик: прямоугольный / не прямоугольный
+
Перетащи каждый набор сторон в правильную колонку.
+
+
+
Прямоугольный
+
+
+
+
Не прямоугольный
+
+
+
+
+
+ + +
+ +
`; + + /* ИНТЕРАКТИВ 5 — Тренажёр */ + html+=`
+
ИНТЕРАКТИВ 5
Тренажёр §14
+
5 задач на обратную теорему Пифагора.
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* ИНТЕРАКТИВ 6 — Босс §14 */ + html+=`
+
БОСС §14
Итоговые задачи
+
4 задачи — +5 XP каждая.
+
+
`; + + html+=`
+ +
`; + html+=secNav('p13','p15'); + box.innerHTML=html; + if(window.renderMathInElement) setTimeout(()=>renderMath(box),0); + + /* == INIT: 3 слайдера == */ + (function(){ + const slA=document.getElementById('p14-sl-a'); + const slB=document.getElementById('p14-sl-b'); + const slC=document.getElementById('p14-sl-c'); + const W=320, H=240; + function triType(a,b,c){ + const sides=[a,b,c].sort((x,y)=>x-y); + const [s1,s2,s3]=sides; + if(s1+s2<=s3) return null; // не треугольник + const lhs=s3*s3, rhs=s1*s1+s2*s2; + if(Math.abs(lhs-rhs)<0.01) return 'right'; + if(lhsx-y); + // angle A opposite side a (smallest): + const cosC=(a*a+b*b-c*c)/(2*a*b); + const sinC=Math.sqrt(Math.max(0,1-cosC*cosC)); + const scale=Math.min(10,140/c); + const bx=a*scale; + const cx2=b*scale*cosC, cy2=b*scale*sinC; + const ox=(W-bx)/2, oy=H-40; + const P1={x:ox,y:oy}, P2={x:ox+bx,y:oy}, P3={x:ox+cx2,y:oy-cy2}; + let s=''; + s+=''; + s+='A'; + s+='B'; + s+='C'; + s+='c='+c+''; + s+='b='+b+''; + s+='a='+a+''; + s+=''; + return s; + } + function update(){ + const a=+slA.value, b=+slB.value, c=+slC.value; + document.getElementById('p14-sl-a-val').textContent=a; + document.getElementById('p14-sl-b-val').textContent=b; + document.getElementById('p14-sl-c-val').textContent=c; + const sides=[a,b,c].sort((x,y)=>x-y); + const [s1,s2,s3]=sides; + const info=document.getElementById('p14-sl-info'); + if(s1+s2<=s3){ + document.getElementById('p14-sl-svg-wrap').innerHTML=''; + info.style.background='var(--fail-bg)'; info.style.color='#7f1d1d'; + info.textContent='Треугольника не существует ('+s1+'+'+s2+'≤'+s3+')'; + return; + } + document.getElementById('p14-sl-svg-wrap').innerHTML=drawTriSVG(a,b,c); + const lhs=s3*s3, rhs=s1*s1+s2*s2; + const type=triType(a,b,c); + const labels={right:'Прямоугольный',acute:'Остроугольный',obtuse:'Тупоугольный'}; + const colors={right:'#dcfce7',acute:'#dbeafe',obtuse:'#fef3c7'}; + const textColors={right:'#15803d',acute:'#1d4ed8',obtuse:'#92400e'}; + info.style.background=colors[type]; + info.style.color=textColors[type]; + info.innerHTML=labels[type]+'  |  '+s3+'²='+lhs+'  '+ + (lhs===rhs?'=':lhs{ + const a=parseFloat(document.getElementById('p14-ca').value); + const b=parseFloat(document.getElementById('p14-cb').value); + const c=parseFloat(document.getElementById('p14-cc').value); + const out=document.getElementById('p14-calc-out'); + if(!isFinite(a)||!isFinite(b)||!isFinite(c)||a<=0||b<=0||c<=0){ + out.innerHTML='Введи три положительных числа.';return; + } + const sides=[a,b,c].sort((x,y)=>x-y); + const [s1,s2,s3]=sides; + if(s1+s2<=s3){out.innerHTML='Треугольника с такими сторонами не существует.';return;} + const lhs=s3*s3, rhs=s1*s1+s2*s2; + let type, color, verdict; + if(Math.abs(lhs-rhs)<0.001){type='прямоугольный';color='#15803d';verdict='='} + else if(lhs$c_0^2 = '+fmt(lhs)+'$,   $'+fmt(s1)+'^2+'+fmt(s2)+'^2 = '+fmt(rhs)+'$.
$'+fmt(lhs)+' '+verdict+' '+fmt(rhs)+'$  ⟹  '+type.charAt(0).toUpperCase()+type.slice(1)+' треугольник.'; + renderMath(out); addXp(2,'p14-calc'); + }); + })(); + + /* == INIT: Тренажёр-проверка == */ + (function(){ + const sets=[ + {sides:[3,4,5],right:true},{sides:[6,8,10],right:true},{sides:[5,12,13],right:true}, + {sides:[7,24,25],right:true},{sides:[2,3,4],right:false},{sides:[5,6,7],right:false}, + {sides:[1,1,1],right:false},{sides:[8,15,17],right:true}, + ]; + const cont=document.getElementById('p14-check-items'); + cont.innerHTML=sets.map((s,i)=>` +
+ (${s.sides.join(', ')}) + + + +
`).join(''); + document.getElementById('p14-check-verify').addEventListener('click',()=>{ + let ok=0, total=0; + sets.forEach((s,i)=>{ + const yes=document.getElementById('p14-ck-'+i+'-yes'); + const no=document.getElementById('p14-ck-'+i+'-no'); + const res=document.getElementById('p14-ck-res'+i); + if(!yes.checked&&!no.checked){res.textContent='';return;} + total++; + const chosen=yes.checked?true:false; + if(chosen===s.right){res.textContent='Верно!';res.style.color='#15803d';ok++;} + else{ + const ss=s.sides.sort((a,b)=>a-b); + res.textContent='Неверно ('+ss[2]+'²='+(ss[2]*ss[2])+', '+ss[0]+'²+'+ss[1]+'²='+(ss[0]*ss[0]+ss[1]*ss[1])+')'; + res.style.color='#dc2626'; + } + }); + const fb=document.getElementById('p14-check-fb'); + fb.style.display='block'; + if(ok===sets.length){feedback(fb,true,'Все верно! +5 XP');addXp(5,'p14-check');bumpProgress('p14',10);confetti();} + else{feedback(fb,false,'Верно: '+ok+' из '+total+'.');} + }); + document.getElementById('p14-check-reset').addEventListener('click',()=>{ + sets.forEach((_,i)=>{ + document.getElementById('p14-ck-'+i+'-yes').checked=false; + document.getElementById('p14-ck-'+i+'-no').checked=false; + document.getElementById('p14-ck-res'+i).textContent=''; + }); + document.getElementById('p14-check-fb').style.display='none'; + }); + })(); + + /* == INIT: DnD == */ + (function(){ + const items=[ + {id:'d1',html:'9, 40, 41',cat:'yes'}, + {id:'d2',html:'5, 12, 13',cat:'yes'}, + {id:'d3',html:'8, 15, 17',cat:'yes'}, + {id:'d4',html:'3, 4, 6', cat:'no'}, + {id:'d5',html:'6, 7, 8', cat:'no'}, + {id:'d6',html:'20, 21, 29',cat:'yes'}, + {id:'d7',html:'2, 2, 3', cat:'no'}, + {id:'d8',html:'10, 24, 26',cat:'yes'}, + ]; + const sorter=setupSorter({poolId:'p14-dnd-pool',scopeSelector:'#p14-dnd-wg',items:items.map(x=>({id:x.id,html:x.html})),cats:['yes','no']}); + document.getElementById('p14-dnd-check').addEventListener('click',()=>{ + const fb=document.getElementById('p14-dnd-fb');fb.style.display='block'; + let ok=0; + items.forEach(it=>{if(sorter.placed[it.id]===it.cat)ok++;}); + if(ok===items.length){feedback(fb,true,'Все верно! +5 XP');addXp(5,'p14-dnd');bumpProgress('p14',10);confetti();} + else{feedback(fb,false,'Верно: '+ok+' из '+items.length+'. Проверь: 9-40-41, 5-12-13, 8-15-17, 20-21-29, 10-24-26 — прямоугольные.');} + }); + document.getElementById('p14-dnd-reset').addEventListener('click',()=>{sorter.reset();document.getElementById('p14-dnd-fb').style.display='none';}); + })(); + + /* == INIT: Тренажёр == */ + (function(){ + const tasks=[ + {q:'Стороны треугольника $6, 8, 10$. Прямоугольный? Введи 1 (да) или 0 (нет).', ans:1, tol:0.1, hint:'6²+8²=100=10². Да, прямоугольный (1).'}, + {q:'Стороны $5, 7, 9$. Прямоугольный? Введи 1 (да) или 0 (нет).', ans:0, tol:0.1, hint:'9²=81 > 5²+7²=74. Тупоугольный (0).'}, + {q:'Катеты прямоугольного треугольника $15$ и $20$. Найти гипотенузу.', ans:25, tol:0.5, hint:'c=√(225+400)=√625=25.'}, + {q:'Стороны треугольника $7, 24, c$. При каком $c$ он прямоугольный (угол напротив $c$)?', ans:25, tol:0.5, hint:'c=√(49+576)=√625=25.'}, + {q:'Стороны $3, 4, 5$ умножили на $3$. Получилась тройка $9, 12, 15$. Это прямоугольный треугольник? Введи 1 (да) или 0 (нет).', ans:1, tol:0.1, hint:'9²+12²=81+144=225=15². Да (1).'}, + ]; + let idx=0, score=0; + function show(){ + document.getElementById('p14-tr-i').textContent=idx+1; + document.getElementById('p14-tr-task').innerHTML=tasks[idx].q; + document.getElementById('p14-tr-ans').value=''; + document.getElementById('p14-tr-fb').style.display='none'; + if(window.renderMathInElement) renderMath(document.getElementById('p14-tr-task')); + } + document.getElementById('p14-tr-start').addEventListener('click',()=>{idx=0;score=0;document.getElementById('p14-tr-score').textContent=0;show();}); + document.getElementById('p14-tr-go').addEventListener('click',()=>{ + if(idx>=tasks.length)return; + const ans=+document.getElementById('p14-tr-ans').value; + const fb=document.getElementById('p14-tr-fb'); + fb.style.display='block'; + const tol=tasks[idx].tol||0.5; + if(Math.abs(ans-tasks[idx].ans)show(),900);} + else{feedback(fb,true,'Все задачи решены! +5 XP');addXp(5,'p14-tr-all');bumpProgress('p14',10);} + }else{feedback(fb,false,'Неверно. '+tasks[idx].hint);} + }); + document.getElementById('p14-tr-ans').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p14-tr-go').click();}); + show(); + })(); + + /* == INIT: Босс §14 == */ + (function(){ + const tasks=[ + {q:'Треугольник со сторонами $9$, $40$, $41$. Прямоугольный? Введи 1 (да) или 0 (нет).', ans:1, hint:'9²+40²=81+1600=1681=41². Да.'}, + {q:'Прямоугольный треугольник, гипотенуза $c = 26$, катет $a = 10$. Найти второй катет $b$.', ans:24, hint:'b=√(676-100)=√576=24.'}, + {q:'Стороны $a$ и $b$ прямоугольного треугольника равны $a = b = 5$. Найти гипотенузу (округли до целых).', ans:7, hint:'c=5√2≈7,07≈7.'}, + {q:'Стороны $p$, $q$, $r$ таковы, что $p^2 + q^2 = r^2$. Угол напротив какой стороны прямой? Введи номер стороны: 1=$p$, 2=$q$, 3=$r$.', ans:3, hint:'По обратной теореме Пифагора — прямой угол напротив r (3).'}, + ]; + const bossBox=document.getElementById('p14-boss-tasks'); + bossBox.innerHTML=tasks.map((t,i)=>` +
+
${t.q}
+
+ + + +
+
`).join(''); + if(window.renderMathInElement) renderMath(bossBox); + })(); +} +function buildP15(){ + const box=document.getElementById('p15-body'); + let html=''; + + html+=makeCard('theory','Пифагоровы тройки','15.1',` +

Пифагорова тройка — три натуральных числа $(a, b, c)$, удовлетворяющих $a^2 + b^2 = c^2$.

+

Примитивные тройки (НОД = 1):

+ + + + + + + + +
abcПроверка
3459+16=25
5121325+144=169
7242549+576=625
8151764+225=289
9404181+1600=1681
202129400+441=841
+

Кратные тройки: если $(a,b,c)$ — тройка, то $(ka, kb, kc)$ тоже тройка для любого натурального $k$.

`); + + html+=makeCard('rule','Формула Евклида','15.2',` +

Для любых натуральных $m > n$ тройка $$(m^2-n^2,\\; 2mn,\\; m^2+n^2)$$ является пифагоровой.

+

Проверка: $(m^2-n^2)^2 + (2mn)^2 = m^4 - 2m^2n^2 + n^4 + 4m^2n^2 = m^4 + 2m^2n^2 + n^4 = (m^2+n^2)^2$. $\\square$

+ + + + + + + +
mn$m^2-n^2$$2mn$$m^2+n^2$
21345
3251213
4115817
4372425
52212029
`); + + html+=makeCard('example','Применение','15.3',` +

Пример 1. Два катета прямоугольного треугольника равны $9$ и $40$. Гипотенуза?

+

Узнаём тройку $(9, 40, 41)$ $\\Rightarrow$ $c = 41$. Без вычислений!

+

Пример 2. Катеты $6$ и $8$. Гипотенуза?

+

$(6,8,10) = 2\\cdot(3,4,5)$ $\\Rightarrow$ $c = 10$.

+

Пример 3. По формуле Евклида при $m=5, n=1$: $(24, 10, 26) = 2\\cdot(12, 5, 13)$.

`); + + /* ИНТЕРАКТИВ 1 — Генератор Евклида */ + html+=`
+
ИНТЕРАКТИВ 1
Генератор троек по формуле Евклида
+
Выбери $m$ и $n$ ($m > n$) — получи пифагорову тройку и увидь её на SVG.
+
+ + +
+
+
+
`; + + /* ИНТЕРАКТИВ 2 — Таблица с мини-SVG */ + html+=`
+
ИНТЕРАКТИВ 2
10 известных троек Пифагора
+
Нажми на тройку — увидишь соответствующий прямоугольный треугольник.
+
+
+
`; + + /* ИНТЕРАКТИВ 3 — Тренажёр: найди третье число */ + html+=`
+
ИНТЕРАКТИВ 3
Тренажёр: найди недостающий элемент тройки
+
Дано 2 числа из пифагоровой тройки — найди третье.
+
Задача 1 / 6Очки: 0
+
+
+ + + +
+ +
`; + + /* ИНТЕРАКТИВ 4 — Викторина тройка/не тройка */ + html+=`
+
ИНТЕРАКТИВ 4
Викторина: тройка или не тройка?
+
Для каждого набора нажми «Тройка» или «Нет».
+
+
+ + +
+ +
`; + + /* ИНТЕРАКТИВ 5 — DnD: примитивные vs кратные */ + html+=`
+
ИНТЕРАКТИВ 5
Сортировщик: примитивные vs кратные тройки
+
Перетащи каждую тройку в правильную колонку.
+
+
+
Примитивная (НОД=1)
+
+
+
+
Кратная (НОД>1)
+
+
+
+
+
+ + +
+ +
`; + + /* ИНТЕРАКТИВ 6 — Босс §15 */ + html+=`
+
БОСС §15
Итоговые задачи
+
5 задач — +5 XP каждая.
+
+
`; + + html+=`
+ +
`; + html+=secNav('p14','final2'); + box.innerHTML=html; + if(window.renderMathInElement) setTimeout(()=>renderMath(box),0); + + /* == INIT: Генератор Евклида == */ + (function(){ + const slM=document.getElementById('p15-sl-m'); + const slN=document.getElementById('p15-sl-n'); + const W=300, H=240; + function drawTriangle(a,b,c){ + const mx=Math.max(a,b,c); + const sc=Math.min(10,180/mx); + const ax=a*sc, by=b*sc; + const ox=(W-ax)/2, oy=H-30; + let s=''; + s+=''; + const rm=9; + s+=''; + s+='B'; + s+='C'; + s+='A'; + s+=''+a+''; + s+=''+b+''; + const hpx=(ox+ax+ox)/2, hpy=(oy+oy-by)/2; + s+=''+c+''; + s+=''; + return s; + } + function update(){ + let m=+slM.value, n=+slN.value; + document.getElementById('p15-sl-m-val').textContent=m; + document.getElementById('p15-sl-n-val').textContent=n; + if(n>=m){ + n=m-1; + slN.value=n; + document.getElementById('p15-sl-n-val').textContent=n; + } + const a=m*m-n*n, b=2*m*n, c=m*m+n*n; + document.getElementById('p15-euclid-svg-wrap').innerHTML=drawTriangle(a,b,c); + document.getElementById('p15-euclid-out').innerHTML= + 'm='+m+', n='+n+'
'+ + '$a = m^2-n^2 = '+m*m+'-'+n*n+' = '+a+'$
'+ + '$b = 2mn = 2\\cdot'+m+'\\cdot'+n+' = '+b+'$
'+ + '$c = m^2+n^2 = '+m*m+'+'+n*n+' = '+c+'$
'+ + 'Тройка: ('+a+', '+b+', '+c+')
'+ + 'Проверка: $'+a+'{}^2+'+b+'{}^2 = '+(a*a+b*b)+' = '+c+'{}^2$ = '+(a*a+b*b===c*c?'✓':'✗'); + if(window.renderMathInElement) renderMath(document.getElementById('p15-euclid-out')); + addXp(1,'p15-euclid'); + } + slM.addEventListener('input',update); + slN.addEventListener('input',update); + update(); + })(); + + /* == INIT: Таблица троек == */ + (function(){ + const triples=[ + [3,4,5],[5,12,13],[7,24,25],[8,15,17],[9,40,41], + [6,8,10],[10,24,26],[12,16,20],[15,20,25],[20,21,29], + ]; + const wrap=document.getElementById('p15-table-wrap'); + const svgBox=document.getElementById('p15-table-svg'); + let sel=-1; + function drawMini(a,b,c,active){ + const sc=Math.min(5.5,40/Math.max(a,b,c)); + const ax=a*sc, by=b*sc; + const ox=10, oy=50+by; + let s=''; + s+=''; + s+=''; + s+=''; + return s; + } + function showSVG(i){ + const [a,b,c]=triples[i]; + const sc=Math.min(8,160/Math.max(a,b,c)); + const ax=a*sc, by=b*sc; + const W=Math.round(ax+80), H=Math.round(by+60); + const ox=40, oy=H-30; + let s=''; + s+=''; + const rm=9; + s+=''; + s+='B'; + s+='C'; + s+='A'; + s+='a='+a+''; + s+='b='+b+''; + const hpx=(ox+ax+ox)/2+16, hpy=(oy+oy-by)/2; + s+='c='+c+''; + s+=''+a+'²+'+b+'²='+c+'²   ('+a*a+'+'+b*b+'='+c*c+')'; + s+=''; + svgBox.innerHTML=s; + } + wrap.innerHTML=triples.map(([a,b,c],i)=>` +
+
(${a}, ${b}, ${c})
+ ${drawMini(a,b,c,false)} +
`).join(''); + triples.forEach((_,i)=>{ + document.getElementById('p15-tri-btn'+i).addEventListener('click',()=>{ + sel=i; + triples.forEach((_,j)=>{ + const el=document.getElementById('p15-tri-btn'+j); + el.style.borderColor=j===i?'var(--sec-acc,var(--pri))':'var(--border)'; + }); + showSVG(i); addXp(1,'p15-table-'+i); + }); + }); + showSVG(0); + document.getElementById('p15-tri-btn0').style.borderColor='var(--sec-acc,var(--pri))'; + })(); + + /* == INIT: Тренажёр == */ + (function(){ + const tasks=[ + {q:'Тройка $(3, 4, ?)$. Найти третье число.', ans:5, hint:'3²+4²=25=5².'}, + {q:'Тройка $(5, 12, ?)$. Найти третье число.', ans:13, hint:'25+144=169=13².'}, + {q:'Тройка $(?, 24, 25)$. Найти первое число.', ans:7, hint:'25²-24²=625-576=49=7².'}, + {q:'Тройка $(9, ?, 41)$. Найти второе число.', ans:40, hint:'41²-9²=1681-81=1600=40².'}, + {q:'Кратная тройка: $(6, 8, ?)$. Это $2\\cdot(3,4,5)$.', ans:10, hint:'c=2·5=10.'}, + {q:'Формула Евклида, $m=4, n=1$: $a=m^2-n^2$, $b=2mn$, $c=m^2+n^2$. Найти $c$.', ans:17, hint:'c=16+1=17.'}, + ]; + let idx=0, score=0; + function show(){ + document.getElementById('p15-tr-i').textContent=idx+1; + document.getElementById('p15-tr-task').innerHTML=tasks[idx].q; + document.getElementById('p15-tr-ans').value=''; + document.getElementById('p15-tr-fb').style.display='none'; + if(window.renderMathInElement) renderMath(document.getElementById('p15-tr-task')); + } + document.getElementById('p15-tr-start').addEventListener('click',()=>{idx=0;score=0;document.getElementById('p15-tr-score').textContent=0;show();}); + document.getElementById('p15-tr-go').addEventListener('click',()=>{ + if(idx>=tasks.length)return; + const ans=+document.getElementById('p15-tr-ans').value; + const fb=document.getElementById('p15-tr-fb'); + fb.style.display='block'; + if(Math.abs(ans-tasks[idx].ans)<0.5){ + score++;document.getElementById('p15-tr-score').textContent=score; + addXp(3,'p15-tr-'+idx);bumpProgress('p15',5); + if(idxshow(),900);} + else{feedback(fb,true,'Все задачи решены! +5 XP');addXp(5,'p15-tr-all');bumpProgress('p15',10);} + }else{feedback(fb,false,'Неверно. '+tasks[idx].hint);} + }); + document.getElementById('p15-tr-ans').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p15-tr-go').click();}); + show(); + })(); + + /* == INIT: Викторина == */ + (function(){ + const sets=[ + {nums:[3,4,5],ok:true},{nums:[5,12,13],ok:true},{nums:[6,8,10],ok:true}, + {nums:[7,24,25],ok:true},{nums:[2,3,4],ok:false},{nums:[4,5,6],ok:false}, + {nums:[8,15,17],ok:true},{nums:[3,5,7],ok:false}, + ]; + const cont=document.getElementById('p15-quiz-items'); + cont.innerHTML=sets.map((s,i)=>` +
+ (${s.nums.join(', ')}) + + + +
`).join(''); + document.getElementById('p15-quiz-check').addEventListener('click',()=>{ + let ok=0,total=0; + sets.forEach((s,i)=>{ + const yesEl=cont.querySelector('[name="p15-qz-'+i+'"][value="yes"]'); + const noEl=cont.querySelector('[name="p15-qz-'+i+'"][value="no"]'); + const res=document.getElementById('p15-qz-res'+i); + if(!yesEl.checked&&!noEl.checked){res.textContent='';return;} + total++; + const chosen=yesEl.checked; + if(chosen===s.ok){res.textContent='Верно!';res.style.color='#15803d';ok++;} + else{ + const ss=s.nums.slice().sort((a,b)=>a-b); + res.textContent='Нет: '+ss[0]+'²+'+ss[1]+'²='+(ss[0]*ss[0]+ss[1]*ss[1])+', '+ss[2]+'²='+(ss[2]*ss[2]); + res.style.color='#dc2626'; + } + }); + const fb=document.getElementById('p15-quiz-fb'); + fb.style.display='block'; + if(ok===sets.length){feedback(fb,true,'Все верно! +5 XP');addXp(5,'p15-quiz');bumpProgress('p15',10);confetti();} + else{feedback(fb,false,'Верно: '+ok+' из '+total+'.');} + }); + document.getElementById('p15-quiz-reset').addEventListener('click',()=>{ + sets.forEach((_,i)=>{ + cont.querySelectorAll('[name="p15-qz-'+i+'"]').forEach(r=>r.checked=false); + document.getElementById('p15-qz-res'+i).textContent=''; + }); + document.getElementById('p15-quiz-fb').style.display='none'; + }); + })(); + + /* == INIT: DnD примитивные vs кратные == */ + (function(){ + const items=[ + {id:'e1',html:'(3, 4, 5)',cat:'prim'}, + {id:'e2',html:'(5, 12, 13)',cat:'prim'}, + {id:'e3',html:'(7, 24, 25)',cat:'prim'}, + {id:'e4',html:'(6, 8, 10)',cat:'mult'}, + {id:'e5',html:'(9, 12, 15)',cat:'mult'}, + {id:'e6',html:'(8, 15, 17)',cat:'prim'}, + {id:'e7',html:'(10, 24, 26)',cat:'mult'}, + {id:'e8',html:'(20, 21, 29)',cat:'prim'}, + ]; + const sorter=setupSorter({poolId:'p15-dnd-pool',scopeSelector:'#p15-dnd-wg',items:items.map(x=>({id:x.id,html:x.html})),cats:['prim','mult']}); + document.getElementById('p15-dnd-check').addEventListener('click',()=>{ + const fb=document.getElementById('p15-dnd-fb');fb.style.display='block'; + let ok=0; + items.forEach(it=>{if(sorter.placed[it.id]===it.cat)ok++;}); + if(ok===items.length){feedback(fb,true,'Всё верно! +5 XP');addXp(5,'p15-dnd');bumpProgress('p15',10);confetti();} + else{feedback(fb,false,'Верно: '+ok+' из '+items.length+'. Примитивные: (3,4,5),(5,12,13),(7,24,25),(8,15,17),(20,21,29).');} + }); + document.getElementById('p15-dnd-reset').addEventListener('click',()=>{sorter.reset();document.getElementById('p15-dnd-fb').style.display='none';}); + })(); + + /* == INIT: Босс §15 == */ + (function(){ + const tasks=[ + {q:'Катеты прямоугольного треугольника $20$ и $21$ см. Гипотенуза (используй тройки)?', ans:29, hint:'(20,21,29) — пифагорова тройка. c=29.'}, + {q:'Формула Евклида: $m=5, n=2$. Найти $c = m^2+n^2$.', ans:29, hint:'c=25+4=29.'}, + {q:'Кратная тройка $(15, 20, 25)$ получена умножением $(3,4,5)$ на $k$. Найти $k$.', ans:5, hint:'15/3=5.'}, + {q:'Стороны прямоугольного треугольника — тройка $(a,b,c)$, $c=65$, $a=25$. Найти $b$.', ans:60, hint:'b=√(65²-25²)=√(4225-625)=√3600=60.'}, + {q:'Периметр прямоугольного треугольника равен $60$. Это тройка, кратная $(3,4,5)$. Найти гипотенузу.', ans:25, hint:'k·(3+4+5)=60 → k=5. c=5·5=25.'}, + ]; + const bossBox=document.getElementById('p15-boss-tasks'); + bossBox.innerHTML=tasks.map((t,i)=>` +
+
${t.q}
+
+ + + +
+
`).join(''); + if(window.renderMathInElement) renderMath(bossBox); + })(); +} function buildFinal2stub(){ document.getElementById('final2-body').innerHTML='

Финал главы 2 — Волна 1: боссы и итоги появятся в следующем обновлении.

'+secNav('p15',null); }