Files
chesskit/src/hooks/useChessActions.ts
GuillaumeSD 74a2adbb7d Squashed commit of the following:
commit dfc79cf287823383a25a650d5788ee5250b1c316
Author: GuillaumeSD <47183782+GuillaumeSD@users.noreply.github.com>
Date:   Sun May 11 01:32:35 2025 +0200

    fix : style

commit bccfa5a3358302c2f037cc2dcfbd0a1df5e2974e
Author: GuillaumeSD <47183782+GuillaumeSD@users.noreply.github.com>
Date:   Sun May 11 01:01:12 2025 +0200

    feat : players clocks v1

commit 5f65009f200686433904710d5f9ceb1ba166fa9d
Author: GuillaumeSD <47183782+GuillaumeSD@users.noreply.github.com>
Date:   Sat May 10 21:58:02 2025 +0200

    fix : merge issues

commit f93dc6104e2d3fbb60088f578c2d1f13bf6519e9
Merge: a9f3728 fea1f3f
Author: GuillaumeSD <47183782+GuillaumeSD@users.noreply.github.com>
Date:   Sat May 10 21:53:11 2025 +0200

    Merge branch 'main' into feat/add-players-clocks

commit a9f372808ef403dfb823c4cf93c837412cc55c53
Author: GuillaumeSD <gsd.lfny@gmail.com>
Date:   Mon Jan 6 23:10:28 2025 +0100

    fix : rename

commit aedf9c252023bebe4da4327b7526371fa75b7b3e
Author: GuillaumeSD <gsd.lfny@gmail.com>
Date:   Sun Jan 5 17:30:27 2025 +0100

    feat : add players clocks
2025-05-11 01:33:10 +02:00

136 lines
3.1 KiB
TypeScript

import { getGameFromPgn, setGameHeaders } from "@/lib/chess";
import {
playGameEndSound,
playIllegalMoveSound,
playSoundFromMove,
} from "@/lib/sounds";
import { Player } from "@/types/game";
import { Chess, Move, DEFAULT_POSITION } from "chess.js";
import { PrimitiveAtom, useAtom } from "jotai";
import { useCallback } from "react";
export interface resetGameParams {
fen?: string;
white?: Player;
black?: Player;
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 (
["1-0", "0-1", "1/2-1/2", "*"].includes(
pgnSplitted.at(-1)?.trim() ?? ""
)
) {
newGame.loadPgn(pgnSplitted.slice(0, -1).join("]") + "]");
return newGame;
}
}
newGame.loadPgn(game.pgn());
return newGame;
}, [game]);
const resetToStartingPosition = useCallback(
(pgn?: string) => {
const newGame = pgn ? getGameFromPgn(pgn) : copyGame();
newGame.load(newGame.getHeaders().FEN || DEFAULT_POSITION, {
preserveHeaders: true,
});
setGame(newGame);
},
[copyGame, setGame]
);
const makeMove = useCallback(
(params: {
from: string;
to: string;
promotion?: string;
comment?: string;
}): Move | null => {
const newGame = copyGame();
try {
const { comment, ...move } = params;
const result = newGame.move(move);
if (comment) newGame.setComment(comment);
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,
resetToStartingPosition,
};
};