feat(p8 ch1): IV-5 расчётные задачи для §1-5, §8, §10 (тепловые явления)
В Физике 8 ch1 §6, §7, §9, §11 уже имели IV-4 'Тренажёр N расчётных задач'. У §1-5, §8, §10 IV-4 был только MCQ — числовых задач не было. inject_p8_ch1_tasks.cjs добавляет IV-5 виджет после IV-4 в build_pN: - §1 Внутр. энергия: 5 задач (T-конверсия, U vs масса/высота) - §2 Способы изменения U: 5 (Q=ΔU+A, кин. энергия молота → тепло) - §3 Теплопроводность: 5 (тепловой поток P=Q/t, зависимости от d, S, λ) - §4 Конвекция: 5 (плотности тёплого/холодного, нагрев радиатором) - §5 Излучение: 5 (солнечный поток, Стефан-Больцман упрощённо) - §8 Плавление: 5 (Q=λm) - §10 Испарение: 5 (Q=rm, испарение пота, лужи) Всего 35 новых задач с автопроверкой числового ответа (±tol), подсказкой-решением (KaTeX) и +20 XP при прохождении всей серии. Используется существующий design system (.wg, .tinp, .feedback, .score-display) — уже подключён через phys-textbook-widgets.css.
This commit is contained in:
@@ -812,9 +812,18 @@ function build_p1(){
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Вопрос: <b id="p1-mcq-i">1</b> / 6</span><span>Правильно: <b id="p1-mcq-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
/* IV5 — Расчётные задачи (auto-injected) */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-5</span><div class="wg-title">Тренажёр: 5 расчётных задач</div></div>'
|
||||
+'<div class="wg-help">Введи числовой ответ (можно с точкой как разделителем). Решено все верно — +20 XP.</div>'
|
||||
+'<div id="p1-tasks5"></div>'
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p1-tasks5-i">1</b> / 5</span><span>Правильно: <b id="p1-tasks5-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
box.innerHTML = h + secNavFor('p1') + readButton('p1');
|
||||
renderMath(box);
|
||||
wireReadBtn('p1');
|
||||
_initp1_iv5();
|
||||
|
||||
_initP1_sim();
|
||||
_initP1_quiz();
|
||||
@@ -822,6 +831,47 @@ function build_p1(){
|
||||
_initP1_mcq();
|
||||
}
|
||||
|
||||
function _initp1_iv5(){
|
||||
const TASKS = [{"q":"Переведите температуру $t = 27\\,^\\circ$C в кельвины. ($T = t + 273$)","ans":300,"tol":1,"why":"$T = 27 + 273 = 300$ К."},{"q":"Температура воды $T = 373$ К. Чему равно $t$ в градусах Цельсия?","ans":100,"tol":1,"why":"$t = T - 273 = 373 - 273 = 100\\,^\\circ$C — кипение воды."},{"q":"У стакана воды массой $m_1 = 0{,}5$ кг и у бочки воды массой $m_2 = 50$ кг одинаковая температура. У кого внутренняя энергия больше во сколько раз?","ans":100,"tol":1,"why":"$U \\propto m$ при одинаковой $T$. $U_2/U_1 = m_2/m_1 = 50/0{,}5 = 100$."},{"q":"Тело нагрели на $\\Delta T = 30$ К. На сколько градусов Цельсия изменилась его температура?","ans":30,"tol":0.5,"why":"Шкалы Кельвина и Цельсия отличаются только сдвигом — разность температур одинакова."},{"q":"При какой температуре по шкале Цельсия средняя кинетическая энергия молекул равна нулю (абсолютный ноль)?","ans":-273,"tol":1,"why":"Абсолютный ноль $T = 0$ К соответствует $t = 0 - 273 = -273\\,^\\circ$C."}];
|
||||
let i = 0, ok = 0, awarded = false;
|
||||
function render(){
|
||||
const t = TASKS[i]; const wrap = document.getElementById('p1-tasks5'); if(!wrap) return;
|
||||
wrap.innerHTML =
|
||||
'<div style="padding:10px 14px;background:rgba(15,23,42,.04);border-radius:9px;margin-bottom:10px;font-size:.95rem;line-height:1.55"><b>Задача '+(i+1)+'.</b> '+t.q+'</div>'
|
||||
+'<div class="actions"><input type="number" step="0.001" class="tinp" id="p1-iv5-inp" placeholder="число" style="width:140px">'
|
||||
+'<button class="btn primary" id="p1-iv5-go">Ответ</button>'
|
||||
+'<button class="btn" id="p1-iv5-hint">Подсказка</button>'
|
||||
+'<button class="btn" id="p1-iv5-next">Следующая</button></div>'
|
||||
+'<details class="spoiler" id="p1-iv5-why-wrap" style="margin-top:8px;display:none"><summary>Решение</summary><div class="spoiler-body">'+t.why+'</div></details>'
|
||||
+'<div class="feedback" id="p1-iv5-fb"></div>';
|
||||
if (window.renderMathInElement) try { renderMathInElement(wrap, {delimiters:[{left:'$',right:'$',display:false}],throwOnError:false}); } catch(e){}
|
||||
document.getElementById('p1-iv5-go').onclick = () => {
|
||||
const v = parseFloat(document.getElementById('p1-iv5-inp').value.replace(',','.'));
|
||||
const fb = document.getElementById('p1-iv5-fb');
|
||||
const wh = document.getElementById('p1-iv5-why-wrap');
|
||||
if (Math.abs(v - t.ans) <= t.tol) {
|
||||
fb.className = 'feedback ok'; fb.innerHTML = 'Верно!'; ok++;
|
||||
document.getElementById('p1-tasks5-ok').textContent = ok;
|
||||
wh.style.display = 'block';
|
||||
} else {
|
||||
fb.className = 'feedback fail'; fb.innerHTML = 'Не совсем. Ожидался $' + t.ans + '$. Загляни в подсказку.';
|
||||
if (window.renderMathInElement) try { renderMathInElement(fb, {delimiters:[{left:'$',right:'$',display:false}],throwOnError:false}); } catch(e){}
|
||||
}
|
||||
};
|
||||
document.getElementById('p1-iv5-hint').onclick = () => {
|
||||
const wh = document.getElementById('p1-iv5-why-wrap');
|
||||
wh.style.display = wh.style.display === 'block' ? 'none' : 'block';
|
||||
};
|
||||
document.getElementById('p1-iv5-next').onclick = () => {
|
||||
i = (i + 1) % TASKS.length;
|
||||
document.getElementById('p1-tasks5-i').textContent = i + 1;
|
||||
render();
|
||||
if (ok === TASKS.length && !awarded) { awarded = true; if (typeof addXp === 'function') addXp(20, 'p1-iv5'); }
|
||||
};
|
||||
}
|
||||
render();
|
||||
}
|
||||
|
||||
/* === §1 IV-1: газ-симуляция === */
|
||||
function _initP1_sim(){
|
||||
_killSim('p1sim');
|
||||
@@ -1116,9 +1166,18 @@ function build_p2(){
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Вопрос: <b id="p2-mcq-i">1</b> / 6</span><span>Правильно: <b id="p2-mcq-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
/* IV5 — Расчётные задачи (auto-injected) */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-5</span><div class="wg-title">Тренажёр: 5 расчётных задач</div></div>'
|
||||
+'<div class="wg-help">Введи числовой ответ (можно с точкой как разделителем). Решено все верно — +20 XP.</div>'
|
||||
+'<div id="p2-tasks5"></div>'
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p2-tasks5-i">1</b> / 5</span><span>Правильно: <b id="p2-tasks5-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
box.innerHTML = h + secNavFor('p2') + readButton('p2');
|
||||
renderMath(box);
|
||||
wireReadBtn('p2');
|
||||
_initp2_iv5();
|
||||
|
||||
_initP2_sim();
|
||||
_initP2_quiz();
|
||||
@@ -1126,6 +1185,47 @@ function build_p2(){
|
||||
_initP2_mcq();
|
||||
}
|
||||
|
||||
function _initp2_iv5(){
|
||||
const TASKS = [{"q":"Газу передали $Q = 200$ Дж теплоты, и он совершил работу $A = 60$ Дж. На сколько увеличилась его внутренняя энергия? ($\\Delta U = Q - A$)","ans":140,"tol":2,"why":"$\\Delta U = Q - A = 200 - 60 = 140$ Дж (первое начало термодинамики)."},{"q":"Над газом совершили работу $A_{внеш} = 150$ Дж, газ отдал $Q = 50$ Дж тепла. На сколько изменилась $U$?","ans":100,"tol":2,"why":"$\\Delta U = A_{внеш} - Q_{отд} = 150 - 50 = 100$ Дж."},{"q":"Газ адиабатно (без теплообмена, $Q = 0$) расширился, совершив $A = 80$ Дж. Найдите $|\\Delta U|$.","ans":80,"tol":2,"why":"При $Q = 0$: $\\Delta U = -A = -80$ Дж. Модуль изменения $|\\Delta U| = 80$ Дж."},{"q":"Молотом массой $0{,}5$ кг, движущимся со скоростью $v = 4$ м/с, ударили по гвоздю. Вся кинетическая энергия перешла в тепло. На сколько Джоулей увеличилась $U$ гвоздя?","ans":4,"tol":0.1,"why":"$E_к = \\dfrac{mv^2}{2} = \\dfrac{0{,}5 \\cdot 16}{2} = 4$ Дж $= \\Delta U$."},{"q":"Газу сообщили $Q = 500$ Дж, при этом $\\Delta U = 350$ Дж. Какую работу совершил газ?","ans":150,"tol":3,"why":"$A = Q - \\Delta U = 500 - 350 = 150$ Дж."}];
|
||||
let i = 0, ok = 0, awarded = false;
|
||||
function render(){
|
||||
const t = TASKS[i]; const wrap = document.getElementById('p2-tasks5'); if(!wrap) return;
|
||||
wrap.innerHTML =
|
||||
'<div style="padding:10px 14px;background:rgba(15,23,42,.04);border-radius:9px;margin-bottom:10px;font-size:.95rem;line-height:1.55"><b>Задача '+(i+1)+'.</b> '+t.q+'</div>'
|
||||
+'<div class="actions"><input type="number" step="0.001" class="tinp" id="p2-iv5-inp" placeholder="число" style="width:140px">'
|
||||
+'<button class="btn primary" id="p2-iv5-go">Ответ</button>'
|
||||
+'<button class="btn" id="p2-iv5-hint">Подсказка</button>'
|
||||
+'<button class="btn" id="p2-iv5-next">Следующая</button></div>'
|
||||
+'<details class="spoiler" id="p2-iv5-why-wrap" style="margin-top:8px;display:none"><summary>Решение</summary><div class="spoiler-body">'+t.why+'</div></details>'
|
||||
+'<div class="feedback" id="p2-iv5-fb"></div>';
|
||||
if (window.renderMathInElement) try { renderMathInElement(wrap, {delimiters:[{left:'$',right:'$',display:false}],throwOnError:false}); } catch(e){}
|
||||
document.getElementById('p2-iv5-go').onclick = () => {
|
||||
const v = parseFloat(document.getElementById('p2-iv5-inp').value.replace(',','.'));
|
||||
const fb = document.getElementById('p2-iv5-fb');
|
||||
const wh = document.getElementById('p2-iv5-why-wrap');
|
||||
if (Math.abs(v - t.ans) <= t.tol) {
|
||||
fb.className = 'feedback ok'; fb.innerHTML = 'Верно!'; ok++;
|
||||
document.getElementById('p2-tasks5-ok').textContent = ok;
|
||||
wh.style.display = 'block';
|
||||
} else {
|
||||
fb.className = 'feedback fail'; fb.innerHTML = 'Не совсем. Ожидался $' + t.ans + '$. Загляни в подсказку.';
|
||||
if (window.renderMathInElement) try { renderMathInElement(fb, {delimiters:[{left:'$',right:'$',display:false}],throwOnError:false}); } catch(e){}
|
||||
}
|
||||
};
|
||||
document.getElementById('p2-iv5-hint').onclick = () => {
|
||||
const wh = document.getElementById('p2-iv5-why-wrap');
|
||||
wh.style.display = wh.style.display === 'block' ? 'none' : 'block';
|
||||
};
|
||||
document.getElementById('p2-iv5-next').onclick = () => {
|
||||
i = (i + 1) % TASKS.length;
|
||||
document.getElementById('p2-tasks5-i').textContent = i + 1;
|
||||
render();
|
||||
if (ok === TASKS.length && !awarded) { awarded = true; if (typeof addXp === 'function') addXp(20, 'p2-iv5'); }
|
||||
};
|
||||
}
|
||||
render();
|
||||
}
|
||||
|
||||
/* === §2 IV-1: симуляция «работа vs теплопередача» === */
|
||||
function _initP2_sim(){
|
||||
_killSim('p2sim');
|
||||
@@ -1433,9 +1533,18 @@ function build_p3(){
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Вопрос: <b id="p3-mcq-i">1</b> / 6</span><span>Правильно: <b id="p3-mcq-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
/* IV5 — Расчётные задачи (auto-injected) */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-5</span><div class="wg-title">Тренажёр: 5 расчётных задач</div></div>'
|
||||
+'<div class="wg-help">Введи числовой ответ (можно с точкой как разделителем). Решено все верно — +20 XP.</div>'
|
||||
+'<div id="p3-tasks5"></div>'
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p3-tasks5-i">1</b> / 5</span><span>Правильно: <b id="p3-tasks5-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
box.innerHTML = h + secNavFor('p3') + readButton('p3');
|
||||
renderMath(box);
|
||||
wireReadBtn('p3');
|
||||
_initp3_iv5();
|
||||
|
||||
_initP3_sim();
|
||||
_initP3_quiz();
|
||||
@@ -1443,6 +1552,47 @@ function build_p3(){
|
||||
_initP3_mcq();
|
||||
}
|
||||
|
||||
function _initp3_iv5(){
|
||||
const TASKS = [{"q":"Через стенку площадью $S = 2$ м² с разностью температур $\\Delta T = 20$ К за $t = 100$ с прошло $Q = 200$ Дж. Найдите тепловой поток (Вт): $P = Q/t$.","ans":2,"tol":0.05,"why":"$P = Q/t = 200 / 100 = 2$ Вт."},{"q":"Тепловой поток через стенку $P = 50$ Вт. Сколько джоулей теплоты пройдёт через неё за $t = 1$ час?","ans":180000,"tol":1000,"why":"$Q = P \\cdot t = 50 \\cdot 3600 = 180\\,000$ Дж."},{"q":"У какого материала теплопроводность больше при прочих равных: у $\\lambda_1 = 400$ Вт/(м·К) (медь) или $\\lambda_2 = 0{,}5$ Вт/(м·К) (вода)? Введите $\\lambda_1/\\lambda_2$.","ans":800,"tol":5,"why":"$\\lambda_1 / \\lambda_2 = 400 / 0{,}5 = 800$ — металлы намного лучше проводят тепло."},{"q":"Стенка толщиной $d_1 = 0{,}1$ м заменена на стенку толщиной $d_2 = 0{,}05$ м из того же материала. Во сколько раз вырастет тепловой поток?","ans":2,"tol":0.05,"why":"Поток $P \\propto 1/d$, поэтому $P_2/P_1 = d_1/d_2 = 0{,}1/0{,}05 = 2$."},{"q":"Площадь стенки увеличили в 3 раза. Во сколько раз вырастет тепловой поток (при той же толщине и $\\Delta T$)?","ans":3,"tol":0.05,"why":"Поток $P \\propto S$, поэтому увеличивается в 3 раза."}];
|
||||
let i = 0, ok = 0, awarded = false;
|
||||
function render(){
|
||||
const t = TASKS[i]; const wrap = document.getElementById('p3-tasks5'); if(!wrap) return;
|
||||
wrap.innerHTML =
|
||||
'<div style="padding:10px 14px;background:rgba(15,23,42,.04);border-radius:9px;margin-bottom:10px;font-size:.95rem;line-height:1.55"><b>Задача '+(i+1)+'.</b> '+t.q+'</div>'
|
||||
+'<div class="actions"><input type="number" step="0.001" class="tinp" id="p3-iv5-inp" placeholder="число" style="width:140px">'
|
||||
+'<button class="btn primary" id="p3-iv5-go">Ответ</button>'
|
||||
+'<button class="btn" id="p3-iv5-hint">Подсказка</button>'
|
||||
+'<button class="btn" id="p3-iv5-next">Следующая</button></div>'
|
||||
+'<details class="spoiler" id="p3-iv5-why-wrap" style="margin-top:8px;display:none"><summary>Решение</summary><div class="spoiler-body">'+t.why+'</div></details>'
|
||||
+'<div class="feedback" id="p3-iv5-fb"></div>';
|
||||
if (window.renderMathInElement) try { renderMathInElement(wrap, {delimiters:[{left:'$',right:'$',display:false}],throwOnError:false}); } catch(e){}
|
||||
document.getElementById('p3-iv5-go').onclick = () => {
|
||||
const v = parseFloat(document.getElementById('p3-iv5-inp').value.replace(',','.'));
|
||||
const fb = document.getElementById('p3-iv5-fb');
|
||||
const wh = document.getElementById('p3-iv5-why-wrap');
|
||||
if (Math.abs(v - t.ans) <= t.tol) {
|
||||
fb.className = 'feedback ok'; fb.innerHTML = 'Верно!'; ok++;
|
||||
document.getElementById('p3-tasks5-ok').textContent = ok;
|
||||
wh.style.display = 'block';
|
||||
} else {
|
||||
fb.className = 'feedback fail'; fb.innerHTML = 'Не совсем. Ожидался $' + t.ans + '$. Загляни в подсказку.';
|
||||
if (window.renderMathInElement) try { renderMathInElement(fb, {delimiters:[{left:'$',right:'$',display:false}],throwOnError:false}); } catch(e){}
|
||||
}
|
||||
};
|
||||
document.getElementById('p3-iv5-hint').onclick = () => {
|
||||
const wh = document.getElementById('p3-iv5-why-wrap');
|
||||
wh.style.display = wh.style.display === 'block' ? 'none' : 'block';
|
||||
};
|
||||
document.getElementById('p3-iv5-next').onclick = () => {
|
||||
i = (i + 1) % TASKS.length;
|
||||
document.getElementById('p3-tasks5-i').textContent = i + 1;
|
||||
render();
|
||||
if (ok === TASKS.length && !awarded) { awarded = true; if (typeof addXp === 'function') addXp(20, 'p3-iv5'); }
|
||||
};
|
||||
}
|
||||
render();
|
||||
}
|
||||
|
||||
function _initP3_sim(){
|
||||
_killSim('p3sim');
|
||||
const svg = document.getElementById('p3-sim'); if(!svg) return;
|
||||
@@ -1647,9 +1797,18 @@ function build_p4(){
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Вопрос: <b id="p4-mcq-i">1</b> / 6</span><span>Правильно: <b id="p4-mcq-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
/* IV5 — Расчётные задачи (auto-injected) */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-5</span><div class="wg-title">Тренажёр: 5 расчётных задач</div></div>'
|
||||
+'<div class="wg-help">Введи числовой ответ (можно с точкой как разделителем). Решено все верно — +20 XP.</div>'
|
||||
+'<div id="p4-tasks5"></div>'
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p4-tasks5-i">1</b> / 5</span><span>Правильно: <b id="p4-tasks5-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
box.innerHTML = h + secNavFor('p4') + readButton('p4');
|
||||
renderMath(box);
|
||||
wireReadBtn('p4');
|
||||
_initp4_iv5();
|
||||
|
||||
_initP4_sim();
|
||||
_initP4_quiz();
|
||||
@@ -1657,6 +1816,47 @@ function build_p4(){
|
||||
_initP4_mcq();
|
||||
}
|
||||
|
||||
function _initp4_iv5(){
|
||||
const TASKS = [{"q":"Плотность тёплого воздуха в $\\rho_1 = 1{,}1$ кг/м³, холодного $\\rho_2 = 1{,}3$ кг/м³. На сколько % холодный плотнее? $((\\rho_2 - \\rho_1)/\\rho_1) \\cdot 100$.","ans":18,"tol":1,"why":"$(1{,}3 - 1{,}1)/1{,}1 \\cdot 100 \\approx 18\\,\\%$."},{"q":"Радиатор отдаёт мощность $P = 1500$ Вт, нагревая воздух массой $m = 50$ кг за $t = 60$ с. На сколько $\\Delta T$ нагрелся воздух? ($c_{возд} = 1000$ Дж/(кг·К))","ans":1.8,"tol":0.1,"why":"$\\Delta T = Q/(cm) = (P\\cdot t)/(cm) = (1500 \\cdot 60)/(1000 \\cdot 50) = 1{,}8$ К."},{"q":"Вода нагревается снизу. Где будет тёплая вода: $a)$ снизу, $b)$ сверху? Введите 2, если сверху, 1, если снизу.","ans":2,"tol":0.1,"why":"Тёплая вода легче — поднимается вверх. Это и есть конвекция."},{"q":"Холодильник остужает $m = 2$ кг воздуха с $T_1 = 25$ до $T_2 = 5\\,^\\circ$C. Какое тепло (в кДж) он унёс? ($c = 1000$)","ans":40,"tol":1,"why":"$Q = cm\\Delta T = 1000 \\cdot 2 \\cdot 20 = 40\\,000$ Дж $= 40$ кДж."},{"q":"Ветер охлаждает кожу. Если без ветра тело отдаёт $P_0 = 50$ Вт, а с ветром $P = 200$ Вт, во сколько раз быстрее идёт теплоотдача?","ans":4,"tol":0.1,"why":"$P/P_0 = 200/50 = 4$ раза."}];
|
||||
let i = 0, ok = 0, awarded = false;
|
||||
function render(){
|
||||
const t = TASKS[i]; const wrap = document.getElementById('p4-tasks5'); if(!wrap) return;
|
||||
wrap.innerHTML =
|
||||
'<div style="padding:10px 14px;background:rgba(15,23,42,.04);border-radius:9px;margin-bottom:10px;font-size:.95rem;line-height:1.55"><b>Задача '+(i+1)+'.</b> '+t.q+'</div>'
|
||||
+'<div class="actions"><input type="number" step="0.001" class="tinp" id="p4-iv5-inp" placeholder="число" style="width:140px">'
|
||||
+'<button class="btn primary" id="p4-iv5-go">Ответ</button>'
|
||||
+'<button class="btn" id="p4-iv5-hint">Подсказка</button>'
|
||||
+'<button class="btn" id="p4-iv5-next">Следующая</button></div>'
|
||||
+'<details class="spoiler" id="p4-iv5-why-wrap" style="margin-top:8px;display:none"><summary>Решение</summary><div class="spoiler-body">'+t.why+'</div></details>'
|
||||
+'<div class="feedback" id="p4-iv5-fb"></div>';
|
||||
if (window.renderMathInElement) try { renderMathInElement(wrap, {delimiters:[{left:'$',right:'$',display:false}],throwOnError:false}); } catch(e){}
|
||||
document.getElementById('p4-iv5-go').onclick = () => {
|
||||
const v = parseFloat(document.getElementById('p4-iv5-inp').value.replace(',','.'));
|
||||
const fb = document.getElementById('p4-iv5-fb');
|
||||
const wh = document.getElementById('p4-iv5-why-wrap');
|
||||
if (Math.abs(v - t.ans) <= t.tol) {
|
||||
fb.className = 'feedback ok'; fb.innerHTML = 'Верно!'; ok++;
|
||||
document.getElementById('p4-tasks5-ok').textContent = ok;
|
||||
wh.style.display = 'block';
|
||||
} else {
|
||||
fb.className = 'feedback fail'; fb.innerHTML = 'Не совсем. Ожидался $' + t.ans + '$. Загляни в подсказку.';
|
||||
if (window.renderMathInElement) try { renderMathInElement(fb, {delimiters:[{left:'$',right:'$',display:false}],throwOnError:false}); } catch(e){}
|
||||
}
|
||||
};
|
||||
document.getElementById('p4-iv5-hint').onclick = () => {
|
||||
const wh = document.getElementById('p4-iv5-why-wrap');
|
||||
wh.style.display = wh.style.display === 'block' ? 'none' : 'block';
|
||||
};
|
||||
document.getElementById('p4-iv5-next').onclick = () => {
|
||||
i = (i + 1) % TASKS.length;
|
||||
document.getElementById('p4-tasks5-i').textContent = i + 1;
|
||||
render();
|
||||
if (ok === TASKS.length && !awarded) { awarded = true; if (typeof addXp === 'function') addXp(20, 'p4-iv5'); }
|
||||
};
|
||||
}
|
||||
render();
|
||||
}
|
||||
|
||||
function _initP4_sim(){
|
||||
_killSim('p4sim');
|
||||
const svg = document.getElementById('p4-sim'); if(!svg) return;
|
||||
@@ -1904,9 +2104,18 @@ function build_p5(){
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Вопрос: <b id="p5-mcq-i">1</b> / 6</span><span>Правильно: <b id="p5-mcq-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
/* IV5 — Расчётные задачи (auto-injected) */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-5</span><div class="wg-title">Тренажёр: 5 расчётных задач</div></div>'
|
||||
+'<div class="wg-help">Введи числовой ответ (можно с точкой как разделителем). Решено все верно — +20 XP.</div>'
|
||||
+'<div id="p5-tasks5"></div>'
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p5-tasks5-i">1</b> / 5</span><span>Правильно: <b id="p5-tasks5-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
box.innerHTML = h + secNavFor('p5') + readButton('p5');
|
||||
renderMath(box);
|
||||
wireReadBtn('p5');
|
||||
_initp5_iv5();
|
||||
|
||||
_initP5_sim();
|
||||
_initP5_quiz();
|
||||
@@ -1914,6 +2123,47 @@ function build_p5(){
|
||||
_initP5_mcq();
|
||||
}
|
||||
|
||||
function _initp5_iv5(){
|
||||
const TASKS = [{"q":"Солнце нагревает квадратный метр земной поверхности с мощностью $P = 1000$ Вт. Сколько теплоты получит $S = 5$ м² за $t = 60$ с?","ans":300000,"tol":5000,"why":"$Q = P \\cdot S \\cdot t = 1000 \\cdot 5 \\cdot 60 = 300\\,000$ Дж = $300$ кДж."},{"q":"Черное тело излучает в 2 раза эффективнее белого. Если белое тело отдаёт $P_1 = 100$ Вт, сколько отдаст чёрное при той же $T$?","ans":200,"tol":5,"why":"$P_{черн} = 2 \\cdot P_{белого} = 2 \\cdot 100 = 200$ Вт."},{"q":"Какая температура (в К) горячей плиты, если её излучение в 16 раз сильнее излучения тела при $T_0 = 300$ К? ($P \\propto T^4$)","ans":600,"tol":10,"why":"$P/P_0 = (T/T_0)^4 = 16$, откуда $T/T_0 = 2$, $T = 600$ К."},{"q":"Какой цвет одежды летом холоднее: белый или чёрный? Введите 1, если чёрный, 2, если белый.","ans":2,"tol":0.1,"why":"Белая отражает солнечное излучение лучше — в ней прохладнее."},{"q":"Тело площадью $S = 0{,}5$ м² излучает $P = 200$ Вт. Найдите интенсивность излучения $I = P/S$ (Вт/м²).","ans":400,"tol":10,"why":"$I = P/S = 200/0{,}5 = 400$ Вт/м²."}];
|
||||
let i = 0, ok = 0, awarded = false;
|
||||
function render(){
|
||||
const t = TASKS[i]; const wrap = document.getElementById('p5-tasks5'); if(!wrap) return;
|
||||
wrap.innerHTML =
|
||||
'<div style="padding:10px 14px;background:rgba(15,23,42,.04);border-radius:9px;margin-bottom:10px;font-size:.95rem;line-height:1.55"><b>Задача '+(i+1)+'.</b> '+t.q+'</div>'
|
||||
+'<div class="actions"><input type="number" step="0.001" class="tinp" id="p5-iv5-inp" placeholder="число" style="width:140px">'
|
||||
+'<button class="btn primary" id="p5-iv5-go">Ответ</button>'
|
||||
+'<button class="btn" id="p5-iv5-hint">Подсказка</button>'
|
||||
+'<button class="btn" id="p5-iv5-next">Следующая</button></div>'
|
||||
+'<details class="spoiler" id="p5-iv5-why-wrap" style="margin-top:8px;display:none"><summary>Решение</summary><div class="spoiler-body">'+t.why+'</div></details>'
|
||||
+'<div class="feedback" id="p5-iv5-fb"></div>';
|
||||
if (window.renderMathInElement) try { renderMathInElement(wrap, {delimiters:[{left:'$',right:'$',display:false}],throwOnError:false}); } catch(e){}
|
||||
document.getElementById('p5-iv5-go').onclick = () => {
|
||||
const v = parseFloat(document.getElementById('p5-iv5-inp').value.replace(',','.'));
|
||||
const fb = document.getElementById('p5-iv5-fb');
|
||||
const wh = document.getElementById('p5-iv5-why-wrap');
|
||||
if (Math.abs(v - t.ans) <= t.tol) {
|
||||
fb.className = 'feedback ok'; fb.innerHTML = 'Верно!'; ok++;
|
||||
document.getElementById('p5-tasks5-ok').textContent = ok;
|
||||
wh.style.display = 'block';
|
||||
} else {
|
||||
fb.className = 'feedback fail'; fb.innerHTML = 'Не совсем. Ожидался $' + t.ans + '$. Загляни в подсказку.';
|
||||
if (window.renderMathInElement) try { renderMathInElement(fb, {delimiters:[{left:'$',right:'$',display:false}],throwOnError:false}); } catch(e){}
|
||||
}
|
||||
};
|
||||
document.getElementById('p5-iv5-hint').onclick = () => {
|
||||
const wh = document.getElementById('p5-iv5-why-wrap');
|
||||
wh.style.display = wh.style.display === 'block' ? 'none' : 'block';
|
||||
};
|
||||
document.getElementById('p5-iv5-next').onclick = () => {
|
||||
i = (i + 1) % TASKS.length;
|
||||
document.getElementById('p5-tasks5-i').textContent = i + 1;
|
||||
render();
|
||||
if (ok === TASKS.length && !awarded) { awarded = true; if (typeof addXp === 'function') addXp(20, 'p5-iv5'); }
|
||||
};
|
||||
}
|
||||
render();
|
||||
}
|
||||
|
||||
function _initP5_sim(){
|
||||
_killSim('p5sim');
|
||||
const svg = document.getElementById('p5-sim'); if(!svg) return;
|
||||
@@ -2635,9 +2885,18 @@ function build_p8(){
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Вопрос: <b id="p8-mcq-i">1</b> / 6</span><span>Правильно: <b id="p8-mcq-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
/* IV5 — Расчётные задачи (auto-injected) */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-5</span><div class="wg-title">Тренажёр: 5 расчётных задач</div></div>'
|
||||
+'<div class="wg-help">Введи числовой ответ (можно с точкой как разделителем). Решено все верно — +20 XP.</div>'
|
||||
+'<div id="p8-tasks5"></div>'
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p8-tasks5-i">1</b> / 5</span><span>Правильно: <b id="p8-tasks5-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
box.innerHTML = h + secNavFor('p8') + readButton('p8');
|
||||
renderMath(box);
|
||||
wireReadBtn('p8');
|
||||
_initp8_iv5();
|
||||
|
||||
_initP8_graph();
|
||||
_initP8_quiz();
|
||||
@@ -2645,6 +2904,47 @@ function build_p8(){
|
||||
_initP8_mcq();
|
||||
}
|
||||
|
||||
function _initp8_iv5(){
|
||||
const TASKS = [{"q":"Сколько теплоты (в кДж) нужно для плавления $m = 2$ кг льда при $0\\,^\\circ$C? ($\\lambda_{льда} = 330$ кДж/кг)","ans":660,"tol":5,"why":"$Q = \\lambda m = 330 \\cdot 2 = 660$ кДж."},{"q":"Какая масса (в кг) свинца расплавится, получив $Q = 50$ кДж? ($\\lambda_{св} = 25$ кДж/кг)","ans":2,"tol":0.1,"why":"$m = Q/\\lambda = 50/25 = 2$ кг."},{"q":"Найдите удельную теплоту плавления вещества (кДж/кг), если на плавление $m = 0{,}5$ кг затрачено $Q = 100$ кДж.","ans":200,"tol":5,"why":"$\\lambda = Q/m = 100/0{,}5 = 200$ кДж/кг."},{"q":"Сколько теплоты (кДж) нужно, чтобы расплавить $m = 5$ кг алюминия при $T_{пл}$? ($\\lambda_{Al} = 380$ кДж/кг)","ans":1900,"tol":20,"why":"$Q = \\lambda m = 380 \\cdot 5 = 1900$ кДж."},{"q":"Лёд массой $m = 1$ кг при $0\\,^\\circ$C сначала нагрели до $t = 0\\,^\\circ$C (не нужно тепла), затем расплавили. Сколько кДж потратили? ($\\lambda = 330$)","ans":330,"tol":3,"why":"$Q = \\lambda m = 330 \\cdot 1 = 330$ кДж — только на плавление."}];
|
||||
let i = 0, ok = 0, awarded = false;
|
||||
function render(){
|
||||
const t = TASKS[i]; const wrap = document.getElementById('p8-tasks5'); if(!wrap) return;
|
||||
wrap.innerHTML =
|
||||
'<div style="padding:10px 14px;background:rgba(15,23,42,.04);border-radius:9px;margin-bottom:10px;font-size:.95rem;line-height:1.55"><b>Задача '+(i+1)+'.</b> '+t.q+'</div>'
|
||||
+'<div class="actions"><input type="number" step="0.001" class="tinp" id="p8-iv5-inp" placeholder="число" style="width:140px">'
|
||||
+'<button class="btn primary" id="p8-iv5-go">Ответ</button>'
|
||||
+'<button class="btn" id="p8-iv5-hint">Подсказка</button>'
|
||||
+'<button class="btn" id="p8-iv5-next">Следующая</button></div>'
|
||||
+'<details class="spoiler" id="p8-iv5-why-wrap" style="margin-top:8px;display:none"><summary>Решение</summary><div class="spoiler-body">'+t.why+'</div></details>'
|
||||
+'<div class="feedback" id="p8-iv5-fb"></div>';
|
||||
if (window.renderMathInElement) try { renderMathInElement(wrap, {delimiters:[{left:'$',right:'$',display:false}],throwOnError:false}); } catch(e){}
|
||||
document.getElementById('p8-iv5-go').onclick = () => {
|
||||
const v = parseFloat(document.getElementById('p8-iv5-inp').value.replace(',','.'));
|
||||
const fb = document.getElementById('p8-iv5-fb');
|
||||
const wh = document.getElementById('p8-iv5-why-wrap');
|
||||
if (Math.abs(v - t.ans) <= t.tol) {
|
||||
fb.className = 'feedback ok'; fb.innerHTML = 'Верно!'; ok++;
|
||||
document.getElementById('p8-tasks5-ok').textContent = ok;
|
||||
wh.style.display = 'block';
|
||||
} else {
|
||||
fb.className = 'feedback fail'; fb.innerHTML = 'Не совсем. Ожидался $' + t.ans + '$. Загляни в подсказку.';
|
||||
if (window.renderMathInElement) try { renderMathInElement(fb, {delimiters:[{left:'$',right:'$',display:false}],throwOnError:false}); } catch(e){}
|
||||
}
|
||||
};
|
||||
document.getElementById('p8-iv5-hint').onclick = () => {
|
||||
const wh = document.getElementById('p8-iv5-why-wrap');
|
||||
wh.style.display = wh.style.display === 'block' ? 'none' : 'block';
|
||||
};
|
||||
document.getElementById('p8-iv5-next').onclick = () => {
|
||||
i = (i + 1) % TASKS.length;
|
||||
document.getElementById('p8-tasks5-i').textContent = i + 1;
|
||||
render();
|
||||
if (ok === TASKS.length && !awarded) { awarded = true; if (typeof addXp === 'function') addXp(20, 'p8-iv5'); }
|
||||
};
|
||||
}
|
||||
render();
|
||||
}
|
||||
|
||||
function _initP8_graph(){
|
||||
const svg = document.getElementById('p8-sim'); if(!svg) return;
|
||||
function draw(){
|
||||
@@ -3060,9 +3360,18 @@ function build_p10(){
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Вопрос: <b id="p10-mcq-i">1</b> / 6</span><span>Правильно: <b id="p10-mcq-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
/* IV5 — Расчётные задачи (auto-injected) */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-5</span><div class="wg-title">Тренажёр: 5 расчётных задач</div></div>'
|
||||
+'<div class="wg-help">Введи числовой ответ (можно с точкой как разделителем). Решено все верно — +20 XP.</div>'
|
||||
+'<div id="p10-tasks5"></div>'
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p10-tasks5-i">1</b> / 5</span><span>Правильно: <b id="p10-tasks5-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
box.innerHTML = h + secNavFor('p10') + readButton('p10');
|
||||
renderMath(box);
|
||||
wireReadBtn('p10');
|
||||
_initp10_iv5();
|
||||
|
||||
_initP10_sim();
|
||||
_initP10_quiz();
|
||||
@@ -3070,6 +3379,47 @@ function build_p10(){
|
||||
_initP10_mcq();
|
||||
}
|
||||
|
||||
function _initp10_iv5(){
|
||||
const TASKS = [{"q":"Сколько теплоты (в кДж) нужно, чтобы испарить $m = 0{,}2$ кг воды при $100\\,^\\circ$C? ($r_{воды} = 2300$ кДж/кг)","ans":460,"tol":5,"why":"$Q = rm = 2300 \\cdot 0{,}2 = 460$ кДж."},{"q":"При испарении $m = 5$ кг этилового спирта поглощено $Q = 4500$ кДж. Найдите $r$ (кДж/кг).","ans":900,"tol":10,"why":"$r = Q/m = 4500/5 = 900$ кДж/кг."},{"q":"Какая масса (в кг) воды испарится, если ей сообщили $Q = 1150$ кДж при $100\\,^\\circ$C? ($r = 2300$)","ans":0.5,"tol":0.02,"why":"$m = Q/r = 1150/2300 = 0{,}5$ кг."},{"q":"Лужа площадью $S = 0{,}5$ м² и толщиной $d = 1$ мм испаряется. Сколько кДж нужно? ($\\rho_{воды} = 1000$ кг/м³, $r = 2300$ кДж/кг)","ans":1.15,"tol":0.05,"why":"$V = Sd = 0{,}5 \\cdot 0{,}001 = 5 \\cdot 10^{-4}$ м³, $m = \\rho V = 0{,}5$ кг $\\cdot 10^{-3} = 0{,}0005$ кг, $Q = rm = 2300 \\cdot 0{,}0005 = 1{,}15$ кДж."},{"q":"Почему пот холодит кожу? При испарении пота поглощается теплота. Если испарилось $m = 100$ г пота ($r \\approx 2400$ кДж/кг), сколько кДж унесено с кожи?","ans":240,"tol":5,"why":"$Q = rm = 2400 \\cdot 0{,}1 = 240$ кДж."}];
|
||||
let i = 0, ok = 0, awarded = false;
|
||||
function render(){
|
||||
const t = TASKS[i]; const wrap = document.getElementById('p10-tasks5'); if(!wrap) return;
|
||||
wrap.innerHTML =
|
||||
'<div style="padding:10px 14px;background:rgba(15,23,42,.04);border-radius:9px;margin-bottom:10px;font-size:.95rem;line-height:1.55"><b>Задача '+(i+1)+'.</b> '+t.q+'</div>'
|
||||
+'<div class="actions"><input type="number" step="0.001" class="tinp" id="p10-iv5-inp" placeholder="число" style="width:140px">'
|
||||
+'<button class="btn primary" id="p10-iv5-go">Ответ</button>'
|
||||
+'<button class="btn" id="p10-iv5-hint">Подсказка</button>'
|
||||
+'<button class="btn" id="p10-iv5-next">Следующая</button></div>'
|
||||
+'<details class="spoiler" id="p10-iv5-why-wrap" style="margin-top:8px;display:none"><summary>Решение</summary><div class="spoiler-body">'+t.why+'</div></details>'
|
||||
+'<div class="feedback" id="p10-iv5-fb"></div>';
|
||||
if (window.renderMathInElement) try { renderMathInElement(wrap, {delimiters:[{left:'$',right:'$',display:false}],throwOnError:false}); } catch(e){}
|
||||
document.getElementById('p10-iv5-go').onclick = () => {
|
||||
const v = parseFloat(document.getElementById('p10-iv5-inp').value.replace(',','.'));
|
||||
const fb = document.getElementById('p10-iv5-fb');
|
||||
const wh = document.getElementById('p10-iv5-why-wrap');
|
||||
if (Math.abs(v - t.ans) <= t.tol) {
|
||||
fb.className = 'feedback ok'; fb.innerHTML = 'Верно!'; ok++;
|
||||
document.getElementById('p10-tasks5-ok').textContent = ok;
|
||||
wh.style.display = 'block';
|
||||
} else {
|
||||
fb.className = 'feedback fail'; fb.innerHTML = 'Не совсем. Ожидался $' + t.ans + '$. Загляни в подсказку.';
|
||||
if (window.renderMathInElement) try { renderMathInElement(fb, {delimiters:[{left:'$',right:'$',display:false}],throwOnError:false}); } catch(e){}
|
||||
}
|
||||
};
|
||||
document.getElementById('p10-iv5-hint').onclick = () => {
|
||||
const wh = document.getElementById('p10-iv5-why-wrap');
|
||||
wh.style.display = wh.style.display === 'block' ? 'none' : 'block';
|
||||
};
|
||||
document.getElementById('p10-iv5-next').onclick = () => {
|
||||
i = (i + 1) % TASKS.length;
|
||||
document.getElementById('p10-tasks5-i').textContent = i + 1;
|
||||
render();
|
||||
if (ok === TASKS.length && !awarded) { awarded = true; if (typeof addXp === 'function') addXp(20, 'p10-iv5'); }
|
||||
};
|
||||
}
|
||||
render();
|
||||
}
|
||||
|
||||
function _initP10_sim(){
|
||||
_killSim('p10sim');
|
||||
const svg = document.getElementById('p10-sim'); if(!svg) return;
|
||||
|
||||
Reference in New Issue
Block a user