/** * 关卡配置:面向 45+ 的认知练习,节奏放慢、无失败惩罚。 * 每组目标只比上一组略增,步数充裕(仅展示,不会因耗尽判负)。 */ /** * 指定关卡固定食材(按 key)。未配置的关卡走随机抽取逻辑。 * 第一关固定为这 16 种带真实图片素材的食物。 */ const FIXED_LEVEL_FOODS = { 1: [ 'sandwich', 'eightTreasureCongee', 'milkOats', 'milletCongee', 'shandongPancake', 'grainMantou', 'riceNoodleSoup', 'youtiao', 'friedNoodles', 'sweetPotato', 'centuryEggCongee', 'whiteRice', 'cake', 'biscuit', 'wonton', 'blackCoffee' ] } export function getLevelConfig(levelId) { const lv = Math.max(1, Math.min(999, Number(levelId) || 1)) const tier = Math.floor((lv - 1) / 5) return { id: lv, // 步数充裕:仅作展示,认全目标即可通关 moves: Math.max(40, 60 - tier * 2), // 认识目标平缓增长,避免给老人压力 goalTargets: [6 + tier, 8 + tier], scoreTarget: 2000 + lv * 300, startGlucose: 50, // 固定食材(可选):存在时本关只用这些食物 foods: FIXED_LEVEL_FOODS[lv] || null, boosters: { insulin: 3, fiber: 1, meal: 5 } } } /** 根据本局表现计算 1~3 星:完成即得星,步数越省星越多(不依赖血糖) */ export function calcLevelStars({ movesLeft, levelConfig }) { const totalMoves = levelConfig?.moves || 1 const ratio = totalMoves > 0 ? movesLeft / totalMoves : 0 let stars = 1 if (ratio >= 0.3) stars = 2 if (ratio >= 0.55) stars = 3 return stars }