Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | /** * Music Note Matching Game - Variant-Specific Type Definitions * * Base types (GamePhase, Difficulty, BaseMatchingCard, etc.) live in the * matching-pairs-framework. This file defines only the music-specific * extensions. */ import { z } from 'zod' import type { BaseMatchingCard, BaseMatchingConfig } from '@/lib/arcade/matching-pairs-framework' // ============================================================================ // Variant-Specific Schemas & Types // ============================================================================ export const MusicCardTypeSchema = z.enum(['staff-note', 'note-name']) export type MusicCardType = z.infer<typeof MusicCardTypeSchema> export const MusicGameTypeSchema = z.enum(['staff-to-name', 'treble-to-bass']) export type MusicGameType = z.infer<typeof MusicGameTypeSchema> export const ClefSchema = z.enum(['treble', 'bass', 'both']) export type ClefOption = z.infer<typeof ClefSchema> export const DifficultySchema = z.union([z.literal(6), z.literal(8), z.literal(12), z.literal(15)]) export type Difficulty = z.infer<typeof DifficultySchema> // ============================================================================ // MusicCard — extends BaseMatchingCard // ============================================================================ export const MusicCardSchema = z.object({ id: z.string(), type: MusicCardTypeSchema, pitchClass: z.string(), octave: z.number(), midiNote: z.number(), clef: z.enum(['treble', 'bass']).optional(), accidental: z.enum(['sharp', 'flat', 'natural', 'none']).optional(), displayName: z.string(), friendlyName: z.string().optional(), matched: z.boolean(), matchedBy: z.string().optional(), }) export type MusicCard = z.infer<typeof MusicCardSchema> // Verify MusicCard extends BaseMatchingCard at the type level const _cardCheck: BaseMatchingCard = {} as MusicCard void _cardCheck // ============================================================================ // MusicConfig — extends BaseMatchingConfig // ============================================================================ export const MusicConfigSchema = z.object({ gameType: MusicGameTypeSchema, clef: ClefSchema, difficulty: DifficultySchema, turnTimer: z.number(), skipSetupPhase: z.boolean().optional(), }) export type MusicConfig = z.infer<typeof MusicConfigSchema> // Verify MusicConfig extends BaseMatchingConfig at the type level const _configCheck: BaseMatchingConfig = {} as MusicConfig void _configCheck // ============================================================================ // Match Validation Result // ============================================================================ export interface MusicMatchValidationResult { isValid: boolean reason?: string type: 'staff-to-name' | 'treble-to-bass' | 'invalid' } |