fix: can make moves after undo
This commit is contained in:
+1
-1
@@ -1,3 +1,3 @@
|
||||
NODE_ENV=development
|
||||
PORT=5000
|
||||
ID_LENGTH=10
|
||||
ID_LENGTH=8
|
||||
|
||||
@@ -13,15 +13,16 @@ const ChessUI: React.FC<InferProps<[typeof ChessBoard, typeof History]>> = (
|
||||
const [showModal, setShowModal] = useState(true);
|
||||
const navigate = useNavigate();
|
||||
const chess = props.chess;
|
||||
const currentChess = chess.getCurrentBoardPosition();
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-screen h-screen flex items-center justify-center">
|
||||
<div className="m-4 flex flex-row gap-4">
|
||||
<ChessBoard
|
||||
key={`${props.blackPerspective}` + chess.getFEN()}
|
||||
key={`${props.blackPerspective}` + currentChess.getFEN()}
|
||||
{...props}
|
||||
chess={chess.getCurrentBoardPosition()}
|
||||
chess={currentChess}
|
||||
disabled={(props.disabled ?? false) || chess.isGameOver()}
|
||||
/>
|
||||
<History {...props} />
|
||||
|
||||
@@ -57,9 +57,18 @@ const ChessBoard: React.FC<{
|
||||
isAttacked: false,
|
||||
isPromotion: false,
|
||||
isActive: false,
|
||||
EndGameIcon: undefined,
|
||||
endGameIcon: undefined,
|
||||
}));
|
||||
|
||||
const lastMove = chess.getHistory().history.at(-1)?.move;
|
||||
console.log(chess.getHistory().history.at(-1));
|
||||
|
||||
if (lastMove) {
|
||||
console.log(lastMove);
|
||||
tileProps[squareIndex(lastMove.from)].isActive = true;
|
||||
tileProps[squareIndex(lastMove.to)].isActive = true;
|
||||
}
|
||||
|
||||
if (activeTile != -1) {
|
||||
tileProps[activeTile].isActive = true;
|
||||
chess.getMovesForSquare(activeTile).forEach(({ to, flags }) => {
|
||||
@@ -72,13 +81,13 @@ const ChessBoard: React.FC<{
|
||||
if (chess.isGameOver()) {
|
||||
const kings = chess.getKings();
|
||||
if (chess.isDraw()) {
|
||||
tileProps[kings[COLOR.BLACK]].EndGameIcon = <HalfStar />;
|
||||
tileProps[kings[COLOR.WHITE]].EndGameIcon = <HalfStar />;
|
||||
tileProps[kings[COLOR.BLACK]].endGameIcon = <HalfStar />;
|
||||
tileProps[kings[COLOR.WHITE]].endGameIcon = <HalfStar />;
|
||||
} else {
|
||||
const loser = chess.getTurn(),
|
||||
winner = swapColor(loser);
|
||||
tileProps[kings[winner]].EndGameIcon = <Crown />;
|
||||
tileProps[kings[loser]].EndGameIcon = <Hashtag />;
|
||||
tileProps[kings[winner]].endGameIcon = <Crown />;
|
||||
tileProps[kings[loser]].endGameIcon = <Hashtag />;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +102,7 @@ const ChessBoard: React.FC<{
|
||||
|
||||
if (isNaN(tile)) return;
|
||||
|
||||
if (!chess.didUndo() && activeTile != -1 && tileProps[tile].isAttacked) {
|
||||
if (activeTile != -1 && tileProps[tile].isAttacked) {
|
||||
const moveObj = {
|
||||
from: algebraic(activeTile),
|
||||
to: algebraic(tile),
|
||||
@@ -180,14 +189,14 @@ const Tile: React.FC<{
|
||||
isActive: boolean;
|
||||
isAttacked: boolean;
|
||||
blackPerspective?: boolean;
|
||||
EndGameIcon?: ReactNode;
|
||||
endGameIcon?: ReactNode;
|
||||
}> = ({
|
||||
tileNumber,
|
||||
piece,
|
||||
isActive,
|
||||
isAttacked,
|
||||
blackPerspective,
|
||||
EndGameIcon,
|
||||
endGameIcon,
|
||||
}) => {
|
||||
const color = squareColor(tileNumber);
|
||||
|
||||
@@ -216,9 +225,9 @@ const Tile: React.FC<{
|
||||
className="max-w-full max-h-full aspect-square"
|
||||
/>
|
||||
)}
|
||||
<Show when={EndGameIcon != undefined}>
|
||||
<Show when={endGameIcon != undefined}>
|
||||
<div className="absolute top-0 left-full -translate-x-1/2 -translate-y-1/2 bg-white z-10 rounded-full p-1 shadow-lg shadow-black aspect-square flex justify-center items-center">
|
||||
{EndGameIcon}
|
||||
{endGameIcon}
|
||||
</div>
|
||||
</Show>
|
||||
<Show when={isAttacked}>
|
||||
|
||||
@@ -20,7 +20,7 @@ const LocalGame = () => {
|
||||
const rerender = () => aux((prev) => !prev);
|
||||
|
||||
const makeMove = (move: Move) => {
|
||||
if (chess.didUndo()) return;
|
||||
if (chess.didUndo()) chess.undoMoves();
|
||||
|
||||
chess.makeMove(move);
|
||||
rerender();
|
||||
|
||||
@@ -7,7 +7,6 @@ import { socket } from "../utils/socket";
|
||||
import { CaretLeft, CaretRight, CopyIcon } from "../components/icons";
|
||||
import Show from "../utils/Show";
|
||||
import ErrorNorification from "../components/ErrorNotification";
|
||||
import Modal, { ModalButton } from "../components/Modal";
|
||||
import ChessUI from "../components/ChessUI";
|
||||
import { removeLocationState } from "../utils/utils";
|
||||
import InferProps from "../utils/InferProps";
|
||||
@@ -106,7 +105,7 @@ const Game = () => {
|
||||
chess={chess}
|
||||
makeMove={makeMove}
|
||||
blackPerspective={color === COLOR.BLACK}
|
||||
disabled={color !== chess.getTurn()}
|
||||
disabled={color !== chess.getTurn() || chess.didUndo()}
|
||||
buttons={buttons}
|
||||
/>
|
||||
</Show>
|
||||
|
||||
+45
-13
@@ -509,7 +509,9 @@ export default class Chess {
|
||||
|
||||
private _moves: Array<InternalMove> = [];
|
||||
private _attacks: Array<number> = [];
|
||||
private _history: Array<Readonly<{ fen: string; san: string }>> = [];
|
||||
private _history: Array<
|
||||
Readonly<{ fen: string; san: string; move: InternalMove }>
|
||||
> = [];
|
||||
private _boardPositionCounter = new Map<string, number>();
|
||||
private _undoCount = 0;
|
||||
|
||||
@@ -600,19 +602,26 @@ export default class Chess {
|
||||
}
|
||||
}
|
||||
|
||||
private _getPositionCounter() {
|
||||
const trimFEN = this.getFEN(true);
|
||||
private _trimFEN(fen: string) {
|
||||
const split = fen.split(" ");
|
||||
return split.splice(0, 4).join(" ");
|
||||
}
|
||||
|
||||
private _getPositionCounter(fen: string) {
|
||||
const trimFEN = this._trimFEN(fen);
|
||||
return this._boardPositionCounter.get(trimFEN) ?? 0;
|
||||
}
|
||||
|
||||
private _incrementPositionCounter(fen: string) {
|
||||
const trimFEN = this._trimFEN(fen);
|
||||
const counter = this._boardPositionCounter.get(trimFEN) ?? 0;
|
||||
this._boardPositionCounter.set(trimFEN, counter + 1);
|
||||
}
|
||||
|
||||
private _processBoardState() {
|
||||
this._computeMoves();
|
||||
|
||||
if (this._enableHistory) {
|
||||
const trimFEN = this.getFEN(true);
|
||||
const counter = this._boardPositionCounter.get(trimFEN) ?? 0;
|
||||
this._boardPositionCounter.set(trimFEN, counter + 1);
|
||||
}
|
||||
if (this._enableHistory) this._incrementPositionCounter(this.getFEN());
|
||||
}
|
||||
|
||||
private static _load(
|
||||
@@ -660,7 +669,7 @@ export default class Chess {
|
||||
return this._load(fen, { enableProcessMoves: true, enableHistory: true });
|
||||
}
|
||||
|
||||
getFEN(trim = false) {
|
||||
getFEN() {
|
||||
let position = "";
|
||||
let emptySquares = 0;
|
||||
|
||||
@@ -702,10 +711,10 @@ export default class Chess {
|
||||
this._turn,
|
||||
castling,
|
||||
this._enPassant,
|
||||
this._halfMoves,
|
||||
this._fullMoves,
|
||||
];
|
||||
|
||||
if (!trim) arr.push(this._halfMoves, this._fullMoves);
|
||||
|
||||
return arr.join(" ");
|
||||
}
|
||||
|
||||
@@ -752,6 +761,7 @@ export default class Chess {
|
||||
this._history.push({
|
||||
fen: this.getFEN(),
|
||||
san: this._generateSan(move),
|
||||
move,
|
||||
});
|
||||
|
||||
this._board[squareIndex(move.to)] =
|
||||
@@ -998,7 +1008,7 @@ export default class Chess {
|
||||
}
|
||||
|
||||
isThreefoldRepetition() {
|
||||
return this._getPositionCounter() >= 3;
|
||||
return this._getPositionCounter(this.getFEN()) >= 3;
|
||||
}
|
||||
|
||||
is50Rule() {
|
||||
@@ -1041,11 +1051,33 @@ export default class Chess {
|
||||
enableHistory: false,
|
||||
enableProcessMoves: true,
|
||||
});
|
||||
chess._undoCount = this._undoCount;
|
||||
chess._undoCount = 0;
|
||||
chess._history = this._history.slice(
|
||||
0,
|
||||
this._history.length - this._undoCount
|
||||
);
|
||||
|
||||
return chess;
|
||||
}
|
||||
|
||||
undoMoves() {
|
||||
const chess = this.getCurrentBoardPosition();
|
||||
|
||||
this._board = chess._board;
|
||||
this._turn = chess._turn;
|
||||
this._castling = chess._castling;
|
||||
this._enPassant = chess._enPassant;
|
||||
this._halfMoves = chess._halfMoves;
|
||||
this._fullMoves = chess._fullMoves;
|
||||
this._kings = chess._kings;
|
||||
this._history = chess._history;
|
||||
this._undoCount = 0;
|
||||
this._boardPositionCounter = new Map<string, number>();
|
||||
this._history.forEach(({ fen }) => this._incrementPositionCounter(fen));
|
||||
|
||||
this._processBoardState();
|
||||
}
|
||||
|
||||
getTurn() {
|
||||
return this._turn;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { nanoid as nanoidOriginal } from "nanoid";
|
||||
dotenv.config();
|
||||
|
||||
const ID_LENGTH = isNaN(parseInt(process.env.ID_LENGTH!))
|
||||
? 10
|
||||
? 8
|
||||
: parseInt(process.env.ID_LENGTH!);
|
||||
|
||||
const nanoid = () => nanoidOriginal(ID_LENGTH);
|
||||
|
||||
Reference in New Issue
Block a user