chess4js 1.0.0-beta.8 → 1.0.0-beta.9a

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/README.md CHANGED
@@ -27,7 +27,7 @@ hundred milliseconds on modern machines.
27
27
  The library provides predefined instances for every square (A1, B1, ..., H8). You can import them directly:
28
28
 
29
29
  ```js
30
- import { A1, G4, D6 } from "chess4js";
30
+ import {A1, G4, D6} from "chess4js";
31
31
  ```
32
32
 
33
33
  ## Piece
@@ -56,7 +56,7 @@ import {WP, BK, WQ, BN} from "chess4js"
56
56
  exist: `WHITE` and `BLACK`. You can import them directly:
57
57
 
58
58
  ```js
59
- import { WHITE, BLACK } from "chess4js"
59
+ import {WHITE, BLACK} from "chess4js"
60
60
  ```
61
61
 
62
62
  ## Bitboard
@@ -118,7 +118,7 @@ A non directly instantiable class that represents a move made on the board.
118
118
  ### Example
119
119
 
120
120
  ```js
121
- import { moveOf } from "chess4js"
121
+ import {moveOf} from "chess4js"
122
122
 
123
123
  const myMove = moveOf("e2e4");
124
124
  ```
@@ -129,9 +129,9 @@ Represents a specific board state. Instances of this class are immutable. Modify
129
129
  inconsistent behavior. Use factory methods to generate new positions.
130
130
 
131
131
  ```js
132
- import { startpos, positionOf } from "chess4js"
132
+ import {startpos, positionOf} from "chess4js"
133
133
 
134
- const initialPosition = startpos();
134
+ const initialPosition = startpos();
135
135
  const somePosition = positionOf("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
136
136
 
137
137
  ```
@@ -177,6 +177,7 @@ const somePosition = positionOf("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w K
177
177
  | `moveFromString` | `move`: `String`, `notation`: `Notation` default `UCI` | `Position` | Retrieves the new Position that results from executing the move specified in the given notation. Throws a MoveException if the move is not legal. If no notation is provided, UCI notation is assumed. |
178
178
  | `toString` | None | `string` | retrieves a nice string representation |
179
179
  | `flipSide` | None | `Position` | Creates a new Position identical to the current one, but with the active side toggled. |
180
+ | `transpositionId` | None | `String` | Generates a unique string identifier for the current position, suitable for use as a key in a transposition table. |
180
181
 
181
182
  ### Factories
182
183
 
@@ -247,6 +248,7 @@ For the `Node` class:
247
248
  | `endLineComment` | `Nullable<string>` | The end-of-line comment for the node, which follows a semicolon ; and goes until the end of the line. |
248
249
  | `suffixAnnotations` | `Nullable<ReadonlyArray<number>>` | The list of suffix annotations (NAGs) for the node. |
249
250
  | `parent` | `Nullable<Node>` | The parent node. It can only be null when it is the root node, which evidently cannot have a parent. |
251
+ | `id` | `number` | An id for the node. |
250
252
 
251
253
  ### Methods
252
254
 
@@ -288,7 +290,7 @@ For the `Node` class
288
290
  ### Example
289
291
 
290
292
  ```js
291
- import { strictMatch } from "chess4js";
293
+ import {strictMatch} from "chess4js";
292
294
 
293
295
  const myGame = strictMatch(() => "someId");
294
296
  myGame.setTag("white", "foo")
@@ -298,12 +300,12 @@ myGame.setTag("site", "foobared place")
298
300
  myGame.setTag("date", "1999.06.10")
299
301
 
300
302
  myGame.root.appendMove("e4")
301
- .appendMove("e5")
302
- .appendMove("Bc4")
303
- .appendMove("Nc6")
304
- .appendMove("Qh5")
305
- .appendMove("Nf6")
306
- .appendMove("Qxf7#")
303
+ .appendMove("e5")
304
+ .appendMove("Bc4")
305
+ .appendMove("Nc6")
306
+ .appendMove("Qh5")
307
+ .appendMove("Nf6")
308
+ .appendMove("Qxf7#")
307
309
 
308
310
  ```
309
311
 
@@ -321,7 +323,7 @@ A non-instantiable class that provides basic information about ECO classificatio
321
323
  ### Example
322
324
 
323
325
  ```javascript
324
- import { strictMatch } from "chess4js";
326
+ import {strictMatch} from "chess4js";
325
327
 
326
328
  const myGame = strictMatch(() => "someId");
327
329
  myGame.setTag("white", "foo")
@@ -331,14 +333,14 @@ myGame.setTag("site", "foobared place")
331
333
  myGame.setTag("date", "1999.06.10")
332
334
 
333
335
  myGame.root.appendMove("e4")
334
- .appendMove("c5")
335
- .appendMove("Nf3")
336
- .appendMove("e6")
337
- .appendMove("d4")
338
- .appendMove("cxd4")
339
- .appendMove("Nxd4")
340
- .appendMove("Qb6")
341
-
336
+ .appendMove("c5")
337
+ .appendMove("Nf3")
338
+ .appendMove("e6")
339
+ .appendMove("d4")
340
+ .appendMove("cxd4")
341
+ .appendMove("Nxd4")
342
+ .appendMove("Qb6")
343
+
342
344
  const ecoInfo = myGame.ecoInfo.eco // "B40"
343
345
  ```
344
346
 
@@ -368,9 +370,9 @@ Represents a score in a tournament. It can't be directly instantiated, you need
368
370
  #### Example
369
371
 
370
372
  ```javascript
371
- import { scoreOf } from "chess4js";
373
+ import {scoreOf} from "chess4js";
372
374
 
373
- const hightScore = scoreOf("2.5");
375
+ const hightScore = scoreOf("2.5");
374
376
  const lowScore = scoreOf("0.0");
375
377
 
376
378
  hightScore.compareTo(lowScore) // 1
@@ -404,7 +406,7 @@ factory.
404
406
  #### Example
405
407
 
406
408
  ```javascript
407
- import { playerOf } from "chess4js";
409
+ import {playerOf} from "chess4js";
408
410
 
409
411
  const foo = playerOf("foo", 1600);
410
412
  const bar = playerOf("bar", 1600);
@@ -422,6 +424,7 @@ factory.
422
424
  | `white` | `Nullable<Player>` | The white player. |
423
425
  | `black` | `Nullable<Player>` | The black player. |
424
426
  | `outcome` | `string` | The outcome of the match, can be "1-0", "0-1", "1/2-1/2", "in game" or "suspended" |
427
+ | `id` | `Nullable<string>` | An id for the match |
425
428
 
426
429
  #### Factories
427
430
 
@@ -432,7 +435,7 @@ factory.
432
435
  #### Example
433
436
 
434
437
  ```javascript
435
- import { matchOf, playerOf } from "chess4js";
438
+ import {matchOf, playerOf} from "chess4js";
436
439
 
437
440
  const white = playerOf("foo", 1600);
438
441
  const black = playerOf("bar", 1600);
@@ -448,16 +451,17 @@ are two types: arena and swiss instances. Both are further detailed in the examp
448
451
 
449
452
  #### Properties
450
453
 
451
- | Property | Type | Description |
452
- |-------------------|-------------------------|------------------------------------------------------------------------------------------------------------------------------------------|
453
- | `impactFactor` | `number` | The K-factor that determines how much a single match affects the rating. A higher value leads to faster rating changes. Default is 32.0. |
454
- | `rangeFactor` | `number` | The scale factor used to determine win probability. Default is 400.0. |
455
- | `logisticBase` | `number` | The base of the exponent in the logistic function. Default is 10. |
456
- | `tiebreakers` | `Array<string>` | The strategy for breaking ties in the leaderboard. |
457
- | `leaderboard` | `ReadonlyArray<Player>` | Current player standings, ordered by score and tie-breakers. |
458
- | `completed` | `boolean` | Whether the tournament has reached its conclusion. |
459
- | `activeMatches` | `ReadonlyArray<Match>` | Current matches being played. |
460
- | `finishedMatches` | `ReadonlyArray<Match>` | All concluded matches in the tournament history. |
454
+ | Property | Type | Description |
455
+ |-------------------|--------------------------|------------------------------------------------------------------------------------------------------------------------------------------|
456
+ | `impactFactor` | `number` | The K-factor that determines how much a single match affects the rating. A higher value leads to faster rating changes. Default is 32.0. |
457
+ | `rangeFactor` | `number` | The scale factor used to determine win probability. Default is 400.0. |
458
+ | `logisticBase` | `number` | The base of the exponent in the logistic function. Default is 10. |
459
+ | `tiebreakers` | `Array<string>` | The strategy for breaking ties in the leaderboard. |
460
+ | `leaderboard` | `ReadonlyArray<Player>` | Current player standings, ordered by score and tie-breakers. |
461
+ | `completed` | `boolean` | Whether the tournament has reached its conclusion. |
462
+ | `activeMatches` | `ReadonlyArray<Match>` | Current matches being played. |
463
+ | `finishedMatches` | `ReadonlyArray<Match>` | All concluded matches in the tournament history. |
464
+ | `idGenerator` | `Nullable<() => string>` | Unique ID generator for assigning identifiers to match objects. |
461
465
 
462
466
  #### Methods
463
467
 
@@ -469,9 +473,9 @@ are two types: arena and swiss instances. Both are further detailed in the examp
469
473
 
470
474
  #### Factories
471
475
 
472
- | Function | Arguments | Return Type | Description |
473
- |--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|-------------------------------------------------------------------------------|
474
- | `tournament` | `type`: `string`, `tiebreakers`: `Array<String>` default `["fidePerformance", "buchholz", "progressive", "sonnebornBerger"]`, `impactFactor`: `number` default `32`, `rangeFactor`: `number` default `400`, `logisticBase`: `number` default `10` | `Tournament` | Factory function to create a Tournament instance based on the specified type. |
476
+ | Function | Arguments | Return Type | Description |
477
+ |--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|-------------------------------------------------------------------------------|
478
+ | `tournament` | `type`: `string`, `tiebreakers`: `Array<String>` default `["fidePerformance", "buchholz", "progressive", "sonnebornBerger"]`, `impactFactor`: `number` default `32`, `rangeFactor`: `number` default `400`, `logisticBase`: `number` default `10`, `idGenerator`: `Nullable<() => string>` default `null` | `Tournament` | Factory function to create a Tournament instance based on the specified type. |
475
479
 
476
480
  #### Examples
477
481
 
@@ -482,74 +486,74 @@ behavior of a Swiss tournament, having a fixed number of rounds, for example. Ad
482
486
  before the next one can be generated.
483
487
 
484
488
  ```javascript
485
- import { tournament, playerOf } from "./chess4js.mjs";
489
+ import {tournament, playerOf} from "./chess4js.mjs";
486
490
 
487
491
  const myTournament = tournament("swiss");
488
492
 
489
493
  function randomInt(min, max) {
490
- return Math.floor(Math.random() * (max - min) + min);
494
+ return Math.floor(Math.random() * (max - min) + min);
491
495
  }
492
496
 
493
497
  function runMatch(match) {
494
- const ratio = (match.white.currentElo - match.black.currentElo) / 100;
495
- const random = Math.random();
496
- if (match.white.currentElo >= match.black.currentElo) {
497
- if (random < ratio) {
498
- match.outcome = "1-0";
499
- } else if (random == ratio) {
500
- match.outcome = "1/2-1/2";
501
- } else {
502
- match.outcome = "0-1";
503
- }
504
- } else {
505
- if (random < ratio) {
506
- match.outcome = "0-1";
507
- } else if (random == ratio) {
508
- match.outcome = "1/2-1/2";
498
+ const ratio = (match.white.currentElo - match.black.currentElo) / 100;
499
+ const random = Math.random();
500
+ if (match.white.currentElo >= match.black.currentElo) {
501
+ if (random < ratio) {
502
+ match.outcome = "1-0";
503
+ } else if (random == ratio) {
504
+ match.outcome = "1/2-1/2";
505
+ } else {
506
+ match.outcome = "0-1";
507
+ }
509
508
  } else {
510
- match.outcome = "1-0";
509
+ if (random < ratio) {
510
+ match.outcome = "0-1";
511
+ } else if (random == ratio) {
512
+ match.outcome = "1/2-1/2";
513
+ } else {
514
+ match.outcome = "1-0";
515
+ }
511
516
  }
512
- }
513
517
  }
514
518
 
515
519
  const minElo = 1800;
516
520
  const maxElo = 2200;
517
521
 
518
522
  const players = [
519
- "William Smith",
520
- "Jack Jones",
521
- "Oliver Williams",
522
- "Joshua Brown",
523
- "Thomas Wilson",
524
- "Lachlan Taylor",
525
- "Cooper Johnson",
526
- "Noah White",
527
- "Ethan Martin",
528
- "Lucas Anderson",
529
- "James Thompson",
530
- "Samuel Nguyen",
531
- "Jacob Thomas",
532
- "Liam Walker",
533
- "Alexander Harris",
534
- "Benjamin Lee",
523
+ "William Smith",
524
+ "Jack Jones",
525
+ "Oliver Williams",
526
+ "Joshua Brown",
527
+ "Thomas Wilson",
528
+ "Lachlan Taylor",
529
+ "Cooper Johnson",
530
+ "Noah White",
531
+ "Ethan Martin",
532
+ "Lucas Anderson",
533
+ "James Thompson",
534
+ "Samuel Nguyen",
535
+ "Jacob Thomas",
536
+ "Liam Walker",
537
+ "Alexander Harris",
538
+ "Benjamin Lee",
535
539
  ].map((name) => {
536
- return playerOf(name, randomInt(minElo, maxElo));
540
+ return playerOf(name, randomInt(minElo, maxElo));
537
541
  });
538
542
 
539
543
  players.forEach((player) => {
540
- console.log(`adding player ${player.toString()}`);
541
- myTournament.addPlayer(player);
544
+ console.log(`adding player ${player.toString()}`);
545
+ myTournament.addPlayer(player);
542
546
  });
543
547
 
544
548
  while (!myTournament.completed) {
545
- console.log("next round");
546
- myTournament.nextRound().forEach((match) => {
547
- runMatch(match);
548
- console.log(`${match.toString()}`);
549
- });
549
+ console.log("next round");
550
+ myTournament.nextRound().forEach((match) => {
551
+ runMatch(match);
552
+ console.log(`${match.toString()}`);
553
+ });
550
554
  }
551
555
 
552
- console.log(myTournament.leaderboard.map( e => e.toString() + ` - ${e.score.toString()}`));
556
+ console.log(myTournament.leaderboard.map(e => e.toString() + ` - ${e.score.toString()}`));
553
557
  ```
554
558
 
555
559
  *Creating an arena tournament*
@@ -561,83 +565,83 @@ is only intended to show the class's behavior when used in arena mode; it is not
561
565
  management of an arena tournament, which is typically more complex.
562
566
 
563
567
  ```javascript
564
- import { tournament, playerOf } from "./chess4js.mjs";
568
+ import {tournament, playerOf} from "./chess4js.mjs";
565
569
 
566
570
  const myTournament = tournament("arena");
567
571
 
568
572
  function randomInt(min, max) {
569
- return Math.floor(Math.random() * (max - min) + min);
573
+ return Math.floor(Math.random() * (max - min) + min);
570
574
  }
571
575
 
572
576
  function runMatch(match) {
573
- const ratio = (match.white.currentElo - match.black.currentElo) / 100;
574
- const random = Math.random();
575
- if (match.white.currentElo >= match.black.currentElo) {
576
- if (random < ratio) {
577
- match.outcome = "1-0";
578
- } else if (random == ratio) {
579
- match.outcome = "1/2-1/2";
580
- } else {
581
- match.outcome = "0-1";
582
- }
583
- } else {
584
- if (random < ratio) {
585
- match.outcome = "0-1";
586
- } else if (random == ratio) {
587
- match.outcome = "1/2-1/2";
577
+ const ratio = (match.white.currentElo - match.black.currentElo) / 100;
578
+ const random = Math.random();
579
+ if (match.white.currentElo >= match.black.currentElo) {
580
+ if (random < ratio) {
581
+ match.outcome = "1-0";
582
+ } else if (random == ratio) {
583
+ match.outcome = "1/2-1/2";
584
+ } else {
585
+ match.outcome = "0-1";
586
+ }
588
587
  } else {
589
- match.outcome = "1-0";
588
+ if (random < ratio) {
589
+ match.outcome = "0-1";
590
+ } else if (random == ratio) {
591
+ match.outcome = "1/2-1/2";
592
+ } else {
593
+ match.outcome = "1-0";
594
+ }
590
595
  }
591
- }
592
596
  }
593
597
 
594
598
  const minElo = 1800;
595
599
  const maxElo = 2200;
596
600
 
597
601
  const players = [
598
- "William Smith",
599
- "Jack Jones",
600
- "Oliver Williams",
601
- "Joshua Brown",
602
- "Thomas Wilson",
603
- "Lachlan Taylor",
604
- "Cooper Johnson",
605
- "Noah White",
606
- "Ethan Martin",
607
- "Lucas Anderson",
608
- "James Thompson",
609
- "Samuel Nguyen",
610
- "Jacob Thomas",
611
- "Liam Walker",
612
- "Alexander Harris",
613
- "Benjamin Lee",
602
+ "William Smith",
603
+ "Jack Jones",
604
+ "Oliver Williams",
605
+ "Joshua Brown",
606
+ "Thomas Wilson",
607
+ "Lachlan Taylor",
608
+ "Cooper Johnson",
609
+ "Noah White",
610
+ "Ethan Martin",
611
+ "Lucas Anderson",
612
+ "James Thompson",
613
+ "Samuel Nguyen",
614
+ "Jacob Thomas",
615
+ "Liam Walker",
616
+ "Alexander Harris",
617
+ "Benjamin Lee",
614
618
  ].map((name) => {
615
- return playerOf(name, randomInt(minElo, maxElo));
619
+ return playerOf(name, randomInt(minElo, maxElo));
616
620
  });
617
621
 
618
622
  players.forEach((player) => {
619
- console.log(`adding player ${player.toString()}`);
620
- myTournament.addPlayer(player);
623
+ console.log(`adding player ${player.toString()}`);
624
+ myTournament.addPlayer(player);
621
625
  });
622
626
 
623
627
  const gamesLimit = 100;
624
628
 
625
629
  let gamesQueue = [];
626
630
 
627
- while((myTournament.finishedMatches.length + myTournament.activeMatches.length) < gamesLimit) {
631
+ while ((myTournament.finishedMatches.length + myTournament.activeMatches.length) < gamesLimit) {
628
632
  myTournament.nextRound();
629
- myTournament.activeMatches.forEach( (match) => gamesQueue.push(match) )
633
+ myTournament.activeMatches.forEach((match) => gamesQueue.push(match))
630
634
  if (gamesQueue.length > 0) {
631
- for(let i = 0; i < (gamesQueue.length / 4 * 3); i++) {
635
+ for (let i = 0; i < (gamesQueue.length / 4 * 3); i++) {
632
636
  runMatch(gamesQueue.pop());
633
637
  }
634
638
  }
635
639
  gamesQueue = [];
636
640
  }
637
641
 
638
- myTournament.activeMatches.forEach( (match) => runMatch(match) );
642
+ myTournament.activeMatches.forEach((match) => runMatch(match));
639
643
 
640
644
  myTournament.completed = true;
641
645
 
642
- console.log(myTournament.leaderboard.map( e => e.toString() + ` - ${e.score.toString()}`));
646
+ console.log(myTournament.leaderboard.map(e => e.toString() + ` - ${e.score.toString()}`));
643
647
  ```
package/chess4js.d.mts CHANGED
@@ -72,7 +72,7 @@ export declare class Game {
72
72
  toAnalysis(idSupplier?: () => Nullable<any>): Game;
73
73
  deleteFromExclusive(node: Node): Node;
74
74
  deleteFromInclusive(node: Node): Node;
75
- deleteBefore(_this_: Game, node: Node): Node;
75
+ deleteBefore(node: Node): Node;
76
76
  updateEco(): void;
77
77
  }
78
78
  /** @deprecated $metadata$ is used for internal purposes, please don't use it in your code, because it can be removed at any moment */
@@ -85,6 +85,7 @@ export declare class Match {
85
85
  get black(): Nullable<Player>;
86
86
  get outcome(): string;
87
87
  set outcome(value: string);
88
+ get id(): Nullable<string>;
88
89
  toString(): string;
89
90
  }
90
91
  /** @deprecated $metadata$ is used for internal purposes, please don't use it in your code, because it can be removed at any moment */
@@ -107,6 +108,7 @@ export declare namespace Move.$metadata$ {
107
108
  }
108
109
  export declare class Node {
109
110
  private constructor();
111
+ get id(): number;
110
112
  get position(): Position;
111
113
  get move(): Nullable<Move>;
112
114
  get children(): ReadonlyArray<Node>;
@@ -244,6 +246,7 @@ export declare class Position {
244
246
  move(move: Move): Position;
245
247
  moveFromString(move: string, notation?: Notation): Position;
246
248
  flipSide(): Position;
249
+ transpositionId(): string;
247
250
  hashCode(): number;
248
251
  equals(other: Nullable<any>): boolean;
249
252
  toString(): string;
@@ -391,6 +394,7 @@ export declare class Tournament {
391
394
  set completed(value: boolean);
392
395
  get activeMatches(): ReadonlyArray<Match>;
393
396
  get finishedMatches(): ReadonlyArray<Match>;
397
+ get idGenerator(): Nullable<() => string>;
394
398
  addPlayer(player: Player): void;
395
399
  removePlayer(player: Player): void;
396
400
  nextRound(): ReadonlyArray<Match>;
@@ -433,6 +437,6 @@ export declare function customGame(gameMode: string, threeRepetitionsMode: strin
433
437
  export declare function parseGames(pgnInput: string, idSupplier?: () => Nullable<any>): ReadonlyArray<Game>;
434
438
  export declare function scoreOf(score: string): Score;
435
439
  export declare function playerOf(name: string, initialElo: number): Player;
436
- export declare function matchOf(white: Player, black: Player, impactFactor?: number, rangeFactor?: number, logisticBase?: number): Match;
437
- export declare function tournament(type: string, tiebreakers?: Array<string>, impactFactor?: number, rangeFactor?: number, logisticBase?: number): Tournament;
440
+ export declare function matchOf(white: Player, black: Player, impactFactor?: number, rangeFactor?: number, logisticBase?: number, id?: Nullable<string>): Match;
441
+ export declare function tournament(type: string, tiebreakers?: Array<string>, impactFactor?: number, rangeFactor?: number, logisticBase?: number, idGenerator?: Nullable<() => string>): Tournament;
438
442
  export declare function visibleSquares(piece: string, square: string, position: Position): Bitboard;