UNPKG

@react-chess-puzzle-fix/react-chess-puzzle

Version:

A lightweight, customizable React component library for rendering and interacting with chess puzzles.

97 lines (81 loc) 2.39 kB
import { useEffect, useReducer } from "react"; import { initializePuzzle, reducer } from "./reducer"; import { getOrientation, type Puzzle } from "../utils"; import { useChessGameContext } from "react-chess-game-fix"; const ANIMATION_MS = 300; export const useChessPuzzle = ( puzzle: Puzzle, onSolve?: (changePuzzle: (puzzle: Puzzle) => void) => void, onFail?: (changePuzzle: (puzzle: Puzzle) => void) => void, ) => { const gameContext = useChessGameContext(); const [state, dispatch] = useReducer(reducer, { puzzle }, initializePuzzle); const { game, methods: { makeMove, setPosition }, currentFen, } = gameContext; useEffect(() => { if (gameContext && game.fen() !== puzzle.fen) { setPosition(puzzle.fen, getOrientation(puzzle)); } }, []); const changePuzzle = (puzzle: Puzzle) => { dispatch({ type: "INITIALIZE", payload: { puzzle } }); setPosition(puzzle.fen, getOrientation(puzzle)); }; const autoRetry = () => { dispatch({ type: "AUTO_RETRY", payload: { puzzle } }); }; useEffect(() => { if (gameContext && game.fen() === puzzle.fen && state.needCpuMove) { setTimeout( () => dispatch({ type: "CPU_MOVE", }), 0, ); } }, [gameContext, state.needCpuMove]); useEffect(() => { if (state.cpuMove) { makeMove(state.cpuMove); } }, [state.cpuMove]); useEffect(() => { if (game?.history()?.length <= 0 + (puzzle.makeFirstMove ? 1 : 0)) { return; } if (game.history().length % 2 === (puzzle.makeFirstMove ? 0 : 1)) { dispatch({ type: "PLAYER_MOVE", payload: { move: gameContext?.game?.history({ verbose: true })?.pop() ?? null, onSolve, onFail, changePuzzle, game: game, }, }); setTimeout(() => dispatch({ type: "CPU_MOVE" }), ANIMATION_MS + 20); // tiny buffer } }, [game?.history()?.length]); if (!gameContext) { throw new Error("useChessPuzzle must be used within a ChessGameContext"); } const onHint = () => { dispatch({ type: "TOGGLE_HINT" }); }; return { status: state.status, changePuzzle, autoRetry, currentMoveIndex: state.currentMoveIndex, puzzle, hint: state.hint, onHint, nextMove: state.nextMove, isPlayerTurn: state.isPlayerTurn, }; };