@datamoc/mw_games 0.20.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +128 -0
- package/dist/audio/Channels.d.ts +19 -0
- package/dist/audio/Channels.d.ts.map +1 -1
- package/dist/audio/Channels.js +33 -4
- package/dist/audio/Channels.js.map +1 -1
- package/dist/audio/LoopTags.d.ts +37 -0
- package/dist/audio/LoopTags.d.ts.map +1 -0
- package/dist/audio/LoopTags.js +116 -0
- package/dist/audio/LoopTags.js.map +1 -0
- package/dist/audio/Midi.d.ts +29 -0
- package/dist/audio/Midi.d.ts.map +1 -1
- package/dist/audio/Midi.js +30 -1
- package/dist/audio/Midi.js.map +1 -1
- package/dist/audio/MidiRender.d.ts +3 -2
- package/dist/audio/MidiRender.d.ts.map +1 -1
- package/dist/audio/MidiRender.js +2 -2
- package/dist/audio/MidiRender.js.map +1 -1
- package/dist/audio/humanize/Groove.d.ts +80 -0
- package/dist/audio/humanize/Groove.d.ts.map +1 -0
- package/dist/audio/humanize/Groove.js +102 -0
- package/dist/audio/humanize/Groove.js.map +1 -0
- package/dist/audio/humanize/GrooveConverter.d.ts +49 -0
- package/dist/audio/humanize/GrooveConverter.d.ts.map +1 -0
- package/dist/audio/humanize/GrooveConverter.js +344 -0
- package/dist/audio/humanize/GrooveConverter.js.map +1 -0
- package/dist/audio/humanize/GrooveExtractor.d.ts +49 -0
- package/dist/audio/humanize/GrooveExtractor.d.ts.map +1 -0
- package/dist/audio/humanize/GrooveExtractor.js +179 -0
- package/dist/audio/humanize/GrooveExtractor.js.map +1 -0
- package/dist/audio/humanize/GrooveHumanizer.d.ts +34 -0
- package/dist/audio/humanize/GrooveHumanizer.d.ts.map +1 -0
- package/dist/audio/humanize/GrooveHumanizer.js +37 -0
- package/dist/audio/humanize/GrooveHumanizer.js.map +1 -0
- package/dist/audio/humanize/Humanize.d.ts +54 -0
- package/dist/audio/humanize/Humanize.d.ts.map +1 -0
- package/dist/audio/humanize/Humanize.js +239 -0
- package/dist/audio/humanize/Humanize.js.map +1 -0
- package/dist/audio/humanize/HumanizerFactory.d.ts +68 -0
- package/dist/audio/humanize/HumanizerFactory.d.ts.map +1 -0
- package/dist/audio/humanize/HumanizerFactory.js +84 -0
- package/dist/audio/humanize/HumanizerFactory.js.map +1 -0
- package/dist/audio/humanize/LiteHumanizer.d.ts +30 -0
- package/dist/audio/humanize/LiteHumanizer.d.ts.map +1 -0
- package/dist/audio/humanize/LiteHumanizer.js +35 -0
- package/dist/audio/humanize/LiteHumanizer.js.map +1 -0
- package/dist/audio/humanize/Onsets.d.ts +26 -0
- package/dist/audio/humanize/Onsets.d.ts.map +1 -0
- package/dist/audio/humanize/Onsets.js +164 -0
- package/dist/audio/humanize/Onsets.js.map +1 -0
- package/dist/audio/index.d.ts +14 -1
- package/dist/audio/index.d.ts.map +1 -1
- package/dist/audio/index.js +7 -0
- package/dist/audio/index.js.map +1 -1
- package/dist/board/bitboard.d.ts +132 -0
- package/dist/board/bitboard.d.ts.map +1 -0
- package/dist/board/bitboard.js +495 -0
- package/dist/board/bitboard.js.map +1 -0
- package/dist/board/chess.d.ts +16 -0
- package/dist/board/chess.d.ts.map +1 -1
- package/dist/board/chess.js +43 -0
- package/dist/board/chess.js.map +1 -1
- package/dist/board/index.d.ts +9 -1
- package/dist/board/index.d.ts.map +1 -1
- package/dist/board/index.js +5 -1
- package/dist/board/index.js.map +1 -1
- package/dist/board/openings.d.ts +58 -0
- package/dist/board/openings.d.ts.map +1 -0
- package/dist/board/openings.js +45 -0
- package/dist/board/openings.js.map +1 -0
- package/dist/board/tablebase.d.ts +118 -0
- package/dist/board/tablebase.d.ts.map +1 -0
- package/dist/board/tablebase.js +414 -0
- package/dist/board/tablebase.js.map +1 -0
- package/dist/board/tourney.d.ts +90 -0
- package/dist/board/tourney.d.ts.map +1 -0
- package/dist/board/tourney.js +1013 -0
- package/dist/board/tourney.js.map +1 -0
- package/dist/core/JavaRandom.d.ts +55 -0
- package/dist/core/JavaRandom.d.ts.map +1 -0
- package/dist/core/JavaRandom.js +81 -0
- package/dist/core/JavaRandom.js.map +1 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -0
- package/dist/core/index.js.map +1 -1
- package/dist/mw_games.global.js +123 -116
- package/dist/rpg/EventRunner.d.ts +7 -0
- package/dist/rpg/EventRunner.d.ts.map +1 -1
- package/dist/rpg/EventRunner.js +6 -0
- package/dist/rpg/EventRunner.js.map +1 -1
- package/dist/rpg/MoveRoute.d.ts +35 -4
- package/dist/rpg/MoveRoute.d.ts.map +1 -1
- package/dist/rpg/MoveRoute.js +40 -11
- package/dist/rpg/MoveRoute.js.map +1 -1
- package/dist/two-d/render/FogLayer.d.ts +68 -0
- package/dist/two-d/render/FogLayer.d.ts.map +1 -0
- package/dist/two-d/render/FogLayer.js +83 -0
- package/dist/two-d/render/FogLayer.js.map +1 -0
- package/dist/two-d/render/LiquidLayer.d.ts +62 -0
- package/dist/two-d/render/LiquidLayer.d.ts.map +1 -0
- package/dist/two-d/render/LiquidLayer.js +102 -0
- package/dist/two-d/render/LiquidLayer.js.map +1 -0
- package/dist/two-d/render/RpgmAutotile.d.ts +42 -0
- package/dist/two-d/render/RpgmAutotile.d.ts.map +1 -1
- package/dist/two-d/render/RpgmAutotile.js +71 -4
- package/dist/two-d/render/RpgmAutotile.js.map +1 -1
- package/dist/two-d/render/TileMap.d.ts +50 -2
- package/dist/two-d/render/TileMap.d.ts.map +1 -1
- package/dist/two-d/render/TileMap.js +120 -2
- package/dist/two-d/render/TileMap.js.map +1 -1
- package/dist/two-d/render/index.d.ts +7 -3
- package/dist/two-d/render/index.d.ts.map +1 -1
- package/dist/two-d/render/index.js +3 -1
- package/dist/two-d/render/index.js.map +1 -1
- package/dist/two-d/ui/Label.d.ts.map +1 -1
- package/dist/two-d/ui/Label.js +11 -2
- package/dist/two-d/ui/Label.js.map +1 -1
- package/dist/two-d/ui/ListView.d.ts +24 -0
- package/dist/two-d/ui/ListView.d.ts.map +1 -1
- package/dist/two-d/ui/ListView.js +97 -4
- package/dist/two-d/ui/ListView.js.map +1 -1
- package/dist/two-d/ui/MessageLog.d.ts +62 -0
- package/dist/two-d/ui/MessageLog.d.ts.map +1 -0
- package/dist/two-d/ui/MessageLog.js +114 -0
- package/dist/two-d/ui/MessageLog.js.map +1 -0
- package/dist/two-d/ui/RadioGroup.d.ts +68 -0
- package/dist/two-d/ui/RadioGroup.d.ts.map +1 -0
- package/dist/two-d/ui/RadioGroup.js +177 -0
- package/dist/two-d/ui/RadioGroup.js.map +1 -0
- package/dist/two-d/ui/TextModel.d.ts +26 -1
- package/dist/two-d/ui/TextModel.d.ts.map +1 -1
- package/dist/two-d/ui/TextModel.js +56 -7
- package/dist/two-d/ui/TextModel.js.map +1 -1
- package/dist/two-d/ui/TextSharpness.d.ts +33 -0
- package/dist/two-d/ui/TextSharpness.d.ts.map +1 -0
- package/dist/two-d/ui/TextSharpness.js +56 -0
- package/dist/two-d/ui/TextSharpness.js.map +1 -0
- package/dist/two-d/ui/index.d.ts +5 -0
- package/dist/two-d/ui/index.d.ts.map +1 -1
- package/dist/two-d/ui/index.js +3 -0
- package/dist/two-d/ui/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +19 -7
- package/sbom.cdx.json +194 -32
- package/tools/build-tablebases.d.mts +22 -0
- package/tools/build-tablebases.mjs +549 -0
- package/tools/compile-openings.d.mts +20 -0
- package/tools/compile-openings.mjs +130 -0
- package/tools/play-uci.d.mts +26 -0
- package/tools/play-uci.mjs +194 -0
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
import { startingChess } from './chess.js';
|
|
2
|
+
const KIND_INDEX = { pawn: 0, knight: 1, bishop: 2, rook: 3, queen: 4, king: 5 };
|
|
3
|
+
const PROMOTION_ORDER = ['queen', 'rook', 'bishop', 'knight'];
|
|
4
|
+
const KNIGHT_STEPS = [
|
|
5
|
+
[1, 2],
|
|
6
|
+
[2, 1],
|
|
7
|
+
[2, -1],
|
|
8
|
+
[1, -2],
|
|
9
|
+
[-1, -2],
|
|
10
|
+
[-2, -1],
|
|
11
|
+
[-2, 1],
|
|
12
|
+
[-1, 2],
|
|
13
|
+
];
|
|
14
|
+
const KING_STEPS = [
|
|
15
|
+
[1, 0],
|
|
16
|
+
[1, 1],
|
|
17
|
+
[0, 1],
|
|
18
|
+
[-1, 1],
|
|
19
|
+
[-1, 0],
|
|
20
|
+
[-1, -1],
|
|
21
|
+
[0, -1],
|
|
22
|
+
[1, -1],
|
|
23
|
+
];
|
|
24
|
+
const DIAGONALS = [
|
|
25
|
+
[1, 1],
|
|
26
|
+
[-1, 1],
|
|
27
|
+
[-1, -1],
|
|
28
|
+
[1, -1],
|
|
29
|
+
];
|
|
30
|
+
const STRAIGHTS = [
|
|
31
|
+
[1, 0],
|
|
32
|
+
[0, 1],
|
|
33
|
+
[-1, 0],
|
|
34
|
+
[0, -1],
|
|
35
|
+
];
|
|
36
|
+
/** the single bit for a square */
|
|
37
|
+
function bit(square) {
|
|
38
|
+
return 1n << BigInt(square);
|
|
39
|
+
}
|
|
40
|
+
/** exact index of a single-bit board: powers of two survive the trip through Number */
|
|
41
|
+
function bitIndex(single) {
|
|
42
|
+
return Math.log2(Number(single));
|
|
43
|
+
}
|
|
44
|
+
function leaperTable(steps) {
|
|
45
|
+
return Array.from({ length: 64 }, (_, square) => {
|
|
46
|
+
const file = square & 7;
|
|
47
|
+
const rank = square >> 3;
|
|
48
|
+
let attacks = 0n;
|
|
49
|
+
for (const [df, dr] of steps) {
|
|
50
|
+
const f = file + df;
|
|
51
|
+
const r = rank + dr;
|
|
52
|
+
if (f >= 0 && f < 8 && r >= 0 && r < 8)
|
|
53
|
+
attacks |= bit(r * 8 + f);
|
|
54
|
+
}
|
|
55
|
+
return attacks;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
const KNIGHT_TABLE = leaperTable(KNIGHT_STEPS);
|
|
59
|
+
const KING_TABLE = leaperTable(KING_STEPS);
|
|
60
|
+
function occupancyOf(board, colorBase) {
|
|
61
|
+
return (board.pieces[colorBase] |
|
|
62
|
+
board.pieces[colorBase + 1] |
|
|
63
|
+
board.pieces[colorBase + 2] |
|
|
64
|
+
board.pieces[colorBase + 3] |
|
|
65
|
+
board.pieces[colorBase + 4] |
|
|
66
|
+
board.pieces[colorBase + 5]);
|
|
67
|
+
}
|
|
68
|
+
/** piece-board index holding the square, or -1 */
|
|
69
|
+
function squareBoard(board, square) {
|
|
70
|
+
const mask = bit(square);
|
|
71
|
+
for (let i = 0; i < 12; i++) {
|
|
72
|
+
if (board.pieces[i] & mask)
|
|
73
|
+
return i;
|
|
74
|
+
}
|
|
75
|
+
return -1;
|
|
76
|
+
}
|
|
77
|
+
/** true when `byWhite` attacks the square, whatever its own king thinks of the move */
|
|
78
|
+
function isAttacked(board, square, byWhite) {
|
|
79
|
+
const by = byWhite ? 0 : 6;
|
|
80
|
+
const file = square & 7;
|
|
81
|
+
const rank = square >> 3;
|
|
82
|
+
//pawns attack one step diagonally towards the other side
|
|
83
|
+
const pawnRank = byWhite ? rank - 1 : rank + 1;
|
|
84
|
+
for (const df of [-1, 1]) {
|
|
85
|
+
const f = file + df;
|
|
86
|
+
if (pawnRank >= 0 && pawnRank < 8 && f >= 0 && f < 8 && board.pieces[by] & bit(pawnRank * 8 + f))
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
if (KNIGHT_TABLE[square] & board.pieces[by + 1])
|
|
90
|
+
return true;
|
|
91
|
+
if (KING_TABLE[square] & board.pieces[by + 5])
|
|
92
|
+
return true;
|
|
93
|
+
//sliders see until something stands in the way
|
|
94
|
+
const rays = [
|
|
95
|
+
{ steps: DIAGONALS, kinds: [2, 4] },
|
|
96
|
+
{ steps: STRAIGHTS, kinds: [3, 4] },
|
|
97
|
+
];
|
|
98
|
+
for (const { steps, kinds } of rays) {
|
|
99
|
+
for (const [df, dr] of steps) {
|
|
100
|
+
let f = file + df;
|
|
101
|
+
let r = rank + dr;
|
|
102
|
+
while (f >= 0 && f < 8 && r >= 0 && r < 8) {
|
|
103
|
+
const found = squareBoard(board, r * 8 + f);
|
|
104
|
+
if (found !== -1) {
|
|
105
|
+
if (found >= by && found < by + 6 && kinds.includes(found - by))
|
|
106
|
+
return true;
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
f += df;
|
|
110
|
+
r += dr;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
function rightBit(side, kingside) {
|
|
117
|
+
return side === 'white' ? (kingside ? 1 : 2) : kingside ? 4 : 8;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Reads a `chess.ts` position onto bitboards: the bridge the differential tests cross
|
|
121
|
+
* in both directions, and the way a FEN reaches the fast board.
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```ts
|
|
125
|
+
* import { bitboardFromChess, bitboardMoves, startingChess } from '@datamoc/mw_games/board';
|
|
126
|
+
*
|
|
127
|
+
* const moves = bitboardMoves(bitboardFromChess(startingChess()));
|
|
128
|
+
* console.log(moves.length); // 20 - the opening position's own count
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
export function bitboardFromChess(state) {
|
|
132
|
+
const pieces = new Array(12).fill(0n);
|
|
133
|
+
const kings = [-1, -1];
|
|
134
|
+
state.board.forEach((piece, square) => {
|
|
135
|
+
if (!piece)
|
|
136
|
+
return;
|
|
137
|
+
const index = (piece.side === 'white' ? 0 : 6) + KIND_INDEX[piece.kind];
|
|
138
|
+
pieces[index] |= bit(square);
|
|
139
|
+
if (piece.kind === 'king')
|
|
140
|
+
kings[piece.side === 'white' ? 0 : 1] = square;
|
|
141
|
+
});
|
|
142
|
+
if (kings[0] === -1 || kings[1] === -1)
|
|
143
|
+
throw new Error('a position without both kings cannot go on bitboards');
|
|
144
|
+
return {
|
|
145
|
+
pieces,
|
|
146
|
+
turn: state.turn,
|
|
147
|
+
castling: (state.castling.whiteKingside ? 1 : 0) |
|
|
148
|
+
(state.castling.whiteQueenside ? 2 : 0) |
|
|
149
|
+
(state.castling.blackKingside ? 4 : 0) |
|
|
150
|
+
(state.castling.blackQueenside ? 8 : 0),
|
|
151
|
+
enPassant: state.enPassant,
|
|
152
|
+
halfmove: 0,
|
|
153
|
+
kings,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* The standard opening array on bitboards, white to move with every right intact.
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```ts
|
|
161
|
+
* import { bitboardMoves, startingBitboard } from '@datamoc/mw_games/board';
|
|
162
|
+
*
|
|
163
|
+
* console.log(bitboardMoves(startingBitboard()).length); // 20 - 16 pawn moves, 4 knight moves
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
export function startingBitboard() {
|
|
167
|
+
return bitboardFromChess(startingChess());
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Every legal move for the side to play, in stable square order: pseudo-moves that leave
|
|
171
|
+
* their own king safe, each tried with `makeMove` and taken back with `unmakeMove`.
|
|
172
|
+
* Castling needs its rights, an empty passage and no check on the way over; en passant
|
|
173
|
+
* pins fall out of the make-and-test filter rather than special-casing.
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```ts
|
|
177
|
+
* import { bitboardMoves, startingBitboard } from '@datamoc/mw_games/board';
|
|
178
|
+
*
|
|
179
|
+
* const moves = bitboardMoves(startingBitboard());
|
|
180
|
+
* console.log(moves.every((move) => move.from >= 0 && move.to < 64)); // true
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
183
|
+
export function bitboardMoves(board) {
|
|
184
|
+
const white = board.turn === 'white';
|
|
185
|
+
const us = white ? 0 : 6;
|
|
186
|
+
const own = occupancyOf(board, us);
|
|
187
|
+
const enemy = occupancyOf(board, us === 0 ? 6 : 0);
|
|
188
|
+
const all = own | enemy;
|
|
189
|
+
const out = [];
|
|
190
|
+
const pseudo = [];
|
|
191
|
+
for (let from = 0; from < 64; from++) {
|
|
192
|
+
if (!(own & bit(from)))
|
|
193
|
+
continue;
|
|
194
|
+
let kind = -1;
|
|
195
|
+
for (let k = 0; k < 6; k++) {
|
|
196
|
+
if (board.pieces[us + k] & bit(from)) {
|
|
197
|
+
kind = k;
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
pseudo.length = 0;
|
|
202
|
+
pseudoMoves(board, from, kind, all, enemy, pseudo);
|
|
203
|
+
for (const move of pseudo) {
|
|
204
|
+
const undo = makeMove(board, move);
|
|
205
|
+
if (!isAttacked(board, board.kings[white ? 0 : 1], !white))
|
|
206
|
+
out.push({ ...move });
|
|
207
|
+
unmakeMove(board, move, undo);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return out;
|
|
211
|
+
}
|
|
212
|
+
/** pseudo-moves for the piece on `from`, ignoring its own king; castling checks rights and passage */
|
|
213
|
+
function pseudoMoves(board, from, kind, all, enemy, out) {
|
|
214
|
+
const white = board.turn === 'white';
|
|
215
|
+
const file = from & 7;
|
|
216
|
+
const rank = from >> 3;
|
|
217
|
+
const push = (to, promotion) => {
|
|
218
|
+
out.push(promotion ? { from, to, promotion } : { from, to });
|
|
219
|
+
};
|
|
220
|
+
const slide = (steps) => {
|
|
221
|
+
for (const [df, dr] of steps) {
|
|
222
|
+
let f = file + df;
|
|
223
|
+
let r = rank + dr;
|
|
224
|
+
while (f >= 0 && f < 8 && r >= 0 && r < 8) {
|
|
225
|
+
const to = r * 8 + f;
|
|
226
|
+
const mask = bit(to);
|
|
227
|
+
if (!(all & mask))
|
|
228
|
+
push(to);
|
|
229
|
+
else {
|
|
230
|
+
if (enemy & mask)
|
|
231
|
+
push(to);
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
f += df;
|
|
235
|
+
r += dr;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
switch (kind) {
|
|
240
|
+
case 0: {
|
|
241
|
+
const dir = white ? 8 : -8;
|
|
242
|
+
const home = white ? 1 : 6;
|
|
243
|
+
const last = white ? 7 : 0;
|
|
244
|
+
const one = from + dir;
|
|
245
|
+
if (one >= 0 && one < 64 && !(all & bit(one))) {
|
|
246
|
+
if (one >> 3 === last) {
|
|
247
|
+
for (const promotion of PROMOTION_ORDER)
|
|
248
|
+
push(one, promotion);
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
push(one);
|
|
252
|
+
const two = from + 2 * dir;
|
|
253
|
+
if (rank === home && !(all & bit(two)))
|
|
254
|
+
push(two);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
for (const df of [-1, 1]) {
|
|
258
|
+
const f = file + df;
|
|
259
|
+
if (f < 0 || f > 7)
|
|
260
|
+
continue;
|
|
261
|
+
const to = from + dir + df;
|
|
262
|
+
if (to < 0 || to >= 64)
|
|
263
|
+
continue;
|
|
264
|
+
const mask = bit(to);
|
|
265
|
+
if (enemy & mask) {
|
|
266
|
+
if (to >> 3 === last) {
|
|
267
|
+
for (const promotion of PROMOTION_ORDER)
|
|
268
|
+
push(to, promotion);
|
|
269
|
+
}
|
|
270
|
+
else
|
|
271
|
+
push(to);
|
|
272
|
+
}
|
|
273
|
+
else if (to === board.enPassant)
|
|
274
|
+
push(to);
|
|
275
|
+
}
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
278
|
+
case 1: {
|
|
279
|
+
let targets = KNIGHT_TABLE[from] & ~occupancyOf(board, white ? 0 : 6);
|
|
280
|
+
while (targets) {
|
|
281
|
+
const single = targets & -targets;
|
|
282
|
+
push(bitIndex(single));
|
|
283
|
+
targets ^= single;
|
|
284
|
+
}
|
|
285
|
+
break;
|
|
286
|
+
}
|
|
287
|
+
case 2:
|
|
288
|
+
slide(DIAGONALS);
|
|
289
|
+
break;
|
|
290
|
+
case 3:
|
|
291
|
+
slide(STRAIGHTS);
|
|
292
|
+
break;
|
|
293
|
+
case 4:
|
|
294
|
+
slide(DIAGONALS);
|
|
295
|
+
slide(STRAIGHTS);
|
|
296
|
+
break;
|
|
297
|
+
case 5: {
|
|
298
|
+
let targets = KING_TABLE[from] & ~occupancyOf(board, white ? 0 : 6);
|
|
299
|
+
//never capture the other king: kings are never adjacent after a legal move
|
|
300
|
+
targets &= ~board.pieces[white ? 11 : 5];
|
|
301
|
+
while (targets) {
|
|
302
|
+
const single = targets & -targets;
|
|
303
|
+
push(bitIndex(single));
|
|
304
|
+
targets ^= single;
|
|
305
|
+
}
|
|
306
|
+
const home = white ? 0 : 56;
|
|
307
|
+
const rights = board.castling;
|
|
308
|
+
const kingside = white ? rights & 1 : rights & 4;
|
|
309
|
+
const queenside = white ? rights & 2 : rights & 8;
|
|
310
|
+
if (from === home + 4 && !isAttacked(board, from, !white)) {
|
|
311
|
+
if (kingside &&
|
|
312
|
+
!(all & bit(home + 5)) &&
|
|
313
|
+
!(all & bit(home + 6)) &&
|
|
314
|
+
!isAttacked(board, home + 5, !white) &&
|
|
315
|
+
!isAttacked(board, home + 6, !white)) {
|
|
316
|
+
push(home + 6);
|
|
317
|
+
}
|
|
318
|
+
if (queenside &&
|
|
319
|
+
!(all & bit(home + 3)) &&
|
|
320
|
+
!(all & bit(home + 2)) &&
|
|
321
|
+
!(all & bit(home + 1)) &&
|
|
322
|
+
!isAttacked(board, home + 3, !white) &&
|
|
323
|
+
!isAttacked(board, home + 2, !white)) {
|
|
324
|
+
push(home + 2);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Plays a move, mutating the position, and returns what `unmakeMove` needs to take it
|
|
333
|
+
* back. Special moves are read off the position rather than flagged on the move: a pawn
|
|
334
|
+
* onto the en passant square captures the pawn behind it, a king stepping two squares
|
|
335
|
+
* swings its rook, a pawn stride of sixteen leaves a square behind it.
|
|
336
|
+
*
|
|
337
|
+
* @example
|
|
338
|
+
* ```ts
|
|
339
|
+
* import { bitboardMoves, makeMove, startingBitboard, unmakeMove } from '@datamoc/mw_games/board';
|
|
340
|
+
*
|
|
341
|
+
* const board = startingBitboard();
|
|
342
|
+
* const move = bitboardMoves(board)[0];
|
|
343
|
+
* const undo = makeMove(board, move);
|
|
344
|
+
* console.log(board.turn); // 'black' - the move is played
|
|
345
|
+
* unmakeMove(board, move, undo);
|
|
346
|
+
* ```
|
|
347
|
+
*/
|
|
348
|
+
export function makeMove(board, move) {
|
|
349
|
+
const white = board.turn === 'white';
|
|
350
|
+
const us = white ? 0 : 1;
|
|
351
|
+
const colorBase = us * 6;
|
|
352
|
+
const fromBit = bit(move.from);
|
|
353
|
+
const toBit = bit(move.to);
|
|
354
|
+
let kind = -1;
|
|
355
|
+
for (let k = 0; k < 6; k++) {
|
|
356
|
+
if (board.pieces[colorBase + k] & fromBit) {
|
|
357
|
+
kind = k;
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
if (kind === -1)
|
|
362
|
+
throw new Error(`no piece on ${move.from} to move`);
|
|
363
|
+
const undo = {
|
|
364
|
+
captured: null,
|
|
365
|
+
castling: board.castling,
|
|
366
|
+
enPassant: board.enPassant,
|
|
367
|
+
halfmove: board.halfmove,
|
|
368
|
+
kingSquare: board.kings[us],
|
|
369
|
+
};
|
|
370
|
+
const themBase = (1 - us) * 6;
|
|
371
|
+
const dir = white ? 8 : -8;
|
|
372
|
+
//a pawn onto the en passant square takes the pawn behind it, not the empty square
|
|
373
|
+
let capturedSquare = move.to;
|
|
374
|
+
if (kind === 0 && move.to === board.enPassant)
|
|
375
|
+
capturedSquare = move.to - dir;
|
|
376
|
+
const capturedBit = bit(capturedSquare);
|
|
377
|
+
for (let k = 0; k < 6; k++) {
|
|
378
|
+
if (board.pieces[themBase + k] & capturedBit) {
|
|
379
|
+
undo.captured = { color: (1 - us), kind: k };
|
|
380
|
+
board.pieces[themBase + k] ^= capturedBit;
|
|
381
|
+
break;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
//castling rights die with the king's first step, a rook's, or a captured rook's
|
|
385
|
+
const home = white ? 0 : 56;
|
|
386
|
+
const themHome = white ? 56 : 0;
|
|
387
|
+
if (kind === 5)
|
|
388
|
+
board.castling &= ~(rightBit(board.turn, true) | rightBit(board.turn, false));
|
|
389
|
+
if (kind === 3 && (move.from === home || move.from === home + 7)) {
|
|
390
|
+
board.castling &= ~rightBit(board.turn, move.from === home + 7);
|
|
391
|
+
}
|
|
392
|
+
if (undo.captured?.kind === 3 && (capturedSquare === themHome || capturedSquare === themHome + 7)) {
|
|
393
|
+
board.castling &= ~rightBit(white ? 'black' : 'white', capturedSquare === themHome + 7);
|
|
394
|
+
}
|
|
395
|
+
board.pieces[colorBase + kind] ^= fromBit;
|
|
396
|
+
if (move.promotion)
|
|
397
|
+
board.pieces[colorBase + KIND_INDEX[move.promotion]] |= toBit;
|
|
398
|
+
else
|
|
399
|
+
board.pieces[colorBase + kind] |= toBit;
|
|
400
|
+
if (kind === 5 && Math.abs(move.to - move.from) === 2) {
|
|
401
|
+
const rook = colorBase + 3;
|
|
402
|
+
if (move.to > move.from)
|
|
403
|
+
board.pieces[rook] ^= bit(home + 7) | bit(home + 5);
|
|
404
|
+
else
|
|
405
|
+
board.pieces[rook] ^= bit(home) | bit(home + 3);
|
|
406
|
+
}
|
|
407
|
+
board.enPassant = kind === 0 && Math.abs(move.to - move.from) === 16 ? (move.from + move.to) / 2 : null;
|
|
408
|
+
board.halfmove = kind === 0 || undo.captured ? 0 : board.halfmove + 1;
|
|
409
|
+
if (kind === 5)
|
|
410
|
+
board.kings[us] = move.to;
|
|
411
|
+
board.turn = white ? 'black' : 'white';
|
|
412
|
+
return undo;
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Takes back exactly what `makeMove` played: the mover returns, the taken piece (or the
|
|
416
|
+
* en passant pawn behind the landing square) is restored, and rights, en passant
|
|
417
|
+
* square, halfmove clock and king square come back from the undo.
|
|
418
|
+
*
|
|
419
|
+
* @example
|
|
420
|
+
* ```ts
|
|
421
|
+
* import { bitboardMoves, makeMove, startingBitboard, unmakeMove } from '@datamoc/mw_games/board';
|
|
422
|
+
*
|
|
423
|
+
* const board = startingBitboard();
|
|
424
|
+
* const move = bitboardMoves(board)[0];
|
|
425
|
+
* const undo = makeMove(board, move);
|
|
426
|
+
* unmakeMove(board, move, undo);
|
|
427
|
+
* console.log(board.turn, bitboardMoves(board).length); // 'white' 20 - taken back whole
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
430
|
+
export function unmakeMove(board, move, undo) {
|
|
431
|
+
board.turn = board.turn === 'white' ? 'black' : 'white';
|
|
432
|
+
const white = board.turn === 'white';
|
|
433
|
+
const us = white ? 0 : 1;
|
|
434
|
+
const colorBase = us * 6;
|
|
435
|
+
const toBit = bit(move.to);
|
|
436
|
+
//a promotion leaves a pawn to restore, anything else the piece standing on `to`
|
|
437
|
+
const kind = move.promotion
|
|
438
|
+
? 0
|
|
439
|
+
: (() => {
|
|
440
|
+
for (let k = 0; k < 6; k++) {
|
|
441
|
+
if (board.pieces[colorBase + k] & toBit)
|
|
442
|
+
return k;
|
|
443
|
+
}
|
|
444
|
+
throw new Error(`nothing on ${move.to} to take back`);
|
|
445
|
+
})();
|
|
446
|
+
if (move.promotion)
|
|
447
|
+
board.pieces[colorBase + KIND_INDEX[move.promotion]] ^= toBit;
|
|
448
|
+
else
|
|
449
|
+
board.pieces[colorBase + kind] ^= toBit;
|
|
450
|
+
board.pieces[colorBase + kind] |= bit(move.from);
|
|
451
|
+
if (kind === 5 && Math.abs(move.to - move.from) === 2) {
|
|
452
|
+
const home = white ? 0 : 56;
|
|
453
|
+
const rook = colorBase + 3;
|
|
454
|
+
if (move.to > move.from)
|
|
455
|
+
board.pieces[rook] ^= bit(home + 7) | bit(home + 5);
|
|
456
|
+
else
|
|
457
|
+
board.pieces[rook] ^= bit(home) | bit(home + 3);
|
|
458
|
+
}
|
|
459
|
+
if (undo.captured) {
|
|
460
|
+
const dir = white ? 8 : -8;
|
|
461
|
+
const square = kind === 0 && move.to === undo.enPassant ? move.to - dir : move.to;
|
|
462
|
+
board.pieces[(1 - us) * 6 + undo.captured.kind] |= bit(square);
|
|
463
|
+
}
|
|
464
|
+
board.castling = undo.castling;
|
|
465
|
+
board.enPassant = undo.enPassant;
|
|
466
|
+
board.halfmove = undo.halfmove;
|
|
467
|
+
board.kings[us] = undo.kingSquare;
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Move-generation node count: 1 at depth 0, else the sum over every legal move. The
|
|
471
|
+
* position is played and taken back as it goes, so it reads identical afterwards.
|
|
472
|
+
* Counts match the published perft numbers, which is the whole point: a wrong move
|
|
473
|
+
* generator cannot hide from them.
|
|
474
|
+
*
|
|
475
|
+
* @example
|
|
476
|
+
* ```ts
|
|
477
|
+
* import { perft, startingBitboard } from '@datamoc/mw_games/board';
|
|
478
|
+
*
|
|
479
|
+
* console.log(perft(startingBitboard(), 2)); // 400 - the opening's two-ply count
|
|
480
|
+
* ```
|
|
481
|
+
*/
|
|
482
|
+
export function perft(board, depth) {
|
|
483
|
+
if (!Number.isInteger(depth) || depth < 0)
|
|
484
|
+
throw new RangeError('perft depth must be a non-negative integer');
|
|
485
|
+
if (depth === 0)
|
|
486
|
+
return 1;
|
|
487
|
+
let nodes = 0;
|
|
488
|
+
for (const move of bitboardMoves(board)) {
|
|
489
|
+
const undo = makeMove(board, move);
|
|
490
|
+
nodes += perft(board, depth - 1);
|
|
491
|
+
unmakeMove(board, move, undo);
|
|
492
|
+
}
|
|
493
|
+
return nodes;
|
|
494
|
+
}
|
|
495
|
+
//# sourceMappingURL=bitboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bitboard.js","sourceRoot":"","sources":["../../src/board/bitboard.ts"],"names":[],"mappings":"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"}
|
package/dist/board/chess.d.ts
CHANGED
|
@@ -61,6 +61,22 @@ export declare function sq(name: string): ChessSquare;
|
|
|
61
61
|
* ```
|
|
62
62
|
*/
|
|
63
63
|
export declare function squareName(sq: ChessSquare): string;
|
|
64
|
+
/**
|
|
65
|
+
* The position half of FEN: placement, side to move, castling rights and en passant
|
|
66
|
+
* square, without either move clock. Two positions share a key exactly when the same
|
|
67
|
+
* moves are legal from both, which is what makes it the lookup key for an opening
|
|
68
|
+
* book (`board/openings.ts` builds and probes keys with this function on both sides,
|
|
69
|
+
* so the en passant square is taken as stored rather than re-derived).
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* import { positionKey, startingChess } from '@datamoc/mw_games/board';
|
|
74
|
+
*
|
|
75
|
+
* console.log(positionKey(startingChess()));
|
|
76
|
+
* // 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -'
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export declare function positionKey(state: ChessState): string;
|
|
64
80
|
/**
|
|
65
81
|
* Reads a position in Forsyth-Edwards Notation - the shape puzzles come in.
|
|
66
82
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chess.d.ts","sourceRoot":"","sources":["../../src/board/chess.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAC1C,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAEjF,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,SAAS,CAAC;CAChB;AAED,0DAA0D;AAC1D,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC;AAEjC,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAEnE,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,WAAW,CAAC;IAClB,EAAE,EAAE,WAAW,CAAC;IAChB,SAAS,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC7B,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IAC1B,KAAK,EAAE,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAChC,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,aAAa,CAAC;IACxB,uEAAuE;IACvE,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,YAAY,GAAG,YAAY,GAAG,WAAW,CAAC;AAEhF;;;;;;;;;;;GAWG;AACH,wBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAO5C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAElD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAqDhD;AAkBD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,IAAI,UAAU,CAe1C;AAED,mEAAmE;AACnE;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAOxD;AA6FD;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAEnE;AA+LD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,EAAE,CAYzD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAelE;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAIzD"}
|
|
1
|
+
{"version":3,"file":"chess.d.ts","sourceRoot":"","sources":["../../src/board/chess.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAC1C,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAEjF,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,SAAS,CAAC;CAChB;AAED,0DAA0D;AAC1D,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC;AAEjC,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAEnE,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,WAAW,CAAC;IAClB,EAAE,EAAE,WAAW,CAAC;IAChB,SAAS,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC7B,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IAC1B,KAAK,EAAE,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAChC,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,aAAa,CAAC;IACxB,uEAAuE;IACvE,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,YAAY,GAAG,YAAY,GAAG,WAAW,CAAC;AAEhF;;;;;;;;;;;GAWG;AACH,wBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAO5C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAElD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CA2BrD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAqDhD;AAkBD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,IAAI,UAAU,CAe1C;AAED,mEAAmE;AACnE;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAOxD;AA6FD;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAEnE;AA+LD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,EAAE,CAYzD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAelE;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAIzD"}
|
package/dist/board/chess.js
CHANGED
|
@@ -42,6 +42,49 @@ export function sq(name) {
|
|
|
42
42
|
export function squareName(sq) {
|
|
43
43
|
return String.fromCharCode(97 + (sq & 7)) + String.fromCharCode(49 + (sq >> 3));
|
|
44
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* The position half of FEN: placement, side to move, castling rights and en passant
|
|
47
|
+
* square, without either move clock. Two positions share a key exactly when the same
|
|
48
|
+
* moves are legal from both, which is what makes it the lookup key for an opening
|
|
49
|
+
* book (`board/openings.ts` builds and probes keys with this function on both sides,
|
|
50
|
+
* so the en passant square is taken as stored rather than re-derived).
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* import { positionKey, startingChess } from '@datamoc/mw_games/board';
|
|
55
|
+
*
|
|
56
|
+
* console.log(positionKey(startingChess()));
|
|
57
|
+
* // 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -'
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export function positionKey(state) {
|
|
61
|
+
const rows = [];
|
|
62
|
+
for (let rank = 7; rank >= 0; rank--) {
|
|
63
|
+
let row = '';
|
|
64
|
+
let empty = 0;
|
|
65
|
+
for (let file = 0; file < 8; file++) {
|
|
66
|
+
const piece = state.board[rank * 8 + file];
|
|
67
|
+
if (!piece) {
|
|
68
|
+
empty++;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (empty > 0) {
|
|
72
|
+
row += String(empty);
|
|
73
|
+
empty = 0;
|
|
74
|
+
}
|
|
75
|
+
const letter = { pawn: 'p', knight: 'n', bishop: 'b', rook: 'r', queen: 'q', king: 'k' }[piece.kind];
|
|
76
|
+
row += piece.side === 'white' ? letter.toUpperCase() : letter;
|
|
77
|
+
}
|
|
78
|
+
if (empty > 0)
|
|
79
|
+
row += String(empty);
|
|
80
|
+
rows.push(row);
|
|
81
|
+
}
|
|
82
|
+
const rights = (state.castling.whiteKingside ? 'K' : '') +
|
|
83
|
+
(state.castling.whiteQueenside ? 'Q' : '') +
|
|
84
|
+
(state.castling.blackKingside ? 'k' : '') +
|
|
85
|
+
(state.castling.blackQueenside ? 'q' : '');
|
|
86
|
+
return `${rows.join('/')} ${state.turn === 'white' ? 'w' : 'b'} ${rights || '-'} ${state.enPassant === null ? '-' : squareName(state.enPassant)}`;
|
|
87
|
+
}
|
|
45
88
|
/**
|
|
46
89
|
* Reads a position in Forsyth-Edwards Notation - the shape puzzles come in.
|
|
47
90
|
*
|