All files / web/src/arcade-games/rithmomachia/hooks usePieceSelection.ts

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

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                                                                                                                                                                       
import { useCallback, useState } from 'react'
import type { Color, Piece } from '../types'
import { validateMove } from '../utils/pathValidator'

/**
 * Callbacks for piece selection events
 */
export interface PieceSelectionCallbacks {
  onMove: (from: string, to: string, pieceId: string) => void
  onCaptureAttempt: (from: string, to: string, pieceId: string) => void
}

/**
 * Hook for managing piece selection state and logic
 */
export function usePieceSelection(
  pieces: Record<string, Piece>,
  playerColor: Color | null,
  isMyTurn: boolean,
  callbacks: PieceSelectionCallbacks
) {
  const [selectedSquare, setSelectedSquare] = useState<string | null>(null)

  const handleSquareClick = useCallback(
    (square: string, piece: Piece | undefined) => {
      if (!isMyTurn) return

      // If no piece selected, select this piece if it's yours
      if (!selectedSquare) {
        if (piece && piece.color === playerColor) {
          setSelectedSquare(square)
        }
        return
      }

      // If clicking the same square, deselect
      if (selectedSquare === square) {
        setSelectedSquare(null)
        return
      }

      // If clicking another piece of yours, select that instead
      if (piece && piece.color === playerColor) {
        setSelectedSquare(square)
        return
      }

      // Otherwise, attempt to move
      const selectedPiece = Object.values(pieces).find(
        (p) => p.square === selectedSquare && !p.captured
      )
      if (selectedPiece) {
        // Validate the move is legal before proceeding
        const validation = validateMove(selectedPiece, selectedSquare, square, pieces)

        if (!validation.valid) {
          // Invalid move - silently ignore
          return
        }

        // If target square has an enemy piece, open capture dialog
        if (piece && piece.color !== playerColor) {
          callbacks.onCaptureAttempt(selectedSquare, square, selectedPiece.id)
        } else {
          // Simple move (no capture)
          callbacks.onMove(selectedSquare, square, selectedPiece.id)
          setSelectedSquare(null)
        }
      }
    },
    [selectedSquare, isMyTurn, playerColor, pieces, callbacks]
  )

  const clearSelection = useCallback(() => {
    setSelectedSquare(null)
  }, [])

  return {
    selectedSquare,
    handleSquareClick,
    clearSelection,
  }
}