From 6177824d28aea903843f409796497114b06d6391 Mon Sep 17 00:00:00 2001 From: GuillaumeSD Date: Tue, 26 Mar 2024 20:19:46 +0100 Subject: [PATCH] fix : remove piece recapture from great moves --- src/lib/chess.ts | 25 ++++++++++++++++---- src/lib/engine/helpers/moveClassification.ts | 21 +++++++++++++--- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/lib/chess.ts b/src/lib/chess.ts index 8216065..8392e4a 100644 --- a/src/lib/chess.ts +++ b/src/lib/chess.ts @@ -1,6 +1,6 @@ import { EvaluateGameParams, PositionEval } from "@/types/eval"; import { Game } from "@/types/game"; -import { Chess, PieceSymbol } from "chess.js"; +import { Chess, PieceSymbol, Square } from "chess.js"; import { getPositionWinPercentage } from "./engine/helpers/winPercentage"; import { Color } from "@/types/enums"; @@ -156,15 +156,30 @@ export const getWhoIsCheckmated = (fen: string): "w" | "b" | null => { export const uciMoveParams = ( uciMove: string ): { - from: string; - to: string; + from: Square; + to: Square; promotion?: string | undefined; } => ({ - from: uciMove.slice(0, 2), - to: uciMove.slice(2, 4), + from: uciMove.slice(0, 2) as Square, + to: uciMove.slice(2, 4) as Square, promotion: uciMove.slice(4, 5) || undefined, }); +export const isSimplePieceRecapture = ( + fen: string, + uciMoves: [string, string] +): boolean => { + const game = new Chess(fen); + const moves = uciMoves.map((uciMove) => uciMoveParams(uciMove)); + + if (moves[0].to !== moves[1].to) return false; + + const piece = game.get(moves[0].to); + if (piece) return true; + + return false; +}; + export const getIsPieceSacrifice = ( fen: string, playedMove: string, diff --git a/src/lib/engine/helpers/moveClassification.ts b/src/lib/engine/helpers/moveClassification.ts index 4c7174f..bce1b2a 100644 --- a/src/lib/engine/helpers/moveClassification.ts +++ b/src/lib/engine/helpers/moveClassification.ts @@ -5,7 +5,7 @@ import { } from "./winPercentage"; import { MoveClassification } from "@/types/enums"; import { openings } from "@/data/openings"; -import { getIsPieceSacrifice } from "@/lib/chess"; +import { getIsPieceSacrifice, isSimplePieceRecapture } from "@/lib/chess"; export const getMovesClassification = ( rawPositions: PositionEval[], @@ -63,12 +63,18 @@ export const getMovesClassification = ( }; } + const fenTwoMovesAgo = index > 1 ? fens[index - 2] : null; + const uciNextTwoMoves: [string, string] | null = + index > 1 ? [uciMoves[index - 2], uciMoves[index - 1]] : null; + if ( isGreatMove( lastPositionWinPercentage, positionWinPercentage, isWhiteMove, - lastPositionAlternativeLineWinPercentage + lastPositionAlternativeLineWinPercentage, + fenTwoMovesAgo, + uciNextTwoMoves ) ) { return { @@ -155,7 +161,9 @@ const isGreatMove = ( lastPositionWinPercentage: number, positionWinPercentage: number, isWhiteMove: boolean, - lastPositionAlternativeLineWinPercentage: number | undefined + lastPositionAlternativeLineWinPercentage: number | undefined, + fenTwoMovesAgo: string | null, + uciMoves: [string, string] | null ): boolean => { if (!lastPositionAlternativeLineWinPercentage) return false; @@ -164,6 +172,13 @@ const isGreatMove = ( (isWhiteMove ? 1 : -1); if (winPercentageDiff < -2) return false; + if ( + fenTwoMovesAgo && + uciMoves && + isSimplePieceRecapture(fenTwoMovesAgo, uciMoves) + ) + return false; + const hasChangedGameOutcome = getHasChangedGameOutcome( lastPositionWinPercentage, positionWinPercentage,