Files
SoundGame/web/harness/sessions/simon.mjs
T

108 lines
5.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 《音序回响》新手会话剧本:教学六音一步一步学(中间故意做错一次听纠错)、
* 收尾听完机会经济句(round3 G5 重录口径:记不住就向上滑重新听);第 1 轮
* 直接答对(途中有双击音就演示「双击=作答」);第 2 轮开局忘序列僵住 10 秒,
* 听到向导「向上滑可以重新听」提示后照做——用掉一次免费重听(round3 G5:
* input 双击永远=作答,重听改绑上滑);第 3 轮凭记忆答对,在**整轮边界**收工
* (round2 剧本修正:不在轮中退出)。
*/
export function describe(game) {
const GN = { up: '上滑', down: '下滑', left: '左滑', right: '右滑', tap: '单击', doubletap: '双击' };
const GESTURES = ['up', 'down', 'left', 'right', 'tap', 'doubletap'];
switch (game.phase) {
case 'tutorial':
return game.teachAwait
? `教学:该做「${GN[GESTURES[game.teachIdx]]}」了`
: '教学旁白在播,先听着';
case 'announce': return `第 ${game.round} 轮报数呢,听好了`;
case 'playback': return `第 ${game.round} 轮序列演奏中(${game.sequence.length} 个音),记住顺序,先别动手`;
case 'input': return `第 ${game.round} 轮轮到你了:已对上 ${game.inputIdx}/${game.sequence.length},照原顺序做手势(双击就是双击那个音,要重听就向上滑)`;
case 'roundend': return '刚答完一轮,播报中';
case 'gameover': return `游戏结束,完成 ${game.round - 1} 轮。单击再来一局,下滑开菜单`;
case 'menu': return '菜单里:单击切选项,双击确认,上滑听规则';
default: return '开场,稍等一下';
}
}
export async function session(ctx, mock) {
const { game } = ctx;
const G = ['up', 'down', 'left', 'right', 'tap', 'doubletap'];
// 教学 T0-T6:教一个练一个
for (let i = 0; i < G.length; i++) {
await ctx.waitCond(() => game.phase === 'tutorial' && game.teachAwait);
ctx.status(`教学第 ${i + 1}/6 个音色`);
if (i === 2) {
ctx.note('把「左滑」记混了,先来了个右滑');
await ctx.gesture('right'); // 听纠错语音(t_wrong_left)
await ctx.waitCond(() => game.phase === 'tutorial' && game.teachAwait);
}
await ctx.gesture(G[i]); // 照指令做对
if (i === G.length - 1) {
// 收尾链(t7 两句 + 机会经济句)播完直达对局——一到 input 就接手,
// 不裸 waitIdle(会把 input 的看门狗窗口整段空烧掉,round1 剧本失真根源)
await ctx.waitCond(() => game.phase === 'playback' || game.phase === 'input'
|| game.phase === 'gameover');
} else {
await ctx.waitIdle();
}
}
ctx.status('教学讲完了:免费重听两次、用完扣机会,想重听就向上滑');
// 正式对局:完整打完第 3 轮,在轮边界收工
let relistenDone = false;
while (mock.now < 12 * 60 * 1000 && game.phase !== 'gameover') {
if (game.phase === 'input') {
// 第 1 轮开局先失忆僵 10 秒(还没动过手,input 看门狗在挂):听向导
// 「向上滑可以重新听一遍序列」,照做——round3 G5:重听已改绑上滑。
// 测试钩子把序列摆成无 up 的两音,保证上滑=重听不被「期望恰为 up」豁免干扰。
if (game.round === 1 && !relistenDone && game.inputIdx === 0) {
relistenDone = true;
if (game.sequence.includes('up')) { game.sequence[0] = 'left'; game.sequence[1] = 'tap'; }
ctx.status('第 1 轮有点懵,先僵一会儿');
ctx.silence(10, '想不起来序列了');
// 10s 看门狗到点:nudge + gd_relisten。直接等提示语音开播(input 态无
// BGM、无别的语音,voiceBusy=提示在播;别用「等满 10.6s」——定时刻度会
// 恰好迈过语音结束点,等成第二次升级)
await ctx.waitCond(() => ctx.voiceBusy());
ctx.status('听到提示:需要的话,向上滑可以重新听一遍序列');
ctx.note('照提示向上滑,用掉一次免费重听');
await ctx.gesture('up');
await ctx.waitCond(() => game.phase === 'playback' || game.phase === 'input');
continue;
}
// 第 2 轮开头演示「期望恰为 up 时上滑=作答」(00 §5.3 豁免同款口径)
if (game.round === 2 && !game.__upDemoDone && game.inputIdx === 0) {
game.__upDemoDone = true;
game.sequence[0] = 'up';
ctx.status('这个是上行音——上滑作答(期望恰为 up 时上滑=作答)');
await ctx.gesture('up');
continue;
}
if (game.round === 3 && game.inputIdx === game.sequence.length - 1) {
// round3 G5 演示钩子(13 号文档允许直读/改实例字段):把最后一个期望音
// 摆成 doubletap,保证转写演示到「input 双击永远=作答」
if (game.sequence[game.inputIdx] !== 'doubletap' && !game.__dtDemoDone) {
game.__dtDemoDone = true;
game.sequence[game.inputIdx] = 'doubletap';
}
ctx.status(game.sequence[game.inputIdx] === 'doubletap'
? '这个是双击音——双击作答(round3:input 双击永远=作答)'
: '最后一轮最后一个音,打完这轮就收');
} else {
ctx.status('轮到我复现了');
}
await ctx.gesture(game.sequence[game.inputIdx]);
continue;
}
// 整轮边界收尾:第 3 轮答完(roundend),不等第 4 轮报数
if (game.phase === 'roundend' && game.round === 3) break;
// announce/playback/roundend:等阶段推进即可,不裸 waitIdle(防吞掉 input 窗口)
const ph = game.phase;
const r = game.round;
await ctx.waitCond(() => game.phase !== ph || game.round !== r);
}
ctx.status(`收工:完整打完 ${game.round} 轮,在轮与轮的边界停手(免费重听剩 ${game.chances} 次)`);
}