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 (所有界面共享) ========================================== */}

星际航行:分数轨道

5年级异分母加减法专项

核心完整度: {unlocked.filter(Boolean).length * 20}%
{/* ========================================== 主要内容区 - 状态分发 ========================================== */}
{/* ------------------------------------------ A) 引导介绍界面 (Intro) ------------------------------------------ */} {gameState === 'intro' && (
{/* 飞船科技感框 */}
🚀
MISSION BRIEFING / 任务简报

拯救“逐星号”探索船

星历 2026 年,逐星号飞船穿过微陨石带,主引擎受损,5大动力核心部件悉数离线。

我们需要利用您的【异分母分数加减法】超强计算力,重新激活各大控制阀门。每修复一个部件,飞船引擎完整度将回升 20%。

{/* 炫酷的收集预览列表 */}

🚀 待锁定的引擎组件:

{PROBLEMS.map((p, idx) => (
{p.componentIcon} {p.componentName}
))}
)} {/* ------------------------------------------ B) 关卡选择地图界面 (Map) ------------------------------------------ */} {gameState === 'map' && (

逐星号 · 核心状态终端

选择故障舱区,启动分步逻辑通分修复

{/* 飞船状态舱位平面图示意 (SVG 精准绘制) */}
{/* 科技感线框飞船 */} {/* 点亮已解锁的喷气动画 */} {isAllUnlocked && ( )} {/* 飞船中央HUD光圈 */}
DIAGNOSTICS
{/* 引擎总体能量条 */}
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 && (
1 第一步:锁定最小公分母

请观察分母 {currentProblem.den1}{currentProblem.den2},它们最小的公共倍数是多少?

setInputLcd(e.target.value)} placeholder="输入两个分母的最小公倍数" className="w-full bg-slate-950 border border-slate-700 rounded-lg px-3 py-2 text-sm font-mono text-cyan-400 focus:outline-none focus:border-cyan-400 text-center" />
)} {/* ----------------- 步骤2:输入通分后的分子 ----------------- */} {step === 2 && (
2 第二步:飞船大脑通分校准

现在分母已统一转换为 {currentProblem.lcd}。请计算通分后的新分子:

{/* 全息分数框通分形态 */}
{/* 分数 1 变换 */}
原: {currentProblem.num1}/{currentProblem.den1} setInputNum1(e.target.value)} placeholder="新分子" className="w-14 bg-slate-900 border border-cyan-500/40 rounded px-1.5 py-1 text-center text-sm font-bold text-cyan-400 focus:outline-none focus:border-cyan-400" /> {currentProblem.lcd}
{currentProblem.operator} {/* 分数 2 变换 */}
原: {currentProblem.num2}/{currentProblem.den2} setInputNum2(e.target.value)} placeholder="新分子" className="w-14 bg-slate-900 border border-cyan-500/40 rounded px-1.5 py-1 text-center text-sm font-bold text-cyan-400 focus:outline-none focus:border-cyan-400" /> {currentProblem.lcd}
)} {/* ----------------- 步骤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} 并非最简形式。请通过求分子与分母的最大公因数来进行最简转换:

{currentProblem.resultNum} {currentProblem.resultDen}
约分→ {/* 最终化简结果输入 */}
setInputFinalNum(e.target.value)} placeholder="最简分子" className="w-16 bg-slate-950 border border-slate-700 rounded px-1.5 py-1 text-center text-sm font-bold text-cyan-400 focus:outline-none focus:border-cyan-400" /> setInputFinalDen(e.target.value)} placeholder="最简分母" className="w-16 bg-slate-950 border border-slate-700 rounded px-1.5 py-1 text-center text-sm font-bold text-cyan-400 focus:outline-none focus:border-cyan-400" />
)} {/* 实时系统报告反馈 (取代传统的 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 动画 (解决过渡与入场动效) */}
); }