Files
chesskit/src/hooks/useChessActions.ts
GuillaumeSD 47e52988f3 Squashed commit of the following:
commit 933ba823d5f991b9ab1f66bd94262c181e9d0267
Author: GuillaumeSD <gsd.lfny@gmail.com>
Date:   Mon Apr 21 20:13:37 2025 +0200

    fix : new chessjs version

commit b9376bcbc718f6eaa9a0fd9caada6b957f73b85a
Author: GuillaumeSD <gsd.lfny@gmail.com>
Date:   Mon Apr 21 19:34:12 2025 +0200

    chore : chessjs bump version
2025-04-21 20:14:13 +02:00

107 lines
2.5 KiB
TypeScript

import { setGameHeaders } from "@/lib/chess";
import {
playGameEndSound,
playIllegalMoveSound,
playSoundFromMove,
} from "@/lib/sounds";
import { Chess, Move } from "chess.js";
import { PrimitiveAtom, useAtom } from "jotai";
import { useCallback } from "react";
export interface resetGameParams {
fen?: string;
whiteName?: string;
blackName?: string;
noHeaders?: boolean;
}
export const useChessActions = (chessAtom: PrimitiveAtom<Chess>) => {
const [game, setGame] = useAtom(chessAtom);
const setPgn = useCallback(
(pgn: string) => {
const newGame = new Chess();
newGame.loadPgn(pgn);
setGame(newGame);
},
[setGame]
);
const reset = useCallback(
(params?: resetGameParams) => {
const newGame = new Chess(params?.fen);
if (!params?.noHeaders) setGameHeaders(newGame, params);
setGame(newGame);
},
[setGame]
);
const copyGame = useCallback(() => {
const newGame = new Chess();
if (game.history().length === 0) {
const pgnSplitted = game.pgn().split("]");
if (
pgnSplitted.at(-1)?.includes("1-0") ||
pgnSplitted.at(-1) === "\n *"
) {
newGame.loadPgn(pgnSplitted.slice(0, -1).join("]") + "]");
return newGame;
}
}
newGame.loadPgn(game.pgn());
return newGame;
}, [game]);
const makeMove = useCallback(
(move: { from: string; to: string; promotion?: string }): Move | null => {
const newGame = copyGame();
try {
const result = newGame.move(move);
setGame(newGame);
playSoundFromMove(result);
return result;
} catch {
playIllegalMoveSound();
return null;
}
},
[copyGame, setGame]
);
const undoMove = useCallback(() => {
const newGame = copyGame();
const move = newGame.undo();
if (move) playSoundFromMove(move);
setGame(newGame);
}, [copyGame, setGame]);
const goToMove = useCallback(
(moveIdx: number, fullGame: Chess) => {
if (moveIdx < 0) return;
const newGame = new Chess();
newGame.loadPgn(fullGame.pgn());
const movesNb = fullGame.history().length;
if (moveIdx > movesNb) return;
let lastMove: Move | null = null;
for (let i = movesNb; i > moveIdx; i--) {
lastMove = newGame.undo();
}
setGame(newGame);
if (lastMove) {
playSoundFromMove(lastMove);
} else {
playGameEndSound();
}
},
[setGame]
);
return { setPgn, reset, makeMove, undoMove, goToMove };
};