Skip to content

Commit cb64b40

Browse files
authored
Merge pull request #19 from jwyce/tracking-ids
2 parents 35c4e69 + e2726a2 commit cb64b40

File tree

6 files changed

+1076
-11
lines changed

6 files changed

+1076
-11
lines changed

.changeset/four-pears-sneeze.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
'gungi.js': minor
3+
---
4+
5+
Implements unique piece identifiers using `type-color-number` format
6+
that persist across all moves, captures, and state changes.
7+
8+
**Parallel ID Registry**: Chose to maintain existing FEN-based
9+
architecture while adding separate `PieceIdRegistry` class. This
10+
preserves backward compatibility while enabling advanced ID features.
11+
12+
**Snapshot/Restore Pattern**: Since moves regenerate state from FEN
13+
(losing IDs), implemented snapshot-before/restore-after pattern in
14+
`move()` method. Captures ID mappings before FEN reinitialization,
15+
then intelligently restores them accounting for piece movements.
16+
17+
**Individual Hand Tracking**: Extended `HandPiece` with `ids?: string[]`
18+
to track individual pieces within aggregate counts. Enables specific
19+
piece selection for arata moves while maintaining existing count-based API.
20+
21+
**Auto-Assignment**: IDs assigned automatically on game initialization.
22+
All existing code works unchanged, IDs are purely additive enhancement.
23+
24+
- `getPieceId()`, `getPieceById()` - board piece lookup
25+
- `getHandPieceIds()`, `getHandWithIds()` - hand piece access
26+
- `getBoardWithIds()` - complete board state with IDs
27+
- `getHandPieceId()` - specific hand piece selection
28+
29+
Addresses the fundamental challenge of maintaining piece identity
30+
across the library's FEN-based state management system.

README.md

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ gungi.js is a TypeScript gungi library for the strategy game from the HUNTER×HU
88
Credit to these two reddit posts from [u/magickirua](https://www.reddit.com/r/HunterXHunter/comments/uqrtct/gungi_the_official_rules) and [u/MythicalTenshi](https://www.reddit.com/r/HunterXHunter/comments/105f43g/comment/j3evkkq)
99
which translate the rule book.
1010

11-
gungi.js is used for move generation/validation, piece placement/movement, and endgame detection - basically everything but the AI.
11+
gungi.js is used for move generation/validation, piece placement/movement, piece ID tracking, and endgame detection - basically everything but the AI.
1212

1313
## Installation
1414

@@ -299,6 +299,19 @@ gungi.getDraftingRights('b');
299299
// -> true
300300
```
301301

302+
### .getBoardWithIds()
303+
304+
Returns a copy of the 3D board tensor with all piece ID information included. Each piece object includes an `id` field with its unique identifier.
305+
306+
```ts
307+
const gungi = new Gungi(BEGINNER_POSITION);
308+
const boardWithIds = gungi.getBoardWithIds();
309+
310+
// Access piece with ID
311+
const piece = boardWithIds[6][0][0]; // 7-1 square
312+
// -> { square: '7-1', tier: 1, type: '兵', color: 'w', id: '兵-w-1' }
313+
```
314+
302315
### .getTop(square)
303316

304317
Returns the top piece of the tower on the square. Returns `undefined` if the square is empty.
@@ -312,6 +325,89 @@ gungi.get('7-3');
312325
// -> undefined
313326
```
314327

328+
### .getHandPieceId(type, color, index)
329+
330+
Returns the ID of a specific hand piece by type, color, and index. Useful for selecting which specific piece to play when multiple pieces of the same type are in hand.
331+
332+
```ts
333+
const gungi = new Gungi(BEGINNER_POSITION);
334+
335+
// Get ID of first major general in white's hand
336+
const firstId = gungi.getHandPieceId('', 'w', 0);
337+
// -> '小-w-1'
338+
339+
// Get ID of second major general (if exists)
340+
const secondId = gungi.getHandPieceId('', 'w', 1);
341+
// -> '小-w-2' or undefined if only one exists
342+
```
343+
344+
### .getHandPieceIds(type?, color?)
345+
346+
Returns an array of all hand piece IDs. Can optionally filter by piece type and color.
347+
348+
```ts
349+
const gungi = new Gungi(BEGINNER_POSITION);
350+
351+
// Get all white major general IDs
352+
const whiteGeneralIds = gungi.getHandPieceIds('', 'w');
353+
// -> ['小-w-1', '小-w-2']
354+
355+
// Get all hand piece IDs
356+
const allHandIds = gungi.getHandPieceIds();
357+
// -> ['小-w-1', '小-w-2', '槍-w-1', ..., '小-b-1', '小-b-2', ...]
358+
```
359+
360+
### .getHandWithIds(color?)
361+
362+
Returns hand pieces with individual ID arrays included. Similar to `.hand()` but includes the `ids` field for each hand piece.
363+
364+
```ts
365+
const gungi = new Gungi(BEGINNER_POSITION);
366+
367+
const whiteHandWithIds = gungi.getHandWithIds('w');
368+
// -> [
369+
// { type: '小', count: 2, color: 'w', ids: ['小-w-1', '小-w-2'] },
370+
// { type: '槍', count: 3, color: 'w', ids: ['槍-w-1', '槍-w-2', '槍-w-3'] },
371+
// ...
372+
// ]
373+
```
374+
375+
### .getPieceById(id)
376+
377+
Returns the piece object with the specified ID. Searches the entire board to find the piece.
378+
379+
```ts
380+
const gungi = new Gungi(BEGINNER_POSITION);
381+
382+
// Find piece by its unique ID
383+
const piece = gungi.getPieceById('兵-w-1');
384+
// -> { square: '7-1', tier: 1, type: '兵', color: 'w', id: '兵-w-1' }
385+
386+
// Returns undefined if piece doesn't exist or was captured
387+
const nonexistent = gungi.getPieceById('兵-w-999');
388+
// -> undefined
389+
```
390+
391+
### .getPieceId(square, tier?)
392+
393+
Returns the unique ID of the piece at the specified location. If tier is omitted, returns the ID of the top piece.
394+
395+
```ts
396+
const gungi = new Gungi(BEGINNER_POSITION);
397+
398+
// Get ID of top piece at square
399+
const topPieceId = gungi.getPieceId('7-1');
400+
// -> '兵-w-1'
401+
402+
// Get ID of piece at specific tier
403+
const specificTierId = gungi.getPieceId('7-4', 2); // After stacking
404+
// -> '砦-w-1'
405+
406+
// Returns undefined if no piece at location
407+
const emptyId = gungi.getPieceId('5-5');
408+
// -> undefined
409+
```
410+
315411
### .hand(color)
316412

317413
Returns a list of pieces in players' hand. Color is an optional parameter to filter pieces by player color

0 commit comments

Comments
 (0)