Upstream lichess-org/lila state of the touched files before dc0269b236

This commit is contained in:
upstream committed 2026-09-26 10:47:45 +02:00
commit 3f6c487976
1 file changed
+114
+114
View File
@@ -0,0 +1,114 @@
import type { DrawShape } from '@lichess-org/chessground/draw';
import type { Outcome } from 'chessops';
import { parseFen } from 'chessops/fen';
import { makeSquare, opposite } from 'chessops/util';
import { fenColor } from './chess';
import { endgameGlyphs } from './glyphs';
import type { StatusName } from './status';
export interface EndgameResult {
winner?: Color;
status?: StatusName;
}
type EndgameNode = {
fen: FEN;
outcome: () => Outcome | undefined;
check: () => boolean;
dests: () => Dests;
};
const endgameResult = (
node: EndgameNode,
isLast: boolean,
gameWinner: Color | undefined,
gameStatus: StatusName,
): EndgameResult => {
const isTerminal = node.dests().size === 0,
isMate = node.check() && isTerminal,
isStalemate = !node.check() && isTerminal,
isGameEnd = isLast || isTerminal;
if (!isGameEnd) return {};
return {
winner: isMate
? opposite(fenColor(node.fen))
: isStalemate
? undefined
: (node.outcome()?.winner ?? gameWinner),
status: isMate ? 'mate' : isStalemate ? 'stalemate' : gameStatus,
};
};
export function endgameShapesForNode(
node: EndgameNode,
isLast: boolean,
gameWinner: Color | undefined,
gameStatus: StatusName,
): DrawShape[] {
const result = endgameResult(node, isLast, gameWinner, gameStatus);
return endgameShapes(node.fen, result.winner, result.status);
}
export function findKingSquare(fen: FEN, color: Color): Key | undefined {
const king = parseFen(fen).unwrap(
setup => setup.board.kingOf(color),
_ => undefined,
);
return king === undefined ? undefined : makeSquare(king);
}
type EndgameGlyph = keyof typeof endgameGlyphs;
const loserGlyph = (status: StatusName | undefined): EndgameGlyph =>
status === 'mate'
? 'mate'
: status === 'resign'
? 'resign'
: status === 'timeout'
? 'abandoned'
: status === 'outoftime'
? 'outoftime'
: 'unknown';
const drawGlyph = (status: StatusName | undefined): EndgameGlyph | undefined =>
status === 'stalemate'
? 'stalemate'
: status === 'draw' ||
status === 'insufficientMaterialClaim' ||
status === 'outoftime' ||
status === 'timeout'
? 'draw'
: undefined;
export function endgameShapes(
fen: FEN,
winner: Color | undefined,
status: StatusName | undefined,
): DrawShape[] {
if (status === 'aborted' || status === 'noStart') return [];
const shapes: DrawShape[] = [];
const add = (color: Color, glyph: EndgameGlyph) => {
const king = findKingSquare(fen, color);
if (king)
shapes.push({
orig: king,
brush: '',
customSvg: { html: endgameGlyphs[glyph](0), center: 'orig' },
});
};
if (winner) {
add(winner, 'win');
add(opposite(winner), loserGlyph(status));
} else {
const glyph = drawGlyph(status);
if (glyph) {
add('white', glyph);
add('black', glyph);
}
}
return shapes;
}