diff --git a/frontend/textbooks/physics_8_ch1.html b/frontend/textbooks/physics_8_ch1.html index e53818e..99a9f86 100644 --- a/frontend/textbooks/physics_8_ch1.html +++ b/frontend/textbooks/physics_8_ch1.html @@ -267,7 +267,8 @@ const ACH_LABELS = { p9_done:"Удельная теплота плавления и кристаллизации освоен!", p10_done:"Испарение жидкостей. Факторы, влияющие на скорость испарения освоен!", p11_done:"Кипение жидкостей. Удельная теплота парообразования освоен!", - ch1_done:"Глава 1 пройдена!" + ch1_done:"Глава 1 пройдена!", + thermal_master:"Мастер теплоты — все боссы главы 1 повержены!" }; const SIDEBARS = { @@ -337,9 +338,24 @@ const SIDEBARS = { ["железо","$\\lambda = 2{,}7 \\cdot 10^5$"], ["Баланс","$Q_{нагр} + Q_{пл} + Q_{нагр.ж}$"] ]}, - p10:{title:"Шпаргалка § 10",rows:[["В разработке","Phase 1 Wave 5"]]}, - p11:{title:"Шпаргалка § 11",rows:[["В разработке","Phase 1 Wave 5"]]}, - final1:{title:"Шпаргалка ★",rows:[["В разработке","Phase 1 Wave 5"]]} + p10:{title:"Шпаргалка § 10",rows:[ + ["Испарение","с поверхности при любой $T$"], + ["Скорость зависит от","$T$, $S$, ветра, рода жидкости"], + ["Жидкость","охлаждается (уходят быстрые)"], + ["Конденсация","пар $\\to$ жидкость, тепло выделяется"] + ]}, + p11:{title:"Шпаргалка § 11",rows:[ + ["Кипение","по всему объёму при $T = T_{кип}$"], + ["Формула","$Q = Lm$"], + ["$L$ для воды","$2{,}26 \\cdot 10^6$ Дж/кг"], + ["$T_{кип}$ воды","100 °C (при 1 атм)"], + ["Давление $\\downarrow$","$T_{кип} \\downarrow$ (на горе)"] + ]}, + final1:{title:"Финал главы 1",rows:[ + ["Формулы","$Q = cm\\Delta T$, $Q = qm$, $Q = \\lambda m$, $Q = Lm$"], + ["3 вида теплопередачи","проводность, конвекция, излучение"], + ["Награда","+50 XP + «Мастер теплоты»"] + ]} }; const TIPS=[ @@ -352,9 +368,9 @@ const TIPS=[ {sec:'p7',html:"При сгорании 1 кг топлива выделяется $q$ Дж энергии. Полное выделение: $Q = q m$. У бензина $q$ в 4,5 раза больше, чем у дров, — поэтому литр бензина греет дольше, чем литр дров."}, {sec:'p8',html:"Пока лёд плавится, температура смеси «лёд + вода» сидит на 0 °C — даже если плита продолжает греть. На графике $T(t)$ это видно как горизонтальная площадка (плато)."}, {sec:'p9',html:"Чтобы расплавить 1 кг льда (без нагрева!), нужно $\\lambda = 334$ кДж. Это столько же, сколько на нагрев той же массы воды от 0 до 80 °C. Поэтому лёд — хороший «холодильник»."}, - {sec:'p10',html:"Параграф § 10 будет реализован в Phase 1 Wave 5. Используем хелперы из phys.js и optics.js."}, - {sec:'p11',html:"Параграф § 11 будет реализован в Phase 1 Wave 5. Используем хелперы из phys.js и optics.js."}, - {sec:'final1',html:"Параграф ★ будет реализован в Phase 1 Wave 5. Используем хелперы из phys.js и optics.js."} + {sec:'p10',html:"Лужа высыхает даже зимой — это испарение. Чем теплее и ветренее, тем быстрее. При этом сама жидкость остывает, потому что её покидают самые быстрые молекулы — вот почему мокрая рука зябнет."}, + {sec:'p11',html:"При кипении пузырьки пара образуются внутри жидкости. Чтобы перевести 1 кг воды (100 °C) в пар, нужно $L = 2{,}26 \\cdot 10^6$ Дж — это в 5,4 раза больше, чем на нагрев той же воды от 0 до 100 °C."}, + {sec:'final1',html:"Финал главы — синтез 11 параграфов. 7 интегрированных боссов на формулы $Q = cm\\Delta T$, $\\lambda m$, $Lm$, $qm$, баланс смешивания, КПД, цепные расчёты. За победу — +50 XP и ачивка «Мастер теплоты»."} ]; const BUILDERS = { @@ -367,9 +383,9 @@ const BUILDERS = { p7: ()=>{ build_p7(); }, p8: ()=>{ build_p8(); }, p9: ()=>{ build_p9(); }, - p10: ()=>{ const box=document.getElementById('p10-body'); box.innerHTML = buildStub('p10', 'Испарение жидкостей. Факторы, влияющие на скорость испарения', 'Phase 1 Wave 5') + secNavFor('p10') + readButton('p10'); renderMath(box); wireReadBtn('p10'); }, - p11: ()=>{ const box=document.getElementById('p11-body'); box.innerHTML = buildStub('p11', 'Кипение жидкостей. Удельная теплота парообразования', 'Phase 1 Wave 5') + secNavFor('p11') + readButton('p11'); renderMath(box); wireReadBtn('p11'); }, - final1: ()=>{ const box=document.getElementById('final1-body'); box.innerHTML = buildStub('final1', 'Финал главы', 'Phase 1 Wave 5') + secNavFor('final1') + readButton('final1'); renderMath(box); wireReadBtn('final1'); } + p10: ()=>{ build_p10(); }, + p11: ()=>{ build_p11(); }, + final1: ()=>{ build_final1(); } }; function calcLevel(xp){ return Math.floor(Math.sqrt((xp||0)/100))+1; } @@ -2968,6 +2984,592 @@ function _initP9_tasks(){ render(); } +/* ====================================================================== + PHASE 1 · WAVE 5 — §10, §11, FINAL 1 + ====================================================================== */ + +/* ======== §10 — Испарение жидкостей ======== */ +function build_p10(){ + const box = document.getElementById('p10-body'); + let h = ''; + + h += makeCard('theory', 'Что такое испарение', '§ 10.1', + '

Испарение — переход жидкости в пар с поверхности. Идёт при любой температуре (даже при 0 °C, даже зимой).

' + +'

Механизм: молекулы у поверхности движутся хаотически. Самые быстрые из них преодолевают притяжение остальных и улетают в воздух — становятся паром.

' + +'

Поэтому при испарении жидкость остывает — её покидают наиболее «горячие» молекулы, средняя $E_k$ оставшихся падает.

' + ); + h += makeCard('rule', 'От чего зависит скорость испарения', '§ 10.2', + '
    ' + +'
  1. Температура: чем выше $T$, тем больше быстрых молекул, испарение интенсивнее.
  2. ' + +'
  3. Площадь свободной поверхности: чем больше $S$, тем больше «выходов».
  4. ' + +'
  5. Движение воздуха (ветер): унося пар, ветер не даёт ему вернуться обратно.
  6. ' + +'
  7. Род жидкости: эфир, спирт испаряются быстро; вода медленнее; ртуть — почти не испаряется.
  8. ' + +'
' + +'

Обратный процесс — конденсация (пар $\\to$ жидкость), при ней теплота выделяется.

' + ); + h += makeCard('example', 'Где встречается', '§ 10.3', + '' + ); + + /* IV1 — симуляция «молекулы покидают поверхность» */ + h += '
' + +'
IV-1
Испарение с поверхности
' + +'
Меняй температуру и ветер — наблюдай, как быстро молекулы покидают жидкость и уносятся в воздух.
' + +'
' + +'' + +'' + +'
' + +'' + +'
Испарилось молекул: 0Скорость: средняя
' + +'
'; + + /* IV2 — викторина «лужа высохнет быстрее…» */ + h += '
' + +'
IV-2
Где жидкость испарится быстрее?
' + +'
Сравни две ситуации.
' + +'
' + +'
' + +'
Раунд: 1 / 6Правильно: 0
' + +'
'; + + /* IV3 — DnD факторы */ + h += '
' + +'
IV-3
Ускоряет или замедляет испарение?
' + +'
Перетащи факторы в две колонки.
' + +'
' + +'
' + +'
Ускоряет
' + +'
Замедляет
' + +'
' + +'
' + +'
' + +'
'; + + /* IV4 — MCQ */ + h += '
' + +'
IV-4
Тренажёр: 6 вопросов
' + +'
4+ правильных — +15 XP.
' + +'
' + +'
Вопрос: 1 / 6Правильно: 0
' + +'
'; + + box.innerHTML = h + secNavFor('p10') + readButton('p10'); + renderMath(box); + wireReadBtn('p10'); + + _initP10_sim(); + _initP10_quiz(); + _initP10_dnd(); + _initP10_mcq(); +} + +function _initP10_sim(){ + _killSim('p10sim'); + const svg = document.getElementById('p10-sim'); if(!svg) return; + const W = 460, H = 220; + /* жидкость в нижней половине, частицы вылетают вверх */ + const liqY = 130; + const N = 28; + const ps = []; + for(let i=0;i W + 10 || p.y < -10){ + /* "вернуть" молекулу обратно */ + p.x = 80 + Math.random()*300; p.y = liqY + 10 + Math.random()*70; + p.vx = 0; p.vy = 0; p.evap = false; + } + } else { + /* у поверхности (y близок к liqY) есть шанс испариться */ + if(p.y < liqY + 14 && Math.random() < pEvap){ + p.evap = true; + p.vy = -1.0 - Math.random()*0.6; + p.vx = (Math.random() - 0.4) * 0.5 + wind*0.2; + evapCount++; + } else { + /* небольшое броуновское движение */ + p.x += (Math.random()-0.5)*0.6; + p.y += (Math.random()-0.5)*0.6; + if(p.x < 75) p.x = 75; if(p.x > 385) p.x = 385; + if(p.y < liqY + 6) p.y = liqY + 6; + if(p.y > 200) p.y = 200; + } + } + } + /* draw */ + let s = ''; + /* сосуд + жидкость */ + s += ''; + s += ''; + /* небо */ + s += ''; + /* солнце-температура */ + const tCol = window.PHYS.tempColor(T, 5, 90); + s += ''; + s += ''+T+'°'; + /* ветер-стрелки */ + if(wind > 0){ + for(let i=0;i'; + } + svg.innerHTML = s; + _SIMS.p10sim.raf = requestAnimationFrame(tick); + } + _SIMS.p10sim = { raf: 0 }; + _SIMS.p10sim.raf = requestAnimationFrame(tick); + + function update(){ + T = +document.getElementById('p10-t').value; + wind = +document.getElementById('p10-w').value; + document.getElementById('p10-tv').textContent = T; + document.getElementById('p10-wv').textContent = ['нет','слабый','умеренный','сильный'][wind]; + const rate = T*0.4 + wind*5; + let rateLabel = 'низкая'; + if(rate > 25) rateLabel = 'высокая'; + else if(rate > 15) rateLabel = 'средняя'; + document.getElementById('p10-rate').textContent = rateLabel; + document.getElementById('p10-evap').textContent = evapCount; + } + document.getElementById('p10-t').addEventListener('input', update); + document.getElementById('p10-w').addEventListener('input', update); + setInterval(()=>{ document.getElementById('p10-evap').textContent = evapCount; }, 500); + update(); +} + +function _initP10_quiz(){ + const QS = [ + {A:'лужа в безветренной комнате при 20 °C', B:'лужа на ветреной площади при 20 °C', ans:'B', why:'Ветер ускоряет испарение, унося пар.'}, + {A:'вода в стакане', B:'та же вода, разлитая по тарелке', ans:'B', why:'Больше площадь свободной поверхности — быстрее испарение.'}, + {A:'мокрая ткань на 20 °C', B:'та же ткань на 5 °C', ans:'A', why:'Выше $T$ — больше быстрых молекул.'}, + {A:'вода', B:'эфир (при той же $T$)', ans:'B', why:'У эфира слабее связи между молекулами, он испаряется в десятки раз быстрее воды.'}, + {A:'бельё в подвале', B:'бельё на солнце и ветру', ans:'B', why:'Солнечное излучение нагревает + ветер уносит пар.'}, + {A:'мокрая рука на воздухе', B:'мокрая рука в воде', ans:'A', why:'В воде испарения почти нет — нет свободной поверхности «жидкость-воздух».'} + ]; + let i = 0, ok = 0; + function render(){ + const q = QS[i]; const wrap = document.getElementById('p10-quiz'); if(!wrap) return; + wrap.innerHTML = + '
' + +'' + +'' + +'
' + +''; + document.getElementById('p10-quiz-r').textContent = (i+1); + document.getElementById('p10-quiz-ok').textContent = ok; + wrap.querySelectorAll('[data-pick]').forEach(btn=>{ + btn.addEventListener('click', ()=>{ + if(btn.disabled) return; wrap.querySelectorAll('[data-pick]').forEach(b=>b.disabled=true); + const fb = document.getElementById('p10-quiz-fb'); + if(btn.dataset.pick === q.ans){ ok++; fb.className='feedback ok'; fb.innerHTML='✓ Верно. '+q.why; addXp(3,'p10-quiz'); bumpProgress('p10', 4); } + else { fb.className='feedback fail'; fb.innerHTML='✗ Не то. '+q.why; } + document.getElementById('p10-quiz-ok').textContent = ok; + }); + }); + } + document.getElementById('p10-quiz-next').addEventListener('click', ()=>{ i=(i+1)%QS.length; render(); }); + render(); +} + +function _initP10_dnd(){ + const items = [ + {id:'up_t', cat:'up', html:'нагрев'}, + {id:'up_s', cat:'up', html:'большая площадь'}, + {id:'up_w', cat:'up', html:'ветер'}, + {id:'up_e', cat:'up', html:'эфир вместо воды'}, + {id:'dn_t', cat:'dn', html:'охлаждение'}, + {id:'dn_s', cat:'dn', html:'узкое горлышко'}, + {id:'dn_w', cat:'dn', html:'закрытая банка'}, + {id:'dn_m', cat:'dn', html:'ртуть вместо воды'} + ]; + const dnd = setupSorter({ poolId:'p10-dnd-pool', scopeSelector:'#sec-p10', cats:['up','dn'], items, columnLayout:false }); + document.getElementById('p10-dnd-check').addEventListener('click', ()=>{ + const fb = document.getElementById('p10-dnd-fb'); + let wrong = 0; items.forEach(it=>{ if(dnd.placed[it.id] !== it.cat) wrong++; }); + if(wrong===0){ fb.className='feedback ok'; fb.innerHTML='✓ Идеально! +15 XP. Четыре фактора: T, S, ветер, род жидкости.'; addXp(15,'p10-dnd'); bumpProgress('p10', 20); } + else { fb.className='feedback fail'; fb.innerHTML='✗ Ошибок: '+wrong+'. Подсказка: ртуть и закрытая банка — это блокирует испарение.'; } + }); + document.getElementById('p10-dnd-reset').addEventListener('click', ()=>{ dnd.reset(); const fb=document.getElementById('p10-dnd-fb'); fb.style.display='none'; }); +} + +function _initP10_mcq(){ + const QS = [ + {q:'При испарении жидкость …', opts:['нагревается','остывает','не меняет $T$','становится твёрже'], ans:1, why:'Уходят самые быстрые молекулы — средняя $E_k$ остающихся падает.'}, + {q:'При какой температуре идёт испарение?', opts:['только при $T_{кип}$','при любой $T$','только зимой','только под солнцем'], ans:1, why:'Испарение идёт всегда, даже у льда (возгонка).'}, + {q:'Почему мокрая рука зябнет на ветру?', opts:['ветер холодный','вода уносит тепло','испарение охлаждает','оба B и C'], ans:3, why:'И вода уносит тепло, и испаряясь, охлаждает кожу.'}, + {q:'Где жидкость испаряется быстрее?', opts:['в стакане','в тарелке','в бутылке','в пробирке'], ans:1, why:'В тарелке самая большая площадь свободной поверхности.'}, + {q:'Что произойдёт, если над паром резко охладить?', opts:['он замёрзнет','он расширится','он конденсируется','ничего'], ans:2, why:'Конденсация — пар возвращается в жидкость, тепло выделяется.'}, + {q:'Когда лужа высохнет быстрее?', opts:['ночью','днём','в тумане','в подвале'], ans:1, why:'Днём — больше тепла, обычно ветер.'} + ]; + let i = 0, ok = 0, done = 0, awarded = false; + function render(){ + const q = QS[i]; const wrap = document.getElementById('p10-mcq'); if(!wrap) return; + let h = '
Вопрос '+(i+1)+'. '+q.q+'
'; + q.opts.forEach((opt,k)=>{ h += ''; }); + h += '
'; + wrap.innerHTML = h; + document.getElementById('p10-mcq-i').textContent = (i+1); + document.getElementById('p10-mcq-ok').textContent = ok; + wrap.querySelectorAll('[data-k]').forEach(btn=>{ + btn.addEventListener('click', ()=>{ + if(btn.disabled) return; wrap.querySelectorAll('[data-k]').forEach(b=>b.disabled=true); + const k = +btn.dataset.k; const fb = document.getElementById('p10-mcq-fb'); + if(k===q.ans){ ok++; done++; fb.className='feedback ok'; fb.innerHTML='✓ Верно. '+q.why; addXp(2,'p10-mcq'); bumpProgress('p10', 3); } + else { done++; fb.className='feedback fail'; fb.innerHTML='✗ Не то. '+q.why; } + document.getElementById('p10-mcq-ok').textContent = ok; + renderMath(wrap); + if(done >= QS.length && !awarded && ok >= 4){ awarded = true; setTimeout(()=>{ const wf=document.getElementById('p10-mcq-fb'); wf.className='feedback ok'; wf.innerHTML='✓ +15 XP — тренажёр пройден ('+ok+'/'+QS.length+').'; addXp(15,'p10-mcq-bonus'); bumpProgress('p10', 15); }, 600); } + }); + }); + const nb = document.getElementById('p10-mcq-next'); if(nb) nb.addEventListener('click', ()=>{ i=(i+1)%QS.length; render(); }); + renderMath(wrap); + } + render(); +} + +/* ======== §11 — Кипение, удельная теплота парообразования ======== */ +function build_p11(){ + const box = document.getElementById('p11-body'); + let h = ''; + + h += makeCard('theory', 'Что такое кипение', '§ 11.1', + '

Кипение — переход жидкости в пар по всему объёму при определённой температуре $T_{кип}$.

' + +'

В жидкости всегда есть растворённый воздух с пузырьками пара. При $T = T_{кип}$ давление пара в пузырьках становится равно атмосферному, пузырьки растут, всплывают и лопаются — это и есть кипение.

' + +'

Во время кипения температура жидкости не меняется, как и при плавлении.

' + ); + h += makeCard('rule', '$Q = Lm$ — удельная теплота парообразования', '§ 11.2', + '

Чтобы перевести массу $m$ жидкости (при $T = T_{кип}$) в пар, нужно:

' + +'

$$Q = L\\,m$$

' + +'

$L$ — удельная теплота парообразования, Дж/кг. Для воды:

' + +'

L = 2,26 · 106 Дж/кг = 2260 кДж/кг

' + +'

Это огромная величина — поэтому ожог паром опаснее ожога кипятком (пар конденсируется на коже и выделяет $L$).

' + ); + h += makeCard('example', '$T_{кип}$ зависит от давления', '§ 11.3', + '
    ' + +'
  • При нормальном давлении (1 атм $= 10^5$ Па) вода кипит при $100$ °C.
  • ' + +'
  • На горе $T_{кип}$ ниже (давление меньше). На Эвересте — около $70$ °C.
  • ' + +'
  • В скороварке давление выше — $T_{кип}$ выше ($120$ °C), еда варится быстрее.
  • ' + +'
  • В вакууме вода кипит при комнатной температуре.
  • ' + +'
' + ); + + /* IV1 — главный визуал: график «лёд → вода → пар» */ + h += '
' + +'
IV-1
Полный цикл «лёд → вода → пар»
' + +'
Нагреваем 1 кг льда от -20 °C до пара при 100 °C. График $T(t)$ имеет два плато: плавление и кипение.
' + +'' + +'
' + +' 1. Нагрев льда' + +' 2. Плавление при 0 °C ($\\lambda m$)' + +' 3. Нагрев воды' + +' 4. Кипение при 100 °C ($L m$) — самое длинное плато!' + +' 5. Нагрев пара' + +'
' + +'
'; + + /* IV2 — калькулятор Q = Lm */ + h += '
' + +'
IV-2
Калькулятор $Q = Lm$
' + +'
Сколько энергии нужно, чтобы перевести жидкость в пар при $T = T_{кип}$?
' + +'
' + +'' + +'' + +'
' + +'
' + +'$Q$ = 2.26 МДж = 0.63 кВт·ч' + +'Эквивалент: нагрев 6.7 кг воды от 20 до 100 °C.' + +'
' + +'
'; + + /* IV3 — DnD «фазовый переход» */ + h += '
' + +'
IV-3
Какой переход?
' + +'
Распредели процессы по типам.
' + +'
' + +'
' + +'
Плавление
' + +'
Испарение / кипение
' + +'
Конденсация / кристаллизация
' + +'
' + +'
' + +'' + +'
'; + + /* IV4 — расчётные задачи */ + h += '
' + +'
IV-4
Тренажёр: 6 расчётных задач
' + +'
4+ верных — +15 XP.
' + +'
' + +'
Задача: 1 / 6Правильно: 0
' + +'
'; + + box.innerHTML = h + secNavFor('p11') + readButton('p11'); + renderMath(box); + wireReadBtn('p11'); + + _initP11_graph(); + _initP11_calc(); + _initP11_dnd(); + _initP11_tasks(); +} + +function _initP11_graph(){ + const svg = document.getElementById('p11-sim'); if(!svg) return; + /* строим график T(t) для 1 кг воды/льда/пара + сегменты по времени: + 1) -20→0 (лёд): t = m·c_ice·20 / P + 2) плавление: t = m·λ / P + 3) 0→100 (вода): t = m·c_w·100 / P + 4) кипение: t = m·L / P + 5) пар после 100, нагрев на 80 К (с pp = 2010 для пара) + Используем относительные времена. */ + const m = 1; + const cIce=2100, lam=3.34e5, cW=4200, L=2.26e6, cSt=2010; + const t1 = m*cIce*20; /* 42 000 */ + const t2 = m*lam; /* 334 000 */ + const t3 = m*cW*100; /* 420 000 */ + const t4 = m*L; /* 2 260 000 */ + const t5 = m*cSt*80; /* 160 800 */ + const T1 = 0, T2 = 100, T3 = 180; + const tot = t1+t2+t3+t4+t5; /* нормируем к 10 */ + const sc = 10/tot; + /* points */ + let cur = 0; + const segs = [ + { tStart: cur, tEnd: (cur+=t1*sc)*1, Tstart: -20, Tend: 0, col: '#2563eb', label:'лёд' }, + { tStart: (cur), tEnd: (cur+=t2*sc), Tstart: 0, Tend: 0, col: '#f59e0b', label:'плавление' }, + { tStart: (cur), tEnd: (cur+=t3*sc), Tstart: 0, Tend: 100, col: '#dc2626', label:'вода' }, + { tStart: (cur), tEnd: (cur+=t4*sc), Tstart: 100, Tend: 100, col: '#ef4444', label:'кипение' }, + { tStart: (cur), tEnd: (cur+=t5*sc), Tstart: 100, Tend: 180, col: '#7c3aed', label:'пар' } + ]; + const W=460, H=280, pad=36; + const r = window.PHYS.phaseGraphTT(W, H, pad, segs.map(s=>({tStart:s.tStart,tEnd:s.tEnd,Tstart:s.Tstart,Tend:s.Tend})), 10, -40, 200); + /* Раскрашиваем сегменты разными цветами поверх */ + let extra = ''; + /* Горизонталь 0 и 100 */ + extra += ''; + extra += ''; + /* подписи 0 и 100 */ + extra += '0 °C (плавление)'; + extra += '100 °C (кипение)'; + /* перерисовываем сегменты */ + for(const s of segs){ + extra += ''; + } + svg.innerHTML = r.svg + extra; +} + +function _initP11_calc(){ + function update(){ + const L = +document.getElementById('p11-liq').value; + const m = +document.getElementById('p11-m').value; + document.getElementById('p11-mv').textContent = m.toFixed(1); + const Q = L*m; + document.getElementById('p11-q').textContent = (Q/1e6).toFixed(2)+' МДж'; + document.getElementById('p11-qkw').textContent = (Q/3.6e6).toFixed(2); + /* эквивалент: нагрев воды от 20 до 100 (ΔT=80, c=4200) */ + document.getElementById('p11-eqkg').textContent = (Q/(4200*80)).toFixed(1); + } + document.getElementById('p11-liq').addEventListener('change', update); + document.getElementById('p11-m').addEventListener('input', update); + update(); +} + +function _initP11_dnd(){ + const items = [ + {id:'a', cat:'melt', html:'лёд тает в стакане'}, + {id:'b', cat:'melt', html:'свинец становится жидким'}, + {id:'c', cat:'evap', html:'лужа высыхает'}, + {id:'d', cat:'evap', html:'кипящий чайник пускает пар'}, + {id:'e', cat:'evap', html:'спирт испаряется с кожи'}, + {id:'f', cat:'cond', html:'роса утром на траве'}, + {id:'g', cat:'cond', html:'пар оседает на холодном стекле'}, + {id:'h', cat:'cond', html:'жидкое золото застывает в слитки'} + ]; + const dnd = setupSorter({ poolId:'p11-dnd-pool', scopeSelector:'#sec-p11', cats:['melt','evap','cond'], items, columnLayout:false }); + document.getElementById('p11-dnd-check').addEventListener('click', ()=>{ + const fb = document.getElementById('p11-dnd-fb'); + let wrong = 0; items.forEach(it=>{ if(dnd.placed[it.id] !== it.cat) wrong++; }); + if(wrong===0){ fb.className='feedback ok'; fb.innerHTML='✓ Идеально! +15 XP. Все фазовые переходы — это пары прямой и обратный.'; addXp(15,'p11-dnd'); bumpProgress('p11', 20); } + else { fb.className='feedback fail'; fb.innerHTML='✗ Ошибок: '+wrong+'. Подсказка: роса — это пар → жидкость (конденсация).'; } + }); + document.getElementById('p11-dnd-reset').addEventListener('click', ()=>{ dnd.reset(); const fb=document.getElementById('p11-dnd-fb'); fb.style.display='none'; }); +} + +function _initP11_tasks(){ + const TASKS = [ + {q:'Сколько энергии (в МДж) нужно, чтобы превратить 0,5 кг воды (100 °C) в пар? ($L = 2{,}26 \\cdot 10^6$)', ans: 1.13, tol: 0.04, why:'$Q = Lm = 2{,}26\\cdot10^6 \\cdot 0{,}5 = 1{,}13\\cdot10^6$ Дж = $1{,}13$ МДж.'}, + {q:'Сколько кг воды можно превратить в пар, имея 11,3 МДж энергии?', ans: 5, tol: 0.1, why:'$m = Q/L = 1{,}13\\cdot10^7/(2{,}26\\cdot10^6) = 5$ кг.'}, + {q:'$Q_1$ — нагрев 1 кг воды от 20 до 100 °C. $Q_2$ — испарение этой воды. Найди отношение $Q_2/Q_1$ (целое число).', ans: 7, tol: 0.5, why:'$Q_1 = 4200 \\cdot 80 = 336$ кДж. $Q_2 = 2260$ кДж. $Q_2/Q_1 \\approx 6{,}7 \\approx 7$.'}, + {q:'Спирт массой 2 кг полностью испаряется. Сколько кДж нужно? ($L = 9 \\cdot 10^5$)', ans: 1800, tol: 30, why:'$Q = 9\\cdot10^5 \\cdot 2 = 1{,}8\\cdot10^6$ Дж = $1800$ кДж.'}, + {q:'При конденсации 100 г пара (100 °C) сколько кДж выделится?', ans: 226, tol: 6, why:'$Q = Lm = 2{,}26\\cdot10^6 \\cdot 0{,}1 = 2{,}26\\cdot10^5$ Дж = $226$ кДж.'}, + {q:'1 кг льда (-10 °C) превратить полностью в пар (100 °C). Сколько МДж нужно? ($c_л=2100$, $\\lambda=3{,}34\\cdot10^5$, $c_в=4200$, $L=2{,}26\\cdot10^6$)', ans: 3.04, tol: 0.06, why:'$Q_1=21\\,000$, $Q_2=334\\,000$, $Q_3=420\\,000$, $Q_4=2\\,260\\,000$. Итого $3{,}04$ МДж.'} + ]; + let i = 0, ok = 0, done = 0, awarded = false; + function render(){ + const t = TASKS[i]; const wrap = document.getElementById('p11-task'); if(!wrap) return; + wrap.innerHTML = + '
Задача '+(i+1)+'. '+t.q+'
' + +'
' + +'' + +'' + +'
' + +'
'+t.why+'
' + +''; + document.getElementById('p11-task-i').textContent = (i+1); + document.getElementById('p11-task-ok').textContent = ok; + document.getElementById('p11-task-go').addEventListener('click', ()=>{ + const v = parseFloat((document.getElementById('p11-task-inp').value || '').replace(',','.')); + const fb = document.getElementById('p11-task-fb'); + if(isNaN(v)){ fb.className='feedback fail'; fb.innerHTML='Введи число.'; return; } + done++; + if(Math.abs(v - t.ans) < t.tol){ ok++; fb.className='feedback ok'; fb.innerHTML='✓ Верно! '+t.why; addXp(4,'p11-task'); bumpProgress('p11', 6); } + else { fb.className='feedback fail'; fb.innerHTML='✗ Не то. Правильный ответ: '+t.ans+'. '+t.why; } + document.getElementById('p11-task-ok').textContent = ok; + renderMath(wrap); + if(done >= TASKS.length && !awarded && ok >= 4){ awarded = true; setTimeout(()=>{ const wf=document.getElementById('p11-task-fb'); wf.className='feedback ok'; wf.innerHTML='✓ +15 XP — расчёты сданы ('+ok+'/'+TASKS.length+').'; addXp(15,'p11-task-bonus'); bumpProgress('p11', 15); }, 600); } + }); + document.getElementById('p11-task-hint').addEventListener('click', ()=>{ document.getElementById('p11-task-hint-txt').classList.toggle('show'); }); + document.getElementById('p11-task-next').addEventListener('click', ()=>{ i=(i+1)%TASKS.length; render(); }); + renderMath(wrap); + } + render(); +} + +/* ======== ФИНАЛ ГЛАВЫ 1 ======== */ +function build_final1(){ + const box = document.getElementById('final1-body'); + let h = ''; + + /* Шпаргалка главы */ + h += '
' + +'
'+ICONS.rule+'
Шпаргалка главы 1
' + +'
' + +'
Тепло при изменении $T$: $Q = c m \\Delta T$
c — Дж/(кг·К). У воды 4200.
' + +'
Тепло при сгорании: $Q = q m$
q — Дж/кг. У бензина 4{,}6·10⁷.
' + +'
Тепло на плавление: $Q = \\lambda m$
λ — Дж/кг. У льда 3{,}34·10⁵.
' + +'
Тепло на парообразование: $Q = L m$
L — Дж/кг. У воды 2{,}26·10⁶.
' + +'
Баланс: $Q_{отд} = Q_{пол}$
' + +'
3 вида теплопередачи: проводность, конвекция, излучение
' + +'
'; + + /* 7 интегрированных боссов */ + const BOSSES = [ + {n:1, title:'Нагрев + расчёт', q:'На сколько градусов нагреется 2 кг алюминия при подведении 92 кДж? ($c = 920$)', hint:'$\\Delta T = Q/(cm) = 92\\,000/(920 \\cdot 2) = 50$ К.', ans:50, tol:1, step:'1'}, + {n:2, title:'Смешивание воды', q:'Смешали 2 кг воды при $80$ °C и 3 кг воды при $20$ °C. Итоговая $T$ (°C)?', hint:'$T = (2\\cdot80 + 3\\cdot20)/5 = 220/5 = 44$ °C.', ans:44, tol:0.5, step:'1'}, + {n:3, title:'Плавление', q:'Сколько кДж нужно, чтобы расплавить 3 кг льда при 0 °C? ($\\lambda = 3{,}34\\cdot10^5$)', hint:'$Q = \\lambda m = 3{,}34\\cdot10^5 \\cdot 3 = 1{,}002\\cdot10^6$ Дж = $1002$ кДж.', ans:1002, tol:10, step:'1'}, + {n:4, title:'Кипение', q:'1 кг воды при 100 °C полностью испарили. Сколько МДж энергии затрачено? ($L = 2{,}26\\cdot10^6$)', hint:'$Q = Lm = 2{,}26$ МДж.', ans:2.26, tol:0.05, step:'0.01'}, + {n:5, title:'Цепная задача', q:'1 кг льда при -10 °C довели до воды при 50 °C. Сколько кДж? ($c_л=2100$, $\\lambda=3{,}34\\cdot10^5$, $c_в=4200$)', hint:'$Q_1 = 21\\,000$, $Q_2 = 334\\,000$, $Q_3 = 210\\,000$, итого $565\\,000$ Дж = $565$ кДж.', ans:565, tol:12, step:'1'}, + {n:6, title:'Топливо + КПД', q:'Котёл с $\\eta = 60\\%$ сжёг 5 кг дров. Какая полезная энергия в МДж? ($q = 10^7$)', hint:'$Q_{сгор} = 5\\cdot10^7 = 50$ МДж. $Q_{пол} = 0{,}6 \\cdot 50 = 30$ МДж.', ans:30, tol:0.5, step:'1'}, + {n:7, title:'Полный цикл', q:'Сколько МДж нужно, чтобы 0,5 кг льда (0 °C) превратить в пар (100 °C)? ($\\lambda = 3{,}34\\cdot10^5$, $c_в = 4200$, $L = 2{,}26\\cdot10^6$). Округли до сотых.', hint:'$Q_{пл}=167\\,000$, $Q_{нагр}=210\\,000$, $Q_{исп}=1\\,130\\,000$. Итого $1{,}51$ МДж.', ans:1.51, tol:0.04, step:'0.01'} + ]; + + h += '
'+ICONS.example+'
Боссы главы 1
' + +'
' + +'Боссов побеждено: 0 / 7' + +'
' + +'
' + +'
' + +'
' + +'
'; + + box.innerHTML = h + secNavFor('final1') + readButton('final1'); + renderMath(box); + wireReadBtn('final1'); + + _initFinal1_bosses(BOSSES); +} + +function _initFinal1_bosses(BOSSES){ + const KEY = 'physics8_ch1_bosses'; + function loadState(){ try { return JSON.parse(localStorage.getItem(KEY) || '{}') || {}; } catch(e){ return {}; } } + function saveState(s){ try { localStorage.setItem(KEY, JSON.stringify(s)); } catch(e){} } + function updateBar(){ + const s = loadState(); + let won = 0; for(const k in s) if(s[k]) won++; + document.getElementById('f1-won').textContent = won; + document.getElementById('f1-bar').style.width = Math.round(won*100/BOSSES.length)+'%'; + if(won >= BOSSES.length && !STATE.achievements.has('thermal_master')){ + addXp(50, 'thermal-master'); + achievement('thermal_master'); + } + return won; + } + function renderAll(){ + const cont = document.getElementById('f1-bosses'); + const state = loadState(); + let html = ''; + BOSSES.forEach(b=>{ + const solved = state[b.n]; + html += '
' + +'
Босс '+b.n+''+b.title+'
' + +'
'+b.q+'
' + +'
' + +'' + +'' + +'' + +'
' + +'' + +'
'+(solved?'✓ Победа! +10 XP. Босс повержен.':'')+'
' + +'
'; + }); + cont.innerHTML = html; + BOSSES.forEach(b=>{ + const go = document.getElementById('f1-b'+b.n+'-go'); + const inp = document.getElementById('f1-b'+b.n+'-inp'); + const fb = document.getElementById('f1-b'+b.n+'-fb'); + const ht = document.getElementById('f1-b'+b.n+'-ht'); + const hintBtn = document.getElementById('f1-b'+b.n+'-hint'); + if(hintBtn) hintBtn.addEventListener('click', ()=>{ ht.style.display = ht.style.display==='block'?'none':'block'; }); + if(!go || go.disabled) return; + go.addEventListener('click', ()=>{ + const v = parseFloat((inp.value || '').replace(',','.')); + if(isNaN(v)){ fb.style.display='block'; fb.className='feedback fail'; fb.innerHTML='Введите число.'; return; } + if(Math.abs(v - b.ans) < b.tol){ + fb.style.display='block'; fb.className='feedback ok'; fb.innerHTML='✓ Победа! +10 XP. '+b.hint; + go.disabled = true; inp.disabled = true; + document.getElementById('f1-boss-'+b.n).classList.add('solved'); + const s = loadState(); + if(!s[b.n]){ s[b.n]=true; saveState(s); addXp(10,'f1-boss-'+b.n); bumpProgress('final1', 12); } + updateBar(); + renderMath(fb); + } else { + fb.style.display='block'; fb.className='feedback fail'; fb.innerHTML='✗ Не то. Перепроверь и попробуй снова.'; + } + }); + inp.addEventListener('keydown', e=>{ if(e.key === 'Enter') go.click(); }); + }); + renderMath(cont); + updateBar(); + } + renderAll(); +} + function init(){ loadProgress(); initTheme(); initSidebarToggle(); initSearch(); buildParaSelector(); refreshProgressUI(); loadServerReadState(); goTo(PARAS[0].id);