All files / web/src/arcade-games/yjs-demo Validator.ts

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

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                                                                                                                                                                                           
import type { GameValidator, ValidationResult } from '@/lib/arcade/validation/types'
import {
  YjsDemoStateSchema,
  type YjsDemoConfig,
  type YjsDemoMove,
  type YjsDemoState,
} from './types'

export class YjsDemoValidator implements GameValidator<YjsDemoState, YjsDemoMove> {
  // Zod schema for runtime validation of state loaded from database
  stateSchema = YjsDemoStateSchema

  validateMove(state: YjsDemoState, move: YjsDemoMove): ValidationResult {
    switch (move.type) {
      case 'START_GAME':
        return this.validateStartGame(state, move.data.activePlayers)
      case 'END_GAME':
        return this.validateEndGame(state)
      case 'GO_TO_SETUP':
        return this.validateGoToSetup(state)
      default:
        return { valid: false, error: 'Unknown move type' }
    }
  }

  private validateStartGame(state: YjsDemoState, activePlayers: string[]): ValidationResult {
    if (state.gamePhase !== 'setup') {
      return { valid: false, error: 'Game already started' }
    }

    if (activePlayers.length === 0) {
      return { valid: false, error: 'No players selected' }
    }

    const playerScores: Record<string, number> = {}
    for (const playerId of activePlayers) {
      playerScores[playerId] = 0
    }

    const newState: YjsDemoState = {
      ...state,
      gamePhase: 'playing',
      activePlayers,
      playerScores,
      startTime: Date.now(),
    }

    return { valid: true, newState }
  }

  private validateEndGame(state: YjsDemoState): ValidationResult {
    if (state.gamePhase !== 'playing') {
      return { valid: false, error: 'Game is not in progress' }
    }

    const newState: YjsDemoState = {
      ...state,
      gamePhase: 'results',
      endTime: Date.now(),
    }

    return { valid: true, newState }
  }

  private validateGoToSetup(state: YjsDemoState): ValidationResult {
    const newState: YjsDemoState = {
      ...state,
      gamePhase: 'setup',
      activePlayers: [],
      playerScores: {},
      startTime: undefined,
      endTime: undefined,
    }

    return { valid: true, newState }
  }

  isGameComplete(state: YjsDemoState): boolean {
    return state.gamePhase === 'results'
  }

  getInitialState(config: YjsDemoConfig): YjsDemoState {
    return {
      gamePhase: 'setup',
      gridSize: config.gridSize,
      duration: config.duration,
      activePlayers: [],
      playerScores: {},
    }
  }
}

export const yjsDemoValidator = new YjsDemoValidator()