// m06 view: the picture is plain data (a list of shapes); drawing it is somebody else's job (m07). /** Pixels per board cell. */ export const CELL = 20 const rect = (x, y, w, h, color) => ({ tag: 'Rect', x, y, w, h, color }) const text = (x, y, str, size, align) => ({ tag: 'Text', x, y, text: str, color: '#ffffff', size, align }) // One cell, inset by 1px so neighbouring segments show a gap. const cell = (p, color) => rect(p.x * CELL + 1, p.y * CELL + 1, CELL - 2, CELL - 2, color) const overlay = (state) => { const cx = (state.width * CELL) / 2 const cy = (state.height * CELL) / 2 const banner = (title, hint) => [text(cx, cy, title, 32, 'center'), text(cx, cy + 30, hint, 16, 'center')] switch (state.status) { case 'Paused': return banner('Paused', 'Press Space to resume') case 'GameOver': return banner('Game Over', 'Press R to restart') case 'Won': return banner('You Win!', 'Press R to restart') default: return [] } } export const view = (state) => [ rect(0, 0, state.width * CELL, state.height * CELL, '#111111'), ...(state.apple === null ? [] : [cell(state.apple, '#e53935')]), ...state.snake.map((p, i) => cell(p, i === 0 ? '#7cb342' : '#43a047')), text(6, 18, `Score: ${state.score}`, 16, 'left'), ...overlay(state), ]