import React, { useState, useEffect } from 'react';
// ==========================================
// 1. 题目数据定义 (精选5年级典型异分母加减法应用题)
// ==========================================
const PROBLEMS = [
{
id: 1,
title: "量子燃料调配 (减法 - 同分母/简单通分)",
story: "【航行日志】领航员报告:飞船起飞时携带了 5/6 吨的量子燃料。在穿越小行星带时,副推进器消耗了 1/3 吨。目前动力舱还剩多少吨燃料?",
question: "计算:\\frac{5}{6} - \\frac{1}{3}",
num1: 5,
den1: 6,
operator: '-',
num2: 1,
den2: 3,
lcd: 6, // 最小公分母
step2Num1: 5,
step2Num2: 2,
resultNum: 3,
resultDen: 6,
simplifiedNum: 1,
simplifiedDen: 2,
needSimplify: true,
componentName: "量子燃料泵",
componentIcon: "⚡",
hint: "提示:分母 6 和 3 的最小公倍数是 6。请把 1/3 的分子分母同时乘以 2,化为分母是 6 的分数再进行减法!"
},
{
id: 2,
title: "星云能量采集 (加法 - 互质分母通分)",
story: "【能量监控】飞船正在采集星云物质。1号采集器收集了 1/4 吨星云结晶,2号采集器收集了 2/5 吨。两台采集器一共收集了多少吨结晶?",
question: "计算:\\frac{1}{4} + \\frac{2}{5}",
num1: 1,
den1: 4,
operator: '+',
num2: 2,
den2: 5,
lcd: 20,
step2Num1: 5,
step2Num2: 8,
resultNum: 13,
resultDen: 20,
simplifiedNum: 13,
simplifiedDen: 20,
needSimplify: false,
componentName: "星云收集器",
componentIcon: "🛸",
hint: "提示:分母 4 和 5 是互质数,它们的最小公分母是 4 × 5 = 20。将两分数分别通分后再相加!"
},
{
id: 3,
title: "超空间航线规划 (减法 - 倍数关系通分)",
story: "【航线警报】导航计算机规划了 7/10 光年的曲率航线。飞船刚刚越过了空间跃迁点,已行驶 2/5 光年。前方还有多少光年的航程?",
question: "计算:\\frac{7}{10} - \\frac{2}{5}",
num1: 7,
den1: 10,
operator: '-',
num2: 2,
den2: 5,
lcd: 10,
step2Num1: 7,
step2Num2: 4,
resultNum: 3,
resultDen: 10,
simplifiedNum: 3,
simplifiedDen: 10,
needSimplify: false,
componentName: "曲率跃迁引擎",
componentIcon: "🌀",
hint: "提示:分母 10 是 5 的倍数,因此最小公分母就是 10。只需要把 2/5 的分子和分母同时乘以 2 即可通分。"
},
{
id: 4,
title: "太空厨房配给 (加法 - 常用分母计算)",
story: "【后勤保障】宇航员正在准备太空晚餐。制作蔬菜沙拉需要 1/2 千克水培生菜,制作高能能量棒需要 3/8 千克大豆蛋白。一共需要准备多少千克的原料?",
question: "计算:\\frac{1}{2} + \\frac{3}{8}",
num1: 1,
den1: 2,
operator: '+',
num2: 3,
den2: 8,
lcd: 8,
step2Num1: 4,
step2Num2: 3,
resultNum: 7,
resultDen: 8,
simplifiedNum: 7,
simplifiedDen: 8,
needSimplify: false,
componentName: "重力厨房炉心",
componentIcon: "🍳",
hint: "提示:分母 2 和 8 具有倍数关系,最小公分母是 8。把 1/2 化成分母为 8 的分数,分子分母同乘以 4。"
},
{
id: 5,
title: "防护盾能量加固 (减法 - 一般合数通分)",
story: "【主控防卫】遭遇陨石碎屑冲击,主能量盾原本有 5/6 的完整度,破损消耗了 1/4。现在的防护盾能量值还剩多少?",
question: "计算:\\frac{5}{6} - \\frac{1}{4}",
num1: 5,
den1: 6,
operator: '-',
num2: 1,
den2: 4,
lcd: 12,
step2Num1: 10,
step2Num2: 3,
resultNum: 7,
resultDen: 12,
simplifiedNum: 7,
simplifiedDen: 12,
needSimplify: false,
componentName: "脉冲防护力场",
componentIcon: "🛡️",
hint: "提示:分母 6 和 4 的最小公倍数是 12(可以通过列举 6,12... 和 4,8,12... 找到)。两分数通分到分母为 12 即可计算。"
}
];
export default function App() {
// ==========================================
// 2. 状态定义
// ==========================================
const [gameState, setGameState] = useState('intro'); // intro | map | solve | victory
const [activeIdx, setActiveIdx] = useState(0);
const [unlocked, setUnlocked] = useState([false, false, false, false, false]);
// 步骤导学状态 (1: 输入公分母, 2: 输入通分分子, 3: 输入初步结果, 4: 化简/确认最终结果)
const [step, setStep] = useState(1);
const [showHint, setShowHint] = useState(false);
const [feedback, setFeedback] = useState({ text: '', isError: false });
// 用户答题输入存储
const [inputLcd, setInputLcd] = useState('');
const [inputNum1, setInputNum1] = useState('');
const [inputNum2, setInputNum2] = useState('');
const [inputResultNum, setInputResultNum] = useState('');
const [inputFinalNum, setInputFinalNum] = useState('');
const [inputFinalDen, setInputFinalDen] = useState('');
const currentProblem = PROBLEMS[activeIdx];
// ==========================================
// 3. 辅助计算与逻辑校验
// ==========================================
const startMission = () => {
setGameState('map');
};
const selectSector = (index) => {
setActiveIdx(index);
setStep(1);
clearInputs();
setShowHint(false);
setFeedback({ text: '', isError: false });
setGameState('solve');
};
const clearInputs = () => {
setInputLcd('');
setInputNum1('');
setInputNum2('');
setInputResultNum('');
setInputFinalNum('');
setInputFinalDen('');
};
// 验证第一步:最小公分母
const handleVerifyStep1 = () => {
const val = parseInt(inputLcd.trim());
if (isNaN(val)) {
setFeedback({ text: "⚠️ 领航员,请输入数值作为公分母!", isError: true });
return;
}
if (val === currentProblem.lcd) {
setFeedback({ text: "✨ 完美锁定公分母!跃迁通道已对齐,请开始量子通分转换。", isError: false });
setStep(2);
} else if (val % currentProblem.den1 === 0 && val % currentProblem.den2 === 0) {
// 输了公倍数但不是最小公倍数
setFeedback({ text: `💡 找到了公倍数 ${val},但为了计算更简便,请寻找分母 ${currentProblem.den1} 和 ${currentProblem.den2} 的【最小】公倍数哦!`, isError: true });
} else {
setFeedback({ text: `❌ 公分母不对哦。提示:它需要同时是 ${currentProblem.den1} 和 ${currentProblem.den2} 的倍数。`, isError: true });
}
};
// 验证第二步:通分后的分子
const handleVerifyStep2 = () => {
const n1 = parseInt(inputNum1.trim());
const n2 = parseInt(inputNum2.trim());
if (isNaN(n1) || isNaN(n2)) {
setFeedback({ text: "⚠️ 仪表盘数据未填满,请输入通分后的两个新分子!", isError: true });
return;
}
if (n1 === currentProblem.step2Num1 && n2 === currentProblem.step2Num2) {
setFeedback({ text: "✨ 通分完全正确!分子能量已校准。现在可以执行分子加减运算了。", isError: false });
setStep(3);
} else {
setFeedback({ text: `❌ 分子校准失败。分母扩大了多少倍,分子也要扩大相同的倍数哦!再检查一下。`, isError: true });
}
};
// 验证第三步:初步相加减结果
const handleVerifyStep3 = () => {
const rNum = parseInt(inputResultNum.trim());
if (isNaN(rNum)) {
setFeedback({ text: "⚠️ 请输入计算得出的分子结果!", isError: true });
return;
}
if (rNum === currentProblem.resultNum) {
if (currentProblem.needSimplify) {
setFeedback({ text: "✨ 运算成功!不过,这个分数好像还可以通过【约分】化为最简分数。试着化简它!", isError: false });
setStep(4);
} else {
// 不需要化简,直接通关
handleProblemComplete();
}
} else {
const correctOp = currentProblem.operator === '+' ? "相加" : "相减";
setFeedback({ text: `❌ 结果分子不正确。请将通分后的两个新分子进行${correctOp} (${currentProblem.step2Num1} ${currentProblem.operator} ${currentProblem.step2Num2})。`, isError: true });
}
};
// 验证第四步:最简分数化简
const handleVerifyStep4 = () => {
const fNum = parseInt(inputFinalNum.trim());
const fDen = parseInt(inputFinalDen.trim());
if (isNaN(fNum) || isNaN(fDen)) {
setFeedback({ text: "⚠️ 请输入最简分数的分子和分母!", isError: true });
return;
}
if (fNum === currentProblem.simplifiedNum && fDen === currentProblem.simplifiedDen) {
handleProblemComplete();
} else {
setFeedback({ text: "❌ 化简结果未对齐。请找出分子和分母的最大公因数,同时除以它来进行约分!", isError: true });
}
};
// 单题完全通关处理
const handleProblemComplete = () => {
const updatedUnlocked = [...unlocked];
updatedUnlocked[activeIdx] = true;
setUnlocked(updatedUnlocked);
// 检查是否全部解锁成功
const allDone = updatedUnlocked.every(status => status === true);
setFeedback({
text: `🎉 太棒了!成功修复并充能【${currentProblem.componentName}】!核心引擎能量+20%!`,
isError: false
});
setTimeout(() => {
if (allDone) {
setGameState('victory');
} else {
setGameState('map');
}
}, 2800);
};
// 检查是否全通关
const isAllUnlocked = unlocked.every(status => status === true);
return (
{/* 炫酷背景星空特效与网格 */}
{/* ==========================================
页头 HEADER (所有界面共享)
========================================== */}
{/* ==========================================
主要内容区 - 状态分发
========================================== */}
{/* ------------------------------------------
A) 引导介绍界面 (Intro)
------------------------------------------ */}
{gameState === 'intro' && (
MISSION BRIEFING / 任务简报
拯救“逐星号”探索船
星历 2026 年,逐星号飞船穿过微陨石带,主引擎受损,5大动力核心部件悉数离线。
我们需要利用您的【异分母分数加减法】超强计算力,重新激活各大控制阀门。每修复一个部件,飞船引擎完整度将回升 20%。
{/* 炫酷的收集预览列表 */}
🚀 待锁定的引擎组件:
{PROBLEMS.map((p, idx) => (
{p.componentIcon}
{p.componentName}
))}
)}
{/* ------------------------------------------
B) 关卡选择地图界面 (Map)
------------------------------------------ */}
{gameState === 'map' && (
逐星号 · 核心状态终端
选择故障舱区,启动分步逻辑通分修复
{/* 飞船状态舱位平面图示意 (SVG 精准绘制) */}
{/* 科技感线框飞船 */}
{/* 飞船中央HUD光圈 */}
{/* 引擎总体能量条 */}
REACTOR CORE (反应堆输出功率)
{unlocked.filter(Boolean).length * 20}%
{/* 关卡列表卡片组 */}
{PROBLEMS.map((prob, idx) => {
const isFinished = unlocked[idx];
return (
);
})}
{/* 隐藏大招:全解锁后的发射选项 */}
{isAllUnlocked && (
)}
)}
{/* ------------------------------------------
C) 核心解题交互界面 (Solve)
------------------------------------------ */}
{gameState === 'solve' && (
{/* 返回按键与当前进度 */}
部件修复任务 {activeIdx + 1}/5
{/* 情境应用题面板 */}
{currentProblem.title}
{currentProblem.story}
{/* 核心数学物理模型展示:将文字题,抽象成美观的分数计算式 */}
待解决算式:
{/* 分数 1 */}
{currentProblem.num1}
{currentProblem.den1}
{/* 运算符 */}
{currentProblem.operator}
{/* 分数 2 */}
{currentProblem.num2}
{currentProblem.den2}
=
?
{/* ==================== 独创分步通分卡片 ==================== */}
{/* 步骤导航条 */}
{[1, 2, 3, 4].map((s) => {
if (s === 4 && !currentProblem.needSimplify) return null; // 不需要化简则隐去第4步
return (
s ? 'bg-emerald-500' : step === s ? 'bg-cyan-500 animate-pulse' : 'bg-slate-800'
}`}>
{s === 1 && "1.找公分母"}
{s === 2 && "2.分子通分"}
{s === 3 && "3.求和/差"}
{s === 4 && "4.约分最简"}
);
})}
{/* ----------------- 步骤1:输入公分母 ----------------- */}
{step === 1 && (
)}
{/* ----------------- 步骤2:输入通分后的分子 ----------------- */}
{step === 2 && (
2
第二步:飞船大脑通分校准
现在分母已统一转换为 {currentProblem.lcd}。请计算通分后的新分子:
{/* 全息分数框通分形态 */}
{/* 分数 1 变换 */}
{currentProblem.operator}
{/* 分数 2 变换 */}
)}
{/* ----------------- 步骤3:计算求和差结果 ----------------- */}
{step === 3 && (
3
第三步:同分母分子相加减
分母已相同!请执行分子的 {currentProblem.operator === '+' ? '加法' : '减法'}:即计算 {currentProblem.step2Num1} {currentProblem.operator} {currentProblem.step2Num2} 得出合并分子:
{currentProblem.step2Num1} {currentProblem.operator} {currentProblem.step2Num2}
{currentProblem.lcd}
=
{/* 用户输入合成的分数结果 */}
setInputResultNum(e.target.value)}
placeholder="?"
className="w-14 bg-slate-950 border border-cyan-500/40 rounded px-1 text-center text-base font-bold text-cyan-400 focus:outline-none focus:border-cyan-400"
/>
{currentProblem.lcd}
)}
{/* ----------------- 步骤4:化简分数 ----------------- */}
{step === 4 && (
4
第四步:量子晶格压缩 (约分为最简分数)
检测到当前结果 {currentProblem.resultNum}/{currentProblem.resultDen} 并非最简形式。请通过求分子与分母的最大公因数来进行最简转换:
)}
{/* 实时系统报告反馈 (取代传统的 Alert) */}
{feedback.text && (
{feedback.isError ? "🚨 诊断错误:" : "📡 测控反馈:"}
{feedback.text}
)}
{/* 辅助折纸条/可视化帮助提示 (帮助理解通分本质) */}
{showHint && (
{currentProblem.hint}
{/* 分数格动态可视化示意 (分数条分割) */}
第一数: {currentProblem.num1}/{currentProblem.den1}
分割为 {currentProblem.lcd} 等份
{/* 简易分割块示意 */}
{Array.from({ length: currentProblem.lcd }).map((_, i) => {
const ratio = currentProblem.lcd / currentProblem.den1;
const isFilled = i < currentProblem.num1 * ratio;
return (
);
})}
第二数: {currentProblem.num2}/{currentProblem.den2}
分割为 {currentProblem.lcd} 等份
{Array.from({ length: currentProblem.lcd }).map((_, i) => {
const ratio = currentProblem.lcd / currentProblem.den2;
const isFilled = i < currentProblem.num2 * ratio;
return (
);
})}
)}
)}
{/* ------------------------------------------
D) 最终胜利欢庆界面 (Victory)
------------------------------------------ */}
{gameState === 'victory' && (
SYSTEM FULLY OPERATIONAL / 飞船状态满载
星空浩瀚,即刻启航!
恭喜你,最强心算领航员!你通过了全部 5 道关卡的量子逻辑校验,成功为“逐星号”的 5 大引擎核心注入了平衡的分数能量!
{/* 炫酷的属性结算面板 */}
🛰️ 任务结算数据库 (Log)
STATUS: COMPLETE
-
• 异分母通分解析数:
100% 对齐成功
-
• 最大公因数极简压缩:
顺利匹配
-
• 拯救探索船等级:
💎 五星统帅
)}
{/* ==========================================
页脚 FOOTER (版权与鼓励说明)
========================================== */}
{/* 极简自定义 CSS 动画 (解决过渡与入场动效) */}
);
}