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

76.36% Statements 84/110
100% Branches 0/0
0% Functions 0/1
76.36% Lines 84/110

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 110 1111x 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  
/**
 * Matching Pairs Battle Game Definition
 *
 * A turn-based multiplayer memory game where players flip cards to find matching pairs.
 * Supports both abacus-numeral matching and complement pairs modes.
 *
 * Now powered by the matching-pairs framework with a thin variant definition.
 */
 
import { getGameTheme } from '@/lib/arcade/game-themes'
import type { GameManifest } from '@/lib/arcade/manifest-schema'
import { defineMatchingPairsGame } from '@/lib/arcade/matching-pairs-framework'
import { abacusVariant } from './variant'
import type { AbacusConfig } from './types'
 
const manifest: GameManifest = {
  name: 'matching',
  displayName: 'Matching Pairs Battle',
  shortName: 'Matching Pairs',
  icon: '⚔️',
  description: 'Multiplayer memory battle with friends',
  longDescription:
    'Battle friends in epic memory challenges. Match pairs faster than your opponents in this exciting multiplayer experience. ' +
    'Choose between abacus-numeral matching or complement pairs mode. Strategic thinking and quick memory are key to victory!',
  maxPlayers: 4,
  difficulty: 'Intermediate',
  chips: ['👥 Multiplayer', '🎯 Strategic', '🏆 Competitive'],
  ...getGameTheme('pink'),
  available: true,
  practiceBreakReady: true,
  practiceBreakConfig: {
    suggestedConfig: {
      gameType: 'abacus-numeral',
      difficulty: 6,
      turnTimer: 30,
    },
    lockedFields: ['turnTimer'],
    minDurationMinutes: 2,
    maxDurationMinutes: 8,
    difficultyPresets: {
      easy: { difficulty: 6, gameType: 'abacus-numeral' },
      medium: { difficulty: 8, gameType: 'abacus-numeral' },
      hard: { difficulty: 12, gameType: 'complement-pairs' },
    },
    fieldConfig: {
      gameType: {
        label: 'Match Type',
        type: 'select',
        options: [
          { value: 'abacus-numeral', label: 'Abacus ↔ Number' },
          { value: 'complement-pairs', label: 'Complement Pairs' },
        ],
      },
      difficulty: {
        label: 'Pairs',
        type: 'select',
        options: [
          { value: 6, label: '6' },
          { value: 8, label: '8' },
          { value: 12, label: '12' },
          { value: 15, label: '15' },
        ],
      },
    },
  },
  resultsConfig: {
    supportsResults: true,
    resultsDisplayDurationMs: 5000,
    scoreboardCategory: 'memory',
  },
  coPlay: { mode: 'join-at-start' },
}
 
// Config validation function
function validateMatchingConfig(config: unknown): config is AbacusConfig {
  if (typeof config !== 'object' || config === null) {
    return false
  }

  const c = config as any

  if (!('gameType' in c) || !['abacus-numeral', 'complement-pairs'].includes(c.gameType)) {
    return false
  }

  if (!('difficulty' in c) || ![6, 8, 12, 15].includes(c.difficulty)) {
    return false
  }

  if (
    !('turnTimer' in c) ||
    typeof c.turnTimer !== 'number' ||
    c.turnTimer < 5 ||
    c.turnTimer > 300
  ) {
    return false
  }

  return true
}
 
const { game, useMatchingPairs, validator } = defineMatchingPairsGame({
  manifest,
  variant: abacusVariant,
  validateConfig: validateMatchingConfig,
})
 
export const matchingGame = game
export { useMatchingPairs }
export const matchingGameValidator = validator