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:
1 parent
818e05beaf
commit
4bc47d7966
2 files changed
+35
-7
No files matched your search
@@ -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' },
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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'), []);
|
||||||
|
});
|
||||||
Reference in new issue
Block a user