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

0% Statements 0/99
0% Branches 0/1
0% Functions 0/1
0% Lines 0/99

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                                                                                                                                                                                                       
import { defineGame, type GameManifest, getGameTheme } from '@/lib/arcade/game-sdk'
import { RithmomachiaGame } from './components/RithmomachiaGame'
import { RithmomachiaProvider } from './Provider'
import type { RithmomachiaConfig, RithmomachiaMove, RithmomachiaState } from './types'
import { rithmomachiaValidator } from './Validator'

/**
 * Game manifest for Rithmomachia.
 */
const manifest: GameManifest = {
  name: 'rithmomachia',
  displayName: 'Rithmomachia',
  icon: '🎲',
  description: 'Medieval mathematical battle game',
  longDescription:
    'Rithmomachia (Battle of Numbers) is a medieval strategy game where pieces with numerical values capture each other through mathematical relations. Win by achieving harmony (a mathematical progression) in enemy territory, or by capturing enough pieces to exhaust your opponent.',
  maxPlayers: 2,
  difficulty: 'Advanced',
  chips: ['⚔️ Strategy', '🔢 Mathematical', '🏛️ Historical', '🎯 Two-Player'],
  ...getGameTheme('purple'),
  available: true,
  practiceBreakReady: false,
}

/**
 * Default configuration for Rithmomachia.
 */
const defaultConfig: RithmomachiaConfig = {
  pointWinEnabled: false,
  pointWinThreshold: 30,
  repetitionRule: true,
  fiftyMoveRule: true,
  allowAnySetOnRecheck: true,
  timeControlMs: null,
}

/**
 * Config validation (type guard).
 * Validates all config fields and their constraints.
 */
function validateConfig(config: unknown): config is RithmomachiaConfig {
  if (typeof config !== 'object' || config === null) {
    return false
  }

  const c = config as Record<string, unknown>

  // Validate pointWinEnabled
  if (!('pointWinEnabled' in c) || typeof c.pointWinEnabled !== 'boolean') {
    return false
  }

  // Validate pointWinThreshold
  if (
    !('pointWinThreshold' in c) ||
    typeof c.pointWinThreshold !== 'number' ||
    c.pointWinThreshold < 1
  ) {
    return false
  }

  // Validate repetitionRule
  if (!('repetitionRule' in c) || typeof c.repetitionRule !== 'boolean') {
    return false
  }

  // Validate fiftyMoveRule
  if (!('fiftyMoveRule' in c) || typeof c.fiftyMoveRule !== 'boolean') {
    return false
  }

  // Validate allowAnySetOnRecheck
  if (!('allowAnySetOnRecheck' in c) || typeof c.allowAnySetOnRecheck !== 'boolean') {
    return false
  }

  // Validate timeControlMs
  if ('timeControlMs' in c) {
    if (c.timeControlMs !== null && (typeof c.timeControlMs !== 'number' || c.timeControlMs < 0)) {
      return false
    }
  }

  return true
}

/**
 * Rithmomachia game definition.
 */
export const rithmomachiaGame = defineGame<RithmomachiaConfig, RithmomachiaState, RithmomachiaMove>(
  {
    manifest,
    Provider: RithmomachiaProvider,
    GameComponent: RithmomachiaGame,
    validator: rithmomachiaValidator,
    defaultConfig,
    validateConfig,
  }
)