feat(js): m10 extensions (pause, restart, speed-up via Frame) with tests

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Lucas Winther
2026-10-28 23:56:49 +01:00
co-authored by Claude Sonnet 5.5
parent 25141ce86d
commit fd7c5f2acf
13 changed files with 1347 additions and 17 deletions
+21 -2
View File
@@ -1,12 +1,31 @@
// m05 game: one `update` function turns every action into a new state; replay is a fold over actions.
// m10 adds pause, restart and a frame clock that speeds up as the score grows.
import { turn } from './rules.js'
import { tick } from './spawn.js'
import { tick, newGame } from './spawn.js'
/** How many frames pass between game steps: 8 at first, one fewer every 3 points, never fewer than 2. */
export const movesEvery = (score) => Math.max(2, 8 - Math.floor(score / 3))
// One animation frame: count it, and every `movesEvery(score)`-th frame run a game step.
const frame = (state) => {
if (state.status !== 'Playing') return state
const counted = { ...state, frame: state.frame + 1 }
return counted.frame % movesEvery(counted.score) === 0 ? tick(counted) : counted
}
// Pause and resume only make sense in those two statuses; a finished game stays finished.
const togglePause = (state) =>
state.status === 'Playing' ? { ...state, status: 'Paused' }
: state.status === 'Paused' ? { ...state, status: 'Playing' }
: state
/** Tick and Turn are handled here; other actions leave the state alone (m10 adds more). */
export const update = (state, action) => {
switch (action.tag) {
case 'Tick': return tick(state)
case 'Turn': return turn(state, action.dir)
case 'TogglePause': return togglePause(state)
case 'Restart': return newGame(state.seed)
case 'Frame': return frame(state)
default: return state
}
}