All files / web/src/arcade-games/matching types.ts

100% Statements 109/109
100% Branches 0/0
100% Functions 0/0
100% Lines 109/109

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 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 1101x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x  
/**
 * Abacus Matching Game - Variant-Specific Type Definitions
 *
 * Base types (GamePhase, Difficulty, BaseMatchingCard, etc.) live in the
 * matching-pairs-framework. This file defines only the abacus-specific
 * extensions and re-exports for backwards compatibility.
 */
 
import { z } from 'zod'
import type { BaseMatchingCard, BaseMatchingConfig } from '@/lib/arcade/matching-pairs-framework'
 
// ============================================================================
// Variant-Specific Schemas & Types
// ============================================================================
 
export const GameTypeSchema = z.enum(['abacus-numeral', 'complement-pairs'])
export type GameType = z.infer<typeof GameTypeSchema>
 
export const CardTypeSchema = z.enum(['abacus', 'number', 'complement'])
export type CardType = z.infer<typeof CardTypeSchema>
 
export const TargetSumSchema = z.union([z.literal(5), z.literal(10), z.literal(20)])
export type TargetSum = z.infer<typeof TargetSumSchema>
 
export const DifficultySchema = z.union([z.literal(6), z.literal(8), z.literal(12), z.literal(15)])
export type Difficulty = z.infer<typeof DifficultySchema>
 
// ============================================================================
// AbacusCard — extends BaseMatchingCard
// ============================================================================
 
export const AbacusCardSchema = z.object({
  id: z.string(),
  type: CardTypeSchema,
  number: z.number(),
  complement: z.number().optional(),
  targetSum: TargetSumSchema.optional(),
  matched: z.boolean(),
  matchedBy: z.string().optional(),
})
 
export type AbacusCard = z.infer<typeof AbacusCardSchema> & {
  element?: HTMLElement | null // runtime-only
}
 
// Verify AbacusCard extends BaseMatchingCard at the type level
const _cardCheck: BaseMatchingCard = {} as AbacusCard
void _cardCheck
 
// ============================================================================
// AbacusConfig — extends BaseMatchingConfig
// ============================================================================
 
export const AbacusConfigSchema = z.object({
  gameType: GameTypeSchema,
  difficulty: DifficultySchema,
  turnTimer: z.number(),
  skipSetupPhase: z.boolean().optional(),
})
 
export type AbacusConfig = z.infer<typeof AbacusConfigSchema>
 
// Verify AbacusConfig extends BaseMatchingConfig at the type level
const _configCheck: BaseMatchingConfig = {} as AbacusConfig
void _configCheck
 
// ============================================================================
// Match Validation Result
// ============================================================================
 
export interface MatchValidationResult {
  isValid: boolean
  reason?: string
  type: 'abacus-numeral' | 'complement' | 'invalid'
}
 
// ============================================================================
// Backwards Compatibility Aliases
// ============================================================================
 
// GameCard is the old name for AbacusCard
export type GameCard = AbacusCard
export const GameCardSchema = AbacusCardSchema
 
// MatchingConfig is the old name for AbacusConfig
export type MatchingConfig = AbacusConfig
export const MatchingConfigSchema = AbacusConfigSchema
 
// Re-export framework types under old names for external consumers
// IMPORTANT: Use concrete type aliases (not bare re-exports) so that
// AbacusConfig fields (e.g. gameType) appear on the state type.
import type {
  MatchingPairsState as _MatchingPairsState,
  MatchingPairsMove as _MatchingPairsMove,
} from '@/lib/arcade/matching-pairs-framework'
 
export type MatchingState = _MatchingPairsState<AbacusCard, AbacusConfig> & AbacusConfig
export type MemoryPairsState = MatchingState
export type MatchingMove = _MatchingPairsMove<AbacusCard>
 
export type {
  GamePhase,
  GameMode,
  PlayerMetadata,
  GameStatistics,
} from '@/lib/arcade/matching-pairs-framework'
 
// Player is just a string
export type Player = string