feat(geom8): Wave 4 Главы 1 — финал главы (шпаргалка, карта связей, 7 боссов)
Часть 1: 9 mini-cards с формулами всех 16 параграфов (KaTeX). Часть 2: интерактивная SVG-карта иерархии четырёхугольников (клик по узлу — подсветка свойств). Часть 3: 7 интегрированных боссов (по 10 XP): - Босс 1: многоугольник из суммы углов 1620° - Босс 2: параллелограмм через треугольник ABD - Босс 3: средние линии прямоугольника → ромб - Босс 4: ромб 60° → диагонали (Пифагор) - Босс 5: теорема Фалеса, 3 подзадачи - Босс 6: треугольник 12-16-20 — средняя линия + медиана + центроид - Босс 7: равнобедренная трапеция 20/8/10 Часть 4: при победе над всеми — achievement 'Мастер многоугольников Главы 1', +50 XP бонус, confetti, кнопка перехода к Главе 2. File: 5194 → 5558 LOC. Глава 1 полностью наполнена. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -495,7 +495,7 @@ const BUILDERS = {
|
||||
p5:()=>buildP5(), p6:()=>buildP6(), p7:()=>buildP7(), p8:()=>buildP8(),
|
||||
p9:()=>buildP9(), p10:()=>buildP10(), p11:()=>buildP11(), p12:()=>buildP12(),
|
||||
p13:()=>buildP13(), p14:()=>buildP14(), p15:()=>buildP15(), p16:()=>buildP16(),
|
||||
final1:()=>buildFinal1stub(),
|
||||
final1:()=>buildFinal1(),
|
||||
};
|
||||
function ensureBuilt(id){ if(BUILT.has(id)) return; const fn = BUILDERS[id]; if(fn){ fn(); BUILT.add(id); } }
|
||||
function goTo(id){
|
||||
@@ -5188,7 +5188,371 @@ function buildP16(){
|
||||
})();
|
||||
renderMath(box);
|
||||
}
|
||||
function buildFinal1stub(){ document.getElementById('final1-body').innerHTML = '<div class="card"><div class="card-body"><p><b>Финал главы 1 — Волна 1</b>: боссы и итоги появятся в следующем обновлении.</p></div></div>' + secNav('p16',null); }
|
||||
/* ============================================================
|
||||
ФИНАЛ ГЛАВЫ 1 — Итоги · 7 боссов · Достижение
|
||||
============================================================ */
|
||||
function buildFinal1(){
|
||||
const box = document.getElementById('final1-body');
|
||||
let html = '';
|
||||
|
||||
/* === ЧАСТЬ 1: Итоговая шпаргалка === */
|
||||
html += `<div class="card" style="border-color:var(--sec-acc,var(--pri));background:linear-gradient(135deg,var(--card),var(--sec-acc-soft,var(--pri-soft)))">
|
||||
<div class="card-header">
|
||||
<div class="card-icon theory">
|
||||
<svg class="ic" viewBox="0 0 24 24"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>
|
||||
</div>
|
||||
<div class="card-title">Итоговая шпаргалка · Вся Глава 1</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:10px">
|
||||
|
||||
<div style="background:var(--card);border:1.5px solid var(--border);border-radius:11px;padding:12px">
|
||||
<div style="font-family:'Unbounded',sans-serif;font-size:.7rem;font-weight:800;color:var(--pri2);text-transform:uppercase;letter-spacing:.07em;margin-bottom:7px">§1–3 Многоугольники</div>
|
||||
<p style="font-size:.88rem;margin-bottom:5px">Диагонали: $D = \\dfrac{n(n-3)}{2}$</p>
|
||||
<p style="font-size:.88rem;margin-bottom:5px">Сумма углов: $(n-2)\\cdot180°$</p>
|
||||
<p style="font-size:.88rem;margin-bottom:0">Сумма внешних: $360°$ (всегда)</p>
|
||||
<p style="font-size:.78rem;color:var(--muted);margin-top:5px">Пример: шестиугольник — 9 диагоналей, $720°$ внутренних</p>
|
||||
</div>
|
||||
|
||||
<div style="background:var(--card);border:1.5px solid var(--border);border-radius:11px;padding:12px">
|
||||
<div style="font-family:'Unbounded',sans-serif;font-size:.7rem;font-weight:800;color:var(--pri2);text-transform:uppercase;letter-spacing:.07em;margin-bottom:7px">§4–6 Параллелограмм</div>
|
||||
<p style="font-size:.86rem;margin-bottom:4px"><b>Свойства:</b> противоположные стороны равны; противоположные углы равны; смежные углы в сумме $180°$; диагонали делятся пополам</p>
|
||||
<p style="font-size:.86rem;margin-bottom:0"><b>Признаки:</b> 2 пары равных сторон; 1 пара параллельных и равных; диагонали делятся пополам</p>
|
||||
</div>
|
||||
|
||||
<div style="background:var(--card);border:1.5px solid var(--border);border-radius:11px;padding:12px">
|
||||
<div style="font-family:'Unbounded',sans-serif;font-size:.7rem;font-weight:800;color:var(--pri2);text-transform:uppercase;letter-spacing:.07em;margin-bottom:7px">§7–8 Прямоугольник</div>
|
||||
<p style="font-size:.88rem;margin-bottom:5px">Все углы $= 90°$</p>
|
||||
<p style="font-size:.88rem;margin-bottom:5px">Диагонали равны: $AC = BD$</p>
|
||||
<p style="font-size:.88rem;margin-bottom:0">$d = \\sqrt{a^2 + b^2}$</p>
|
||||
<p style="font-size:.78rem;color:var(--muted);margin-top:5px">Признак: параллелограмм с равными диагоналями</p>
|
||||
</div>
|
||||
|
||||
<div style="background:var(--card);border:1.5px solid var(--border);border-radius:11px;padding:12px">
|
||||
<div style="font-family:'Unbounded',sans-serif;font-size:.7rem;font-weight:800;color:var(--pri2);text-transform:uppercase;letter-spacing:.07em;margin-bottom:7px">§9 Ромб</div>
|
||||
<p style="font-size:.88rem;margin-bottom:5px">Все стороны равны</p>
|
||||
<p style="font-size:.88rem;margin-bottom:5px">Диагонали $\\perp$ и делят углы пополам</p>
|
||||
<p style="font-size:.88rem;margin-bottom:0">$S = \\dfrac{d_1 \\cdot d_2}{2}$</p>
|
||||
<p style="font-size:.78rem;color:var(--muted);margin-top:5px">Пример: ромб со стороной 5 и диагоналями 6, 8 — $S=24$</p>
|
||||
</div>
|
||||
|
||||
<div style="background:var(--card);border:1.5px solid var(--border);border-radius:11px;padding:12px">
|
||||
<div style="font-family:'Unbounded',sans-serif;font-size:.7rem;font-weight:800;color:var(--pri2);text-transform:uppercase;letter-spacing:.07em;margin-bottom:7px">§10 Квадрат</div>
|
||||
<p style="font-size:.88rem;margin-bottom:5px">Прямоугольник + ромб одновременно</p>
|
||||
<p style="font-size:.88rem;margin-bottom:5px">$d = a\\sqrt{2}$</p>
|
||||
<p style="font-size:.88rem;margin-bottom:0">$S = a^2$, $P = 4a$</p>
|
||||
<p style="font-size:.78rem;color:var(--muted);margin-top:5px">Все свойства ромба и прямоугольника вместе</p>
|
||||
</div>
|
||||
|
||||
<div style="background:var(--card);border:1.5px solid var(--border);border-radius:11px;padding:12px">
|
||||
<div style="font-family:'Unbounded',sans-serif;font-size:.7rem;font-weight:800;color:var(--pri2);text-transform:uppercase;letter-spacing:.07em;margin-bottom:7px">§11 Теорема Фалеса</div>
|
||||
<p style="font-size:.88rem;margin-bottom:5px">Параллельные прямые отсекают пропорциональные отрезки</p>
|
||||
<p style="font-size:.88rem;margin-bottom:0">Если $n$ параллельных делят одну прямую на равные части — они делят на равные части и другую прямую</p>
|
||||
</div>
|
||||
|
||||
<div style="background:var(--card);border:1.5px solid var(--border);border-radius:11px;padding:12px">
|
||||
<div style="font-family:'Unbounded',sans-serif;font-size:.7rem;font-weight:800;color:var(--pri2);text-transform:uppercase;letter-spacing:.07em;margin-bottom:7px">§12 Медианы</div>
|
||||
<p style="font-size:.88rem;margin-bottom:5px">3 медианы пересекаются в центроиде $G$</p>
|
||||
<p style="font-size:.88rem;margin-bottom:0">$G$ делит каждую медиану в отношении $2:1$ от вершины</p>
|
||||
<p style="font-size:.78rem;color:var(--muted);margin-top:5px">$BG = \\tfrac{2}{3}m_b$, $GM_b = \\tfrac{1}{3}m_b$</p>
|
||||
</div>
|
||||
|
||||
<div style="background:var(--card);border:1.5px solid var(--border);border-radius:11px;padding:12px">
|
||||
<div style="font-family:'Unbounded',sans-serif;font-size:.7rem;font-weight:800;color:var(--pri2);text-transform:uppercase;letter-spacing:.07em;margin-bottom:7px">§13 Средняя линия Δ</div>
|
||||
<p style="font-size:.88rem;margin-bottom:5px">Соединяет середины двух сторон</p>
|
||||
<p style="font-size:.88rem;margin-bottom:5px">Параллельна третьей стороне</p>
|
||||
<p style="font-size:.88rem;margin-bottom:0">$MN = \\dfrac{1}{2} \\cdot BC$</p>
|
||||
</div>
|
||||
|
||||
<div style="background:var(--card);border:1.5px solid var(--border);border-radius:11px;padding:12px">
|
||||
<div style="font-family:'Unbounded',sans-serif;font-size:.7rem;font-weight:800;color:var(--pri2);text-transform:uppercase;letter-spacing:.07em;margin-bottom:7px">§14–16 Трапеция</div>
|
||||
<p style="font-size:.88rem;margin-bottom:5px">Одна пара параллельных сторон ($a \\parallel b$)</p>
|
||||
<p style="font-size:.88rem;margin-bottom:5px">Средняя линия: $m = \\dfrac{a+b}{2}$</p>
|
||||
<p style="font-size:.88rem;margin-bottom:0">Равнобедренная: углы при основании равны, диагонали равны</p>
|
||||
<p style="font-size:.78rem;color:var(--muted);margin-top:5px">Признаки: равные углы при осн. или равные диагонали</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
/* === ЧАСТЬ 2: Карта связей — иерархия четырёхугольников === */
|
||||
html += `<div class="wg" id="final1-hier-wrap">
|
||||
<div class="wg-header"><span class="wg-badge">КАРТА СВЯЗЕЙ</span><div class="wg-title">Иерархия четырёхугольников</div></div>
|
||||
<div class="wg-help">Нажми на фигуру, чтобы увидеть её ключевые свойства. Стрелки означают «является частным случаем».</div>
|
||||
<div id="final1-hier-svg" style="display:flex;justify-content:center;overflow-x:auto"></div>
|
||||
<div id="final1-hier-info" style="min-height:56px;padding:12px 16px;background:var(--sec-acc-soft,var(--pri-soft));border-radius:10px;margin-top:10px;font-size:.9rem;line-height:1.65;color:var(--text)">Нажми на фигуру в схеме выше</div>
|
||||
</div>`;
|
||||
|
||||
/* === ЧАСТЬ 3: 7 боссов === */
|
||||
html += `<div class="wg" style="border-color:#d97706;background:linear-gradient(135deg,var(--card),#fef9c3)">
|
||||
<div class="wg-header">
|
||||
<span class="wg-badge" style="background:#d97706">7 БОССОВ ГЛАВЫ 1</span>
|
||||
<div class="wg-title">Интегрированные задачи</div>
|
||||
</div>
|
||||
<div class="wg-help">Каждая задача объединяет 2–3 темы главы. +10 XP за каждого побеждённого босса. Победи всех семерых — получишь +50 XP и достижение!</div>
|
||||
<div id="final1-bosses"></div>
|
||||
</div>`;
|
||||
|
||||
/* === ЧАСТЬ 4: Финальная плашка === */
|
||||
html += `<div id="final1-finish" style="display:none;margin-top:20px;padding:24px;background:linear-gradient(135deg,#fef3c7,#d1fae5);border:2px solid var(--ok,#10b981);border-radius:16px;text-align:center">
|
||||
<div style="font-family:'Unbounded',sans-serif;font-size:1.2rem;font-weight:900;color:#065f46;margin-bottom:10px">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:28px;height:28px;vertical-align:middle;margin-right:6px"><polygon points="12,2 15.09,8.26 22,9.27 17,14.14 18.18,21.02 12,17.77 5.82,21.02 7,14.14 2,9.27 8.91,8.26"/></svg>
|
||||
Мастер многоугольников Главы 1!
|
||||
</div>
|
||||
<p style="color:#065f46;font-size:.95rem;margin-bottom:16px">Ты победил всех 7 боссов и освоил всю Главу 1. Это серьёзно!</p>
|
||||
<a href="/textbook/geometry-8-ch2" class="btn primary" style="font-size:.98rem;padding:12px 28px">
|
||||
<svg class="ic" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
|
||||
Перейти к Главе 2
|
||||
</a>
|
||||
</div>`;
|
||||
|
||||
html += `<div style="margin-top:18px;display:flex;justify-content:center">
|
||||
<button class="btn primary" id="final1-read-btn" onclick="addXp(10,'final1-read');bumpProgress('final1',40);this.textContent='Прочитано!';this.disabled=true;">
|
||||
<svg class="ic" viewBox="0 0 24 24"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>
|
||||
Я изучил Главу 1 (+10 XP)
|
||||
</button>
|
||||
</div>`;
|
||||
|
||||
html += secNav('p16', null);
|
||||
box.innerHTML = html;
|
||||
|
||||
/* === JS: Карта связей SVG === */
|
||||
(function(){
|
||||
const W = 680, H = 320;
|
||||
const nodes = [
|
||||
{ id:'quad', x:340, y:30, label:'Четырёхугольник', r:52,
|
||||
props:'4 стороны, 4 угла, сумма углов = 360°. Диагонали — отрезки, соединяющие несмежные вершины.' },
|
||||
{ id:'trap', x:120, y:130, label:'Трапеция', r:42,
|
||||
props:'Одна пара параллельных сторон. Средняя линия = (a+b)/2. Признак равнобедренной: равные углы при основании или равные диагонали.' },
|
||||
{ id:'istrap', x:90, y:250, label:'Равнобедренная трапеция', r:42,
|
||||
props:'Боковые стороны равны. Углы при каждом основании равны. Диагонали равны.' },
|
||||
{ id:'para', x:400, y:130, label:'Параллелограмм', r:48,
|
||||
props:'Две пары параллельных сторон. Противоположные стороны и углы равны. Диагонали делятся пополам.' },
|
||||
{ id:'rect', x:290, y:250, label:'Прямоугольник', r:44,
|
||||
props:'Все углы = 90°. Диагонали равны: AC = BD. d = √(a²+b²). Признак: параллелограмм с равными диагоналями.' },
|
||||
{ id:'rhomb', x:490, y:250, label:'Ромб', r:40,
|
||||
props:'Все стороны равны. Диагонали ⊥ и делят углы пополам. S = d₁·d₂/2.' },
|
||||
{ id:'sq', x:390, y:300, label:'Квадрат', r:38,
|
||||
props:'Прямоугольник и ромб одновременно. d = a√2. S = a². Все свойства ромба и прямоугольника.' },
|
||||
];
|
||||
const edges = [
|
||||
['quad','trap'], ['quad','para'],
|
||||
['trap','istrap'], ['para','rect'], ['para','rhomb'],
|
||||
['rect','sq'], ['rhomb','sq'],
|
||||
];
|
||||
let sel = null;
|
||||
function draw(selId){
|
||||
const colors = { quad:'#d97706', trap:'#f97316', istrap:'#ef4444', para:'#8b5cf6', rect:'#2563eb', rhomb:'#0891b2', sq:'#059669' };
|
||||
let s = `<svg viewBox="0 0 ${W} ${H}" style="width:100%;max-width:700px;background:var(--card);border:1.5px solid var(--border);border-radius:14px;cursor:pointer">`;
|
||||
s += `<defs><marker id="fh-arr" markerWidth="7" markerHeight="7" refX="6" refY="3.5" orient="auto"><polygon points="0 0,7 3.5,0 7" fill="#94a3b8"/></marker></defs>`;
|
||||
edges.forEach(([a,b])=>{
|
||||
const na=nodes.find(n=>n.id===a), nb=nodes.find(n=>n.id===b);
|
||||
const dx=nb.x-na.x, dy=nb.y-na.y, len=Math.sqrt(dx*dx+dy*dy);
|
||||
const sx=na.x+dx/len*na.r, sy=na.y+dy/len*na.r;
|
||||
const ex=nb.x-dx/len*(nb.r+7), ey=nb.y-dy/len*(nb.r+7);
|
||||
const isActive = selId===a||selId===b;
|
||||
s += `<line x1="${sx}" y1="${sy}" x2="${ex}" y2="${ey}" stroke="${isActive?'#d97706':'#94a3b8'}" stroke-width="${isActive?2.5:1.5}" marker-end="url(#fh-arr)"/>`;
|
||||
});
|
||||
nodes.forEach(n=>{
|
||||
const isS = selId===n.id;
|
||||
const col = colors[n.id] || '#d97706';
|
||||
s += `<ellipse cx="${n.x}" cy="${n.y}" rx="${n.r}" ry="${n.r*0.52}" fill="${isS?col:'var(--card)'}" stroke="${col}" stroke-width="${isS?3:2}" data-nid="${n.id}" style="cursor:pointer;transition:all .18s"/>`;
|
||||
const words = n.label.split(' ');
|
||||
const line1 = words.slice(0,2).join(' '), line2 = words.slice(2).join(' ');
|
||||
const textCol = isS ? '#fff' : col;
|
||||
if(line2){
|
||||
s += `<text x="${n.x}" y="${n.y-5}" text-anchor="middle" font-size="9" font-weight="800" font-family="Unbounded,sans-serif" fill="${textCol}" style="pointer-events:none">${line1}</text>`;
|
||||
s += `<text x="${n.x}" y="${n.y+8}" text-anchor="middle" font-size="9" font-weight="800" font-family="Unbounded,sans-serif" fill="${textCol}" style="pointer-events:none">${line2}</text>`;
|
||||
} else {
|
||||
s += `<text x="${n.x}" y="${n.y+4}" text-anchor="middle" font-size="9" font-weight="800" font-family="Unbounded,sans-serif" fill="${textCol}" style="pointer-events:none">${line1}</text>`;
|
||||
}
|
||||
});
|
||||
s += '</svg>';
|
||||
document.getElementById('final1-hier-svg').innerHTML = s;
|
||||
document.getElementById('final1-hier-svg').querySelector('svg').addEventListener('click', function(e){
|
||||
const el = e.target.closest('[data-nid]');
|
||||
if(!el) return;
|
||||
const nid = el.dataset.nid;
|
||||
sel = (sel===nid) ? null : nid;
|
||||
const nd = nodes.find(n=>n.id===nid);
|
||||
if(sel && nd) document.getElementById('final1-hier-info').innerHTML = '<b>' + nd.label + '</b>: ' + nd.props;
|
||||
else document.getElementById('final1-hier-info').textContent = 'Нажми на фигуру в схеме выше';
|
||||
draw(sel);
|
||||
});
|
||||
}
|
||||
draw(null);
|
||||
})();
|
||||
|
||||
/* === JS: 7 боссов === */
|
||||
(function(){
|
||||
const bosses = [
|
||||
{
|
||||
n: 1,
|
||||
title: 'Многоугольники и углы',
|
||||
color: '#d97706',
|
||||
cond: 'В выпуклом многоугольнике сумма внутренних углов равна $1620°$.',
|
||||
parts: [
|
||||
{ label: 'Сколько у него сторон?', ans: 11, hint: '$(n-2)\\cdot180°=1620°$ → $n-2=9$ → $n=11$' },
|
||||
{ label: 'Сколько диагоналей?', ans: 44, hint: '$\\dfrac{11\\cdot(11-3)}{2}=\\dfrac{88}{2}=44$' },
|
||||
{ label: 'Если он правильный, найди один внутренний угол (в градусах).', ans: 147, hint: '$\\dfrac{1620°}{11}\\approx147.27°$ — ответ: 147 (до целых)', tol: 1 },
|
||||
{ label: 'Один внешний угол правильного 11-угольника (в градусах, до целых).', ans: 33, hint: '$\\dfrac{360°}{11}\\approx32.7°$ — ответ: 33', tol: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
n: 2,
|
||||
title: 'Параллелограмм через диагональ',
|
||||
color: '#8b5cf6',
|
||||
cond: 'В параллелограмме $ABCD$ диагональ $BD$ делит его на два треугольника. $\\angle ABD=40°$, $\\angle ADB=65°$.',
|
||||
parts: [
|
||||
{ label: 'Найди угол A параллелограмма (в градусах).', ans: 75, hint: 'В треугольнике ABD: $\\angle A = 180°-40°-65°=75°$' },
|
||||
{ label: 'Найди угол B параллелограмма (в градусах).', ans: 105, hint: 'Смежные углы параллелограмма в сумме $180°$: $\\angle B=180°-75°=105°$' },
|
||||
{ label: 'Найди угол D параллелограмма (в градусах).', ans: 105, hint: 'Противоположные углы параллелограмма равны: $\\angle D=\\angle B=105°$' },
|
||||
],
|
||||
},
|
||||
{
|
||||
n: 3,
|
||||
title: 'Прямоугольник и ромб',
|
||||
color: '#2563eb',
|
||||
cond: 'В прямоугольнике $ABCD$: $AB=6$, $AD=8$. Точки $M, N, K, L$ — середины сторон $AB, BC, CD, DA$ соответственно.',
|
||||
parts: [
|
||||
{ label: 'Найди длину MN (стороны MNKL).', ans: 5, hint: 'По теореме средней линии треугольника: $MN = \\tfrac{1}{2}AC$, $AC=\\sqrt{36+64}=10$, $MN=5$' },
|
||||
{ label: 'Докажи, что MNKL — ромб. Все стороны MNKL равны? (1 — да, 0 — нет)', ans: 1, hint: 'Все стороны = 5 (по теореме средней линии во всех четырёх треугольниках). MNKL — ромб.' },
|
||||
{ label: 'Найди площадь MNKL.', ans: 24, hint: '$S_{MNKL} = \\tfrac{1}{2}S_{ABCD}=\\tfrac{1}{2}\\cdot48=24$' },
|
||||
],
|
||||
},
|
||||
{
|
||||
n: 4,
|
||||
title: 'Ромб и теорема Пифагора',
|
||||
color: '#0891b2',
|
||||
cond: 'В ромбе $ABCD$ сторона $a=10$, угол $\\angle A=60°$.',
|
||||
parts: [
|
||||
{ label: 'Найди длину бо́льшей диагонали (AC, проходит через угол A=60°, единицы).', ans: 10, hint: 'Треугольник ABD при угле 60°: $\\triangle ABD$ равносторонний ($AB=BD=AD=10$). $AC=10$. Диагональ через вершины с углом 60° равна стороне.' },
|
||||
{ label: 'Найди длину меньшей диагонали BD (единицы), используя теорему Пифагора.', ans: 17, hint: '$AO=5$ (полудиагональ AC), $BO=\\sqrt{10^2-5^2}=\\sqrt{75}\\approx8.66$. $BD=2\\cdot8.66\\approx17.32$. Округли до 17.', tol: 1 },
|
||||
{ label: 'Найди площадь ромба (округли до целых).', ans: 87, hint: '$S=\\dfrac{d_1\\cdot d_2}{2}=\\dfrac{10\\cdot17.32}{2}\\approx86.6\\approx87$', tol: 1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
n: 5,
|
||||
title: 'Теорема Фалеса',
|
||||
color: '#16a34a',
|
||||
cond: 'По теореме Фалеса параллельные прямые делят отрезки пропорционально.',
|
||||
parts: [
|
||||
{ label: 'Отрезок AB разделён на 5 равных частей параллельными прямыми, пересекающими отрезок CD (CD ∥ AB, CD=20). Расстояние между соседними точками деления на CD (число).', ans: 4, hint: '5 равных частей делят CD тоже на 5 равных частей по теореме Фалеса: $20/5=4$' },
|
||||
{ label: 'Отрезок AB=15 делится параллельными прямыми на n равных частей, расстояние между точками деления = 3. Найди n.', ans: 5, hint: 'Шаг = $AB/n = 15/n = 3$ → $n=5$' },
|
||||
{ label: 'Три параллельные прямые делят отрезок PQ на части 4, 4, 4 (три равные части). Отрезок RS, параллельный PQ, имеет длину 30. Какова длина каждой части RS?', ans: 10, hint: 'По теореме Фалеса — тоже 3 равные части: $30/3=10$' },
|
||||
],
|
||||
},
|
||||
{
|
||||
n: 6,
|
||||
title: 'Медиана и средняя линия',
|
||||
color: '#e11d48',
|
||||
cond: 'В треугольнике $ABC$: $AB=12$, $BC=16$, $AC=20$. Это прямоугольный треугольник ($\\angle B=90°$).',
|
||||
parts: [
|
||||
{ label: 'M — середина AB, N — середина AC. Найди MN (средняя линия треугольника).', ans: 8, hint: '$MN = \\tfrac{1}{2}BC = \\tfrac{1}{2}\\cdot16 = 8$' },
|
||||
{ label: 'G — центроид. Длина медианы из B к середине AC: $m_b=\\tfrac{1}{2}AC=10$. Найди BG.', ans: 7, hint: '$BG = \\tfrac{2}{3}m_b = \\tfrac{2}{3}\\cdot10 = 6.67 \\approx 7$', tol: 1 },
|
||||
{ label: 'В прямоугольном треугольнике медиана из прямого угла равна половине гипотенузы. Гипотенуза AC=20. Найди медиану из B (m_b).', ans: 10, hint: '$m_b = \\tfrac{1}{2}\\cdot AC = \\tfrac{1}{2}\\cdot20 = 10$' },
|
||||
],
|
||||
},
|
||||
{
|
||||
n: 7,
|
||||
title: 'Трапеция (комплексная)',
|
||||
color: '#f97316',
|
||||
cond: 'В равнобедренной трапеции $ABCD$: $AD \\parallel BC$, $AD=20$, $BC=8$, боковая сторона $AB=10$.',
|
||||
parts: [
|
||||
{ label: 'Найди высоту трапеции h.', ans: 8, hint: 'Проекция основания: $(20-8)/2=6$. $h=\\sqrt{10^2-6^2}=\\sqrt{64}=8$' },
|
||||
{ label: 'Найди среднюю линию трапеции m.', ans: 14, hint: '$m=\\dfrac{20+8}{2}=14$' },
|
||||
{ label: 'Найди длину диагонали AC (округли до целых).', ans: 16, hint: 'Сдвиг горизонтальный = $(20-8)/2=6$. $AC=\\sqrt{(8+6)^2+8^2}=\\sqrt{196+64}=\\sqrt{260}\\approx16$', tol: 1 },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
window.final1BossSolved = new Set();
|
||||
const bossBox = document.getElementById('final1-bosses');
|
||||
bossBox.innerHTML = bosses.map(b => {
|
||||
const partsHtml = b.parts.map((p,pi) => `
|
||||
<div style="padding:10px 0;border-top:1px dashed var(--border)">
|
||||
<div style="font-size:.9rem;margin-bottom:7px">${p.label}</div>
|
||||
<div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap">
|
||||
<input type="number" class="tinp final1-boss-inp" data-b="${b.n-1}" data-p="${pi}" placeholder="Ответ" style="width:110px">
|
||||
<button class="btn primary final1-boss-check" data-b="${b.n-1}" data-p="${pi}" style="background:${b.color};border-color:${b.color}">Проверить</button>
|
||||
<span class="final1-boss-ok" data-b="${b.n-1}" data-p="${pi}" style="display:none;color:var(--ok);font-weight:700">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" style="width:16px;height:16px;vertical-align:middle"><polyline points="20 6 9 17 4 12"/></svg>
|
||||
</span>
|
||||
</div>
|
||||
<div class="feedback final1-boss-fb" data-b="${b.n-1}" data-p="${pi}" style="display:none;margin-top:6px"></div>
|
||||
</div>`).join('');
|
||||
|
||||
return `<div style="padding:16px;background:var(--card);border-radius:12px;border:2px solid ${b.color};margin-bottom:14px" id="final1-boss-card-${b.n-1}">
|
||||
<div style="display:flex;align-items:center;gap:10px;margin-bottom:12px;flex-wrap:wrap">
|
||||
<span style="background:${b.color};color:#fff;padding:4px 10px;border-radius:6px;font-family:'Unbounded',sans-serif;font-size:.7rem;font-weight:800">БОСС ${b.n}</span>
|
||||
<span style="font-family:'Unbounded',sans-serif;font-size:.88rem;font-weight:800;color:${b.color}">${b.title}</span>
|
||||
<span id="final1-boss-xp-${b.n-1}" style="margin-left:auto;display:none;background:var(--ok-bg);color:#065f46;padding:3px 10px;border-radius:99px;font-size:.78rem;font-weight:800">+10 XP</span>
|
||||
</div>
|
||||
<div style="padding:10px 14px;background:linear-gradient(135deg,#fef3c7,#fff);border-left:4px solid ${b.color};border-radius:9px;font-size:.92rem;line-height:1.6;margin-bottom:4px">${b.cond}</div>
|
||||
${partsHtml}
|
||||
</div>`;
|
||||
}).join('');
|
||||
|
||||
/* attach logic */
|
||||
function checkPart(bi, pi){
|
||||
const boss = bosses[bi];
|
||||
const part = boss.parts[pi];
|
||||
const inp = bossBox.querySelector(`.final1-boss-inp[data-b="${bi}"][data-p="${pi}"]`);
|
||||
const fb = bossBox.querySelector(`.final1-boss-fb[data-b="${bi}"][data-p="${pi}"]`);
|
||||
const ok = bossBox.querySelector(`.final1-boss-ok[data-b="${bi}"][data-p="${pi}"]`);
|
||||
if(!inp) return;
|
||||
const val = parseFloat(inp.value);
|
||||
const tol = part.tol !== undefined ? part.tol : 0;
|
||||
if(Math.abs(val - part.ans) <= tol){
|
||||
feedback(fb, true, 'Верно! ' + (part.hint ? '<br><span style="font-size:.82rem;opacity:.85">' + part.hint + '</span>' : ''));
|
||||
inp.disabled = true;
|
||||
const btn = bossBox.querySelector(`.final1-boss-check[data-b="${bi}"][data-p="${pi}"]`);
|
||||
if(btn) btn.disabled = true;
|
||||
if(ok) ok.style.display = 'inline';
|
||||
/* check if all parts of boss solved */
|
||||
const allDone = boss.parts.every((_, pj) => {
|
||||
const el = bossBox.querySelector(`.final1-boss-inp[data-b="${bi}"][data-p="${pj}"]`);
|
||||
return el && el.disabled;
|
||||
});
|
||||
if(allDone && !window.final1BossSolved.has(bi)){
|
||||
window.final1BossSolved.add(bi);
|
||||
addXp(10, 'final1-boss-' + (bi+1));
|
||||
const xpBadge = document.getElementById('final1-boss-xp-' + bi);
|
||||
if(xpBadge) xpBadge.style.display = 'inline';
|
||||
bumpProgress('final1', 8);
|
||||
/* check all bosses done */
|
||||
if(window.final1BossSolved.size === bosses.length){
|
||||
setTimeout(()=>{
|
||||
confetti();
|
||||
if(!STATE.achievements.has('final1-master')){
|
||||
STATE.achievements.set('final1-master', 'Мастер многоугольников Главы 1');
|
||||
saveProgress();
|
||||
const pop = document.getElementById('ach-popup');
|
||||
if(pop){ document.getElementById('ach-text').textContent = 'Мастер многоугольников Главы 1!'; pop.classList.add('show'); setTimeout(()=>pop.classList.remove('show'), 4000); }
|
||||
}
|
||||
addXp(50, 'final1-all-bosses');
|
||||
bumpProgress('final1', 20);
|
||||
const fin = document.getElementById('final1-finish');
|
||||
if(fin) fin.style.display = 'block';
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
feedback(fb, false, 'Неверно. Подсказка: ' + part.hint);
|
||||
}
|
||||
}
|
||||
|
||||
bossBox.querySelectorAll('.final1-boss-check').forEach(btn=>{
|
||||
btn.addEventListener('click', ()=>{ checkPart(+btn.dataset.b, +btn.dataset.p); });
|
||||
});
|
||||
bossBox.querySelectorAll('.final1-boss-inp').forEach(inp=>{
|
||||
inp.addEventListener('keydown', e=>{ if(e.key==='Enter'){ const btn=bossBox.querySelector(`.final1-boss-check[data-b="${inp.dataset.b}"][data-p="${inp.dataset.p}"]`); if(btn)btn.click(); } });
|
||||
});
|
||||
})();
|
||||
|
||||
renderMath(box);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user