show endgame glyph on another piece when there is no king - closes #21971

Antichess and horde can end with a side that has no king, so the
result glyph had nothing to sit on. Fall back to the queen, rook,
bishop, knight and pawn, in that order.
This commit is contained in:
dualfroz committed 2026-10-16 09:54:10 +02:00
1 parent 818e05beaf
commit 4bc47d7966
2 files changed
+35 -7

No files matched your search

+9 -7
View File
@@ -44,12 +44,14 @@ export function endgameShapesForNode(
return endgameShapes(node.fen, result.winner, result.status); return endgameShapes(node.fen, result.winner, result.status);
} }
export function findKingSquare(fen: FEN, color: Color): Key | undefined { const glyphRoles: Role[] = ['king', 'queen', 'rook', 'bishop', 'knight', 'pawn'];
const king = parseFen(fen).unwrap(
setup => setup.board.kingOf(color), export function findGlyphSquare(fen: FEN, color: Color): Key | undefined {
const square = parseFen(fen).unwrap(
setup => glyphRoles.map(role => setup.board.pieces(color, role).first()).find(sq => sq !== undefined),
_ => undefined, _ => undefined,
); );
return king === undefined ? undefined : makeSquare(king); return square === undefined ? undefined : makeSquare(square);
} }
const loserGlyph = (status: StatusName | undefined): EndgameGlyph => const loserGlyph = (status: StatusName | undefined): EndgameGlyph =>
@@ -82,10 +84,10 @@ export function endgameShapes(
const shapes: DrawShape[] = []; const shapes: DrawShape[] = [];
const add = (color: Color, glyph: EndgameGlyph) => { const add = (color: Color, glyph: EndgameGlyph) => {
const king = findKingSquare(fen, color); const square = findGlyphSquare(fen, color);
if (king) if (square)
shapes.push({ shapes.push({
orig: king, orig: square,
brush: '', brush: '',
customSvg: { html: endgameGlyphs[glyph](0), center: 'orig' }, customSvg: { html: endgameGlyphs[glyph](0), center: 'orig' },
}); });
+26
View File
@@ -0,0 +1,26 @@
import assert from 'node:assert/strict';
import { test } from 'node:test';
import { endgameShapes } from '../src/game/endgame';
import type { StatusName } from '../src/game/status';
const origs = (fen: FEN, winner: Color | undefined, status: StatusName) =>
endgameShapes(fen, winner, status).map(shape => shape.orig);
test('glyph goes on the king when there is one', () => {
assert.deepStrictEqual(origs('4k3/8/8/8/8/8/8/Q3K3 w - - 0 1', 'black', 'resign'), ['e1']);
});
test('glyph falls back to the strongest piece without a king', () => {
assert.deepStrictEqual(origs('8/8/8/8/8/8/8/6N1 b - - 0 28', 'black', 'variantEnd'), ['g1']);
assert.deepStrictEqual(origs('8/8/8/8/8/8/2P5/1NR5 b - - 0 40', 'black', 'variantEnd'), ['c1']);
assert.deepStrictEqual(origs('8/8/8/8/8/8/2P5/1N6 b - - 0 40', 'black', 'variantEnd'), ['b1']);
});
test('draw glyphs show for a side without a king', () => {
assert.deepStrictEqual(origs('4k3/8/8/8/8/8/PPPPPPPP/8 w - - 0 1', undefined, 'stalemate'), ['a2', 'e8']);
});
test('no glyph for a side without pieces', () => {
assert.deepStrictEqual(origs('8/8/8/8/8/8/8/6N1 b - - 0 28', 'white', 'variantEnd'), []);
});