export type ClockConnectTimeMode = | 'random' | 'whole-hour' | 'half-hour' | 'quarter-hour'; export interface ClockConnectProblem { hour: number; minute: number; /** 格式化后的时间文本,如 "6:00" */ timeText: string; } export interface ClockConnectData { /** 左侧钟表列表(按原始顺序) */ clocks: ClockConnectProblem[]; /** 右侧时间文本列表(打乱顺序) */ shuffledTimes: ClockConnectProblem[]; timeMode: ClockConnectTimeMode; } export const CLOCK_CONNECT_PROBLEM_COUNT = 6; const MINUTES_BY_MODE: Record< Exclude, readonly number[] > = { 'whole-hour': [0], 'half-hour': [30], 'quarter-hour': [15, 45], }; function pickMinute(timeMode: ClockConnectTimeMode): number { if (timeMode === 'random') { const options = [0, 15, 30, 45]; return options[Math.floor(Math.random() * options.length)]; } const pool = MINUTES_BY_MODE[timeMode]; return pool[Math.floor(Math.random() * pool.length)] ?? 0; } function formatTime(hour: number, minute: number): string { return `${hour}:${minute.toString().padStart(2, '0')}`; } /** Fisher-Yates shuffle */ function shuffle(arr: T[]): T[] { const result = [...arr]; for (let i = result.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [result[i], result[j]] = [result[j], result[i]]; } return result; } /** 生成一页 6 道时钟连线题,同一页内时刻不重复 */ export function generateClockConnectProblems( timeMode: ClockConnectTimeMode, ): ClockConnectProblem[] { const used = new Set(); const problems: ClockConnectProblem[] = []; let guard = 0; while (problems.length < CLOCK_CONNECT_PROBLEM_COUNT && guard < 500) { guard += 1; const hour = Math.floor(Math.random() * 12) + 1; const minute = pickMinute(timeMode); const key = `${hour}:${minute}`; if (used.has(key)) continue; used.add(key); problems.push({ hour, minute, timeText: formatTime(hour, minute) }); } return problems; } export function buildClockConnectData( timeMode: ClockConnectTimeMode, ): ClockConnectData { const clocks = generateClockConnectProblems(timeMode); const shuffledTimes = shuffle(clocks); return { timeMode, clocks, shuffledTimes, }; } export const CLOCK_CONNECT_TIME_MODE_OPTIONS = [ { id: 'whole-hour' as const, label: '整点', subtitle: '如 3:00' }, { id: 'half-hour' as const, label: '半点', subtitle: '如 6:30' }, { id: 'quarter-hour' as const, label: '刻钟', subtitle: '如 2:15、7:45' }, { id: 'random' as const, label: '随机', subtitle: '整点/半点/刻钟' }, ];