From a8e656c454e4862c20d86050ad34e9abedd9194b Mon Sep 17 00:00:00 2001 From: Ell AchE <26192612+EllAchE@users.noreply.github.com> Date: Mon, 6 Nov 2023 23:53:01 -0800 Subject: [PATCH] Add more metrics and clean up old code (#40) * fix uas refactor * add gh workflow * remove redundant tests * update average distance to metric * add chkmt to revenge kills * clean up some old tests and validate existing metrics * rename to UAS * consolidate metrics * correct tests * add test for promotions * single game move max calcs * compiler fixes old cold * add tests for the moves metric * updt shortpgn * add capture map * fix tests * play with optimization * use metadata instead of gameLink --- .github/workflows/node.js.yml | 25 + badhistory.json | 1923 ----------------------- cjsmin/src/chess.ts | 102 +- historiesShort.json | 588 +++---- historiestst.json | 2616 -------------------------------- history.json | 199 --- src/gameHistory.ts | 11 - src/index.ts | 84 +- src/metrics/captures.ts | 376 ++--- src/metrics/distances.ts | 312 ++-- src/metrics/metric.ts | 7 +- src/metrics/moves.ts | 226 ++- src/metrics/promotions.ts | 96 +- src/prepare.ts | 52 - src/types.ts | 12 +- src/utils.ts | 67 + tests/enPassant.test.ts | 2 +- tests/historyGenerator.test.ts | 4 +- tests/metrics.test.ts | 454 +++--- tests/queensidecastle.test.ts | 2 +- tests/shortPgn.test.ts | 16 +- 21 files changed, 1274 insertions(+), 5900 deletions(-) create mode 100644 .github/workflows/node.js.yml delete mode 100644 badhistory.json delete mode 100644 historiestst.json delete mode 100644 history.json delete mode 100644 src/gameHistory.ts delete mode 100644 src/prepare.ts diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml new file mode 100644 index 0000000..ddeb89b --- /dev/null +++ b/.github/workflows/node.js.yml @@ -0,0 +1,25 @@ +name: Node.js CI + +on: + pull_request: + branches: [main] + +jobs: + build-and-test: + if: github.event.pull_request.draft == false + runs-on: ubuntu-latest + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Install Node + uses: actions/setup-node@v3 + with: + node-version: 20 + + - name: Install Dependencies + run: npm install + + - name: Run tests + run: npm run test diff --git a/badhistory.json b/badhistory.json deleted file mode 100644 index 987ad45..0000000 --- a/badhistory.json +++ /dev/null @@ -1,1923 +0,0 @@ -[ - [ - { - "color": "w", - "from": "e2", - "to": "e4", - "flags": "b", - "piece": "p", - "originalString": "e4" - }, - { - "color": "b", - "from": "e7", - "to": "e6", - "flags": "n", - "piece": "p", - "originalString": "e6" - }, - { - "color": "w", - "from": "d2", - "to": "d4", - "flags": "b", - "piece": "p", - "originalString": "d4" - }, - { - "color": "b", - "from": "b7", - "to": "b6", - "flags": "n", - "piece": "p", - "originalString": "b6" - }, - { - "color": "w", - "from": "a2", - "to": "a3", - "flags": "n", - "piece": "p", - "originalString": "a3" - }, - { - "color": "b", - "from": "c8", - "to": "b7", - "flags": "n", - "piece": "b", - "originalString": "Bb7" - }, - { - "color": "w", - "from": "b1", - "to": "c3", - "flags": "n", - "piece": "n", - "originalString": "Nc3" - }, - { - "color": "b", - "from": "g8", - "to": "h6", - "flags": "n", - "piece": "n", - "originalString": "Nh6" - }, - { - "color": "w", - "captured": "n", - "from": "c1", - "to": "h6", - "flags": "c", - "piece": "b", - "originalString": "Bxh6" - }, - { - "color": "b", - "captured": "b", - "from": "g7", - "to": "h6", - "flags": "c", - "piece": "p", - "originalString": "gxh6" - }, - { - "color": "w", - "from": "f1", - "to": "e2", - "flags": "n", - "piece": "b", - "originalString": "Be2" - }, - { - "color": "b", - "from": "d8", - "to": "g5", - "flags": "n", - "piece": "q", - "originalString": "Qg5" - }, - { - "color": "w", - "from": "e2", - "to": "g4", - "flags": "n", - "piece": "b", - "originalString": "Bg4" - }, - { - "color": "b", - "from": "h6", - "to": "h5", - "flags": "n", - "piece": "p", - "originalString": "h5" - }, - { - "color": "w", - "from": "g1", - "to": "f3", - "flags": "n", - "piece": "n", - "originalString": "Nf3" - }, - { - "color": "b", - "from": "g5", - "to": "g6", - "flags": "n", - "piece": "q", - "originalString": "Qg6" - }, - { - "color": "w", - "from": "f3", - "to": "h4", - "flags": "n", - "piece": "n", - "originalString": "Nh4" - }, - { - "color": "b", - "from": "g6", - "to": "g5", - "flags": "n", - "piece": "q", - "originalString": "Qg5" - }, - { - "color": "w", - "captured": "p", - "from": "g4", - "to": "h5", - "flags": "c", - "piece": "b", - "originalString": "Bxh5" - }, - { - "color": "b", - "captured": "n", - "from": "g5", - "to": "h4", - "flags": "c", - "piece": "q", - "originalString": "Qxh4" - }, - { - "color": "w", - "from": "d1", - "to": "f3", - "flags": "n", - "piece": "q", - "originalString": "Qf3" - }, - { - "color": "b", - "from": "e8", - "to": "d8", - "flags": "n", - "piece": "k", - "originalString": "Kd8" - }, - { - "color": "w", - "captured": "p", - "from": "f3", - "to": "f7", - "flags": "c", - "piece": "q", - "originalString": "Qxf7" - }, - { - "color": "b", - "from": "b8", - "to": "c6", - "flags": "n", - "piece": "n", - "originalString": "Nc6" - }, - { - "color": "w", - "from": "f7", - "to": "e8", - "flags": "n", - "piece": "q", - "originalString": "Qe8#" - } - ], - [ - { - "color": "w", - "from": "d2", - "to": "d4", - "flags": "b", - "piece": "p", - "originalString": "d4" - }, - { - "color": "b", - "from": "d7", - "to": "d5", - "flags": "b", - "piece": "p", - "originalString": "d5" - }, - { - "color": "w", - "from": "g1", - "to": "f3", - "flags": "n", - "piece": "n", - "originalString": "Nf3" - }, - { - "color": "b", - "from": "g8", - "to": "f6", - "flags": "n", - "piece": "n", - "originalString": "Nf6" - }, - { - "color": "w", - "from": "e2", - "to": "e3", - "flags": "n", - "piece": "p", - "originalString": "e3" - }, - { - "color": "b", - "from": "c8", - "to": "f5", - "flags": "n", - "piece": "b", - "originalString": "Bf5" - }, - { - "color": "w", - "from": "f3", - "to": "h4", - "flags": "n", - "piece": "n", - "originalString": "Nh4" - }, - { - "color": "b", - "from": "f5", - "to": "g6", - "flags": "n", - "piece": "b", - "originalString": "Bg6" - }, - { - "color": "w", - "captured": "b", - "from": "h4", - "to": "g6", - "flags": "c", - "piece": "n", - "originalString": "Nxg6" - }, - { - "color": "b", - "captured": "n", - "from": "h7", - "to": "g6", - "flags": "c", - "piece": "p", - "originalString": "hxg6" - }, - { - "color": "w", - "from": "b1", - "to": "d2", - "flags": "n", - "piece": "n", - "originalString": "Nd2" - }, - { - "color": "b", - "from": "e7", - "to": "e6", - "flags": "n", - "piece": "p", - "originalString": "e6" - }, - { - "color": "w", - "from": "f1", - "to": "d3", - "flags": "n", - "piece": "b", - "originalString": "Bd3" - }, - { - "color": "b", - "from": "f8", - "to": "d6", - "flags": "n", - "piece": "b", - "originalString": "Bd6" - }, - { - "color": "w", - "from": "e3", - "to": "e4", - "flags": "n", - "piece": "p", - "originalString": "e4" - }, - { - "color": "b", - "captured": "p", - "from": "d5", - "to": "e4", - "flags": "c", - "piece": "p", - "originalString": "dxe4" - }, - { - "color": "w", - "captured": "p", - "from": "d2", - "to": "e4", - "flags": "c", - "piece": "n", - "originalString": "Nxe4" - }, - { - "color": "b", - "captured": "p", - "from": "h8", - "to": "h2", - "flags": "c", - "piece": "r", - "originalString": "Rxh2" - }, - { - "color": "w", - "from": "e1", - "to": "e2", - "flags": "n", - "piece": "k", - "originalString": "Ke2" - }, - { - "color": "b", - "captured": "r", - "from": "h2", - "to": "h1", - "flags": "c", - "piece": "r", - "originalString": "Rxh1" - }, - { - "color": "w", - "captured": "r", - "from": "d1", - "to": "h1", - "flags": "c", - "piece": "q", - "originalString": "Qxh1" - }, - { - "color": "b", - "from": "b8", - "to": "c6", - "flags": "n", - "piece": "n", - "originalString": "Nc6" - }, - { - "color": "w", - "from": "c1", - "to": "g5", - "flags": "n", - "piece": "b", - "originalString": "Bg5" - }, - { - "color": "b", - "from": "e8", - "to": "e7", - "flags": "n", - "piece": "k", - "originalString": "Ke7" - }, - { - "color": "w", - "from": "h1", - "to": "h7", - "flags": "n", - "piece": "q", - "originalString": "Qh7" - }, - { - "color": "b", - "captured": "p", - "from": "c6", - "to": "d4", - "flags": "c", - "piece": "n", - "originalString": "Nxd4+" - }, - { - "color": "w", - "from": "e2", - "to": "d2", - "flags": "n", - "piece": "k", - "originalString": "Kd2" - }, - { - "color": "b", - "from": "d8", - "to": "e8", - "flags": "n", - "piece": "q", - "originalString": "Qe8" - }, - { - "color": "w", - "captured": "p", - "from": "h7", - "to": "g7", - "flags": "c", - "piece": "q", - "originalString": "Qxg7" - }, - { - "color": "b", - "from": "e8", - "to": "h8", - "flags": "n", - "piece": "q", - "originalString": "Qh8" - }, - { - "color": "w", - "captured": "n", - "from": "g5", - "to": "f6", - "flags": "c", - "piece": "b", - "originalString": "Bxf6+" - }, - { - "color": "b", - "from": "e7", - "to": "d7", - "flags": "n", - "piece": "k", - "originalString": "Kd7" - }, - { - "color": "w", - "captured": "q", - "from": "g7", - "to": "h8", - "flags": "c", - "piece": "q", - "originalString": "Qxh8" - }, - { - "color": "b", - "captured": "q", - "from": "a8", - "to": "h8", - "flags": "c", - "piece": "r", - "originalString": "Rxh8" - }, - { - "color": "w", - "captured": "r", - "from": "f6", - "to": "h8", - "flags": "c", - "piece": "b", - "originalString": "Bxh8" - } - ], - [ - { - "color": "w", - "from": "e2", - "to": "e4", - "flags": "b", - "piece": "p", - "originalString": "e4" - }, - { - "color": "b", - "from": "e7", - "to": "e5", - "flags": "b", - "piece": "p", - "originalString": "e5" - }, - { - "color": "w", - "from": "g1", - "to": "f3", - "flags": "n", - "piece": "n", - "originalString": "Nf3" - }, - { - "color": "b", - "from": "b8", - "to": "c6", - "flags": "n", - "piece": "n", - "originalString": "Nc6" - }, - { - "color": "w", - "from": "f1", - "to": "c4", - "flags": "n", - "piece": "b", - "originalString": "Bc4" - }, - { - "color": "b", - "from": "g8", - "to": "f6", - "flags": "n", - "piece": "n", - "originalString": "Nf6" - }, - { - "color": "w", - "from": "b1", - "to": "c3", - "flags": "n", - "piece": "n", - "originalString": "Nc3" - }, - { - "color": "b", - "from": "f8", - "to": "c5", - "flags": "n", - "piece": "b", - "originalString": "Bc5" - }, - { - "color": "w", - "from": "a2", - "to": "a3", - "flags": "n", - "piece": "p", - "originalString": "a3" - }, - { - "color": "b", - "captured": "p", - "from": "c5", - "to": "f2", - "flags": "c", - "piece": "b", - "originalString": "Bxf2+" - }, - { - "color": "w", - "captured": "b", - "from": "e1", - "to": "f2", - "flags": "c", - "piece": "k", - "originalString": "Kxf2" - }, - { - "color": "b", - "from": "c6", - "to": "d4", - "flags": "n", - "piece": "n", - "originalString": "Nd4" - }, - { - "color": "w", - "from": "d2", - "to": "d3", - "flags": "n", - "piece": "p", - "originalString": "d3" - }, - { - "color": "b", - "from": "f6", - "to": "g4", - "flags": "n", - "piece": "n", - "originalString": "Ng4+" - }, - { - "color": "w", - "from": "f2", - "to": "f1", - "flags": "n", - "piece": "k", - "originalString": "Kf1" - }, - { - "color": "b", - "from": "d8", - "to": "f6", - "flags": "n", - "piece": "q", - "originalString": "Qf6" - }, - { - "color": "w", - "from": "h2", - "to": "h3", - "flags": "n", - "piece": "p", - "originalString": "h3" - }, - { - "color": "b", - "from": "d7", - "to": "d5", - "flags": "b", - "piece": "p", - "originalString": "d5" - }, - { - "color": "w", - "captured": "p", - "from": "c3", - "to": "d5", - "flags": "c", - "piece": "n", - "originalString": "Nxd5" - }, - { - "color": "b", - "from": "f6", - "to": "e6", - "flags": "n", - "piece": "q", - "originalString": "Qe6" - }, - { - "color": "w", - "captured": "p", - "from": "d5", - "to": "c7", - "flags": "c", - "piece": "n", - "originalString": "Nxc7+" - } - ], - [ - { - "color": "w", - "from": "e2", - "to": "e4", - "flags": "b", - "piece": "p", - "originalString": "e4" - }, - { - "color": "b", - "from": "c7", - "to": "c6", - "flags": "n", - "piece": "p", - "originalString": "c6" - }, - { - "color": "w", - "from": "b1", - "to": "c3", - "flags": "n", - "piece": "n", - "originalString": "Nc3" - }, - { - "color": "b", - "from": "d7", - "to": "d5", - "flags": "b", - "piece": "p", - "originalString": "d5" - }, - { - "color": "w", - "from": "d1", - "to": "f3", - "flags": "n", - "piece": "q", - "originalString": "Qf3" - }, - { - "color": "b", - "captured": "p", - "from": "d5", - "to": "e4", - "flags": "c", - "piece": "p", - "originalString": "dxe4" - }, - { - "color": "w", - "captured": "p", - "from": "c3", - "to": "e4", - "flags": "c", - "piece": "n", - "originalString": "Nxe4" - }, - { - "color": "b", - "from": "b8", - "to": "d7", - "flags": "n", - "piece": "n", - "originalString": "Nd7" - }, - { - "color": "w", - "from": "f1", - "to": "c4", - "flags": "n", - "piece": "b", - "originalString": "Bc4" - }, - { - "color": "b", - "from": "g8", - "to": "f6", - "flags": "n", - "piece": "n", - "originalString": "Ngf6" - }, - { - "color": "w", - "captured": "n", - "from": "e4", - "to": "f6", - "flags": "c", - "piece": "n", - "originalString": "Nxf6+" - }, - { - "color": "b", - "captured": "n", - "from": "d7", - "to": "f6", - "flags": "c", - "piece": "n", - "originalString": "Nxf6" - }, - { - "color": "w", - "from": "f3", - "to": "g3", - "flags": "n", - "piece": "q", - "originalString": "Qg3" - }, - { - "color": "b", - "from": "c8", - "to": "f5", - "flags": "n", - "piece": "b", - "originalString": "Bf5" - }, - { - "color": "w", - "from": "d2", - "to": "d3", - "flags": "n", - "piece": "p", - "originalString": "d3" - }, - { - "color": "b", - "from": "f5", - "to": "g6", - "flags": "n", - "piece": "b", - "originalString": "Bg6" - }, - { - "color": "w", - "from": "g1", - "to": "e2", - "flags": "n", - "piece": "n", - "originalString": "Ne2" - }, - { - "color": "b", - "from": "e7", - "to": "e6", - "flags": "n", - "piece": "p", - "originalString": "e6" - }, - { - "color": "w", - "from": "c1", - "to": "f4", - "flags": "n", - "piece": "b", - "originalString": "Bf4" - }, - { - "color": "b", - "from": "f6", - "to": "h5", - "flags": "n", - "piece": "n", - "originalString": "Nh5" - }, - { - "color": "w", - "from": "g3", - "to": "f3", - "flags": "n", - "piece": "q", - "originalString": "Qf3" - }, - { - "color": "b", - "captured": "b", - "from": "h5", - "to": "f4", - "flags": "c", - "piece": "n", - "originalString": "Nxf4" - }, - { - "color": "w", - "captured": "n", - "from": "e2", - "to": "f4", - "flags": "c", - "piece": "n", - "originalString": "Nxf4" - }, - { - "color": "b", - "from": "f8", - "to": "e7", - "flags": "n", - "piece": "b", - "originalString": "Be7" - }, - { - "color": "w", - "captured": "p", - "from": "c4", - "to": "e6", - "flags": "c", - "piece": "b", - "originalString": "Bxe6" - }, - { - "color": "b", - "captured": "b", - "from": "f7", - "to": "e6", - "flags": "c", - "piece": "p", - "originalString": "fxe6" - }, - { - "color": "w", - "captured": "p", - "from": "f4", - "to": "e6", - "flags": "c", - "piece": "n", - "originalString": "Nxe6" - }, - { - "color": "b", - "from": "d8", - "to": "a5", - "flags": "n", - "piece": "q", - "originalString": "Qa5+" - }, - { - "color": "w", - "from": "c2", - "to": "c3", - "flags": "n", - "piece": "p", - "originalString": "c3" - }, - { - "color": "b", - "from": "a5", - "to": "e5", - "flags": "n", - "piece": "q", - "originalString": "Qe5+" - }, - { - "color": "w", - "from": "f3", - "to": "e3", - "flags": "n", - "piece": "q", - "originalString": "Qe3" - }, - { - "color": "b", - "captured": "q", - "from": "e5", - "to": "e3", - "flags": "c", - "piece": "q", - "originalString": "Qxe3+" - }, - { - "color": "w", - "captured": "q", - "from": "f2", - "to": "e3", - "flags": "c", - "piece": "p", - "originalString": "fxe3" - }, - { - "color": "b", - "from": "e8", - "to": "d7", - "flags": "n", - "piece": "k", - "originalString": "Kd7" - }, - { - "color": "w", - "from": "e6", - "to": "f4", - "flags": "n", - "piece": "n", - "originalString": "Nf4" - }, - { - "color": "b", - "from": "e7", - "to": "d6", - "flags": "n", - "piece": "b", - "originalString": "Bd6" - }, - { - "color": "w", - "captured": "b", - "from": "f4", - "to": "g6", - "flags": "c", - "piece": "n", - "originalString": "Nxg6" - }, - { - "color": "b", - "captured": "n", - "from": "h7", - "to": "g6", - "flags": "c", - "piece": "p", - "originalString": "hxg6" - }, - { - "color": "w", - "from": "h2", - "to": "h3", - "flags": "n", - "piece": "p", - "originalString": "h3" - }, - { - "color": "b", - "from": "d6", - "to": "g3", - "flags": "n", - "piece": "b", - "originalString": "Bg3+" - }, - { - "color": "w", - "from": "e1", - "to": "d2", - "flags": "n", - "piece": "k", - "originalString": "Kd2" - }, - { - "color": "b", - "from": "a8", - "to": "f8", - "flags": "n", - "piece": "r", - "originalString": "Raf8" - }, - { - "color": "w", - "from": "h1", - "to": "f1", - "flags": "n", - "piece": "r", - "originalString": "Rhf1" - }, - { - "color": "b", - "from": "d7", - "to": "e7", - "flags": "n", - "piece": "k", - "originalString": "Ke7" - }, - { - "color": "w", - "from": "d3", - "to": "d4", - "flags": "n", - "piece": "p", - "originalString": "d4" - }, - { - "color": "b", - "captured": "r", - "from": "f8", - "to": "f1", - "flags": "c", - "piece": "r", - "originalString": "Rxf1" - }, - { - "color": "w", - "captured": "r", - "from": "a1", - "to": "f1", - "flags": "c", - "piece": "r", - "originalString": "Rxf1" - }, - { - "color": "b", - "from": "h8", - "to": "f8", - "flags": "n", - "piece": "r", - "originalString": "Rf8" - }, - { - "color": "w", - "captured": "r", - "from": "f1", - "to": "f8", - "flags": "c", - "piece": "r", - "originalString": "Rxf8" - }, - { - "color": "b", - "captured": "r", - "from": "e7", - "to": "f8", - "flags": "c", - "piece": "k", - "originalString": "Kxf8" - }, - { - "color": "w", - "from": "e3", - "to": "e4", - "flags": "n", - "piece": "p", - "originalString": "e4" - }, - { - "color": "b", - "from": "f8", - "to": "e7", - "flags": "n", - "piece": "k", - "originalString": "Ke7" - }, - { - "color": "w", - "from": "d2", - "to": "e3", - "flags": "n", - "piece": "k", - "originalString": "Ke3" - }, - { - "color": "b", - "from": "g6", - "to": "g5", - "flags": "n", - "piece": "p", - "originalString": "g5" - }, - { - "color": "w", - "from": "e3", - "to": "f3", - "flags": "n", - "piece": "k", - "originalString": "Kf3" - }, - { - "color": "b", - "from": "g3", - "to": "e1", - "flags": "n", - "piece": "b", - "originalString": "Be1" - }, - { - "color": "w", - "from": "f3", - "to": "g4", - "flags": "n", - "piece": "k", - "originalString": "Kg4" - }, - { - "color": "b", - "from": "e1", - "to": "d2", - "flags": "n", - "piece": "b", - "originalString": "Bd2" - }, - { - "color": "w", - "from": "g4", - "to": "f5", - "flags": "n", - "piece": "k", - "originalString": "Kf5" - }, - { - "color": "b", - "from": "d2", - "to": "c1", - "flags": "n", - "piece": "b", - "originalString": "Bc1" - }, - { - "color": "w", - "from": "f5", - "to": "g6", - "flags": "n", - "piece": "k", - "originalString": "Kg6" - }, - { - "color": "b", - "from": "e7", - "to": "f8", - "flags": "n", - "piece": "k", - "originalString": "Kf8" - }, - { - "color": "w", - "from": "e4", - "to": "e5", - "flags": "n", - "piece": "p", - "originalString": "e5" - }, - { - "color": "b", - "captured": "p", - "from": "c1", - "to": "b2", - "flags": "c", - "piece": "b", - "originalString": "Bxb2" - }, - { - "color": "w", - "captured": "p", - "from": "g6", - "to": "g5", - "flags": "c", - "piece": "k", - "originalString": "Kxg5" - }, - { - "color": "b", - "captured": "p", - "from": "b2", - "to": "c3", - "flags": "c", - "piece": "b", - "originalString": "Bxc3" - }, - { - "color": "w", - "from": "h3", - "to": "h4", - "flags": "n", - "piece": "p", - "originalString": "h4" - }, - { - "color": "b", - "captured": "p", - "from": "c3", - "to": "d4", - "flags": "c", - "piece": "b", - "originalString": "Bxd4" - }, - { - "color": "w", - "from": "h4", - "to": "h5", - "flags": "n", - "piece": "p", - "originalString": "h5" - }, - { - "color": "b", - "captured": "p", - "from": "d4", - "to": "e5", - "flags": "c", - "piece": "b", - "originalString": "Bxe5" - }, - { - "color": "w", - "from": "g2", - "to": "g4", - "flags": "b", - "piece": "p", - "originalString": "g4" - }, - { - "color": "b", - "from": "e5", - "to": "b2", - "flags": "n", - "piece": "b", - "originalString": "Bb2" - }, - { - "color": "w", - "from": "g5", - "to": "f5", - "flags": "n", - "piece": "k", - "originalString": "Kf5" - }, - { - "color": "b", - "from": "f8", - "to": "f7", - "flags": "n", - "piece": "k", - "originalString": "Kf7" - }, - { - "color": "w", - "from": "g4", - "to": "g5", - "flags": "n", - "piece": "p", - "originalString": "g5" - }, - { - "color": "b", - "from": "b2", - "to": "c1", - "flags": "n", - "piece": "b", - "originalString": "Bc1" - }, - { - "color": "w", - "from": "g5", - "to": "g6", - "flags": "n", - "piece": "p", - "originalString": "g6+" - }, - { - "color": "b", - "from": "f7", - "to": "e7", - "flags": "n", - "piece": "k", - "originalString": "Ke7" - }, - { - "color": "w", - "from": "f5", - "to": "e5", - "flags": "n", - "piece": "k", - "originalString": "Ke5" - }, - { - "color": "b", - "from": "b7", - "to": "b5", - "flags": "b", - "piece": "p", - "originalString": "b5" - }, - { - "color": "w", - "from": "e5", - "to": "d4", - "flags": "n", - "piece": "k", - "originalString": "Kd4" - }, - { - "color": "b", - "from": "e7", - "to": "d6", - "flags": "n", - "piece": "k", - "originalString": "Kd6" - }, - { - "color": "w", - "from": "d4", - "to": "c3", - "flags": "n", - "piece": "k", - "originalString": "Kc3" - }, - { - "color": "b", - "from": "c6", - "to": "c5", - "flags": "n", - "piece": "p", - "originalString": "c5" - }, - { - "color": "w", - "from": "a2", - "to": "a3", - "flags": "n", - "piece": "p", - "originalString": "a3" - }, - { - "color": "b", - "from": "c1", - "to": "g5", - "flags": "n", - "piece": "b", - "originalString": "Bg5" - }, - { - "color": "w", - "from": "a3", - "to": "a4", - "flags": "n", - "piece": "p", - "originalString": "a4" - }, - { - "color": "b", - "captured": "p", - "from": "b5", - "to": "a4", - "flags": "c", - "piece": "p", - "originalString": "bxa4" - }, - { - "color": "w", - "from": "c3", - "to": "b2", - "flags": "n", - "piece": "k", - "originalString": "Kb2" - }, - { - "color": "b", - "from": "d6", - "to": "d5", - "flags": "n", - "piece": "k", - "originalString": "Kd5" - }, - { - "color": "w", - "from": "b2", - "to": "a3", - "flags": "n", - "piece": "k", - "originalString": "Ka3" - }, - { - "color": "b", - "from": "d5", - "to": "d4", - "flags": "n", - "piece": "k", - "originalString": "Kd4" - }, - { - "color": "w", - "captured": "p", - "from": "a3", - "to": "a4", - "flags": "c", - "piece": "k", - "originalString": "Kxa4" - }, - { - "color": "b", - "from": "c5", - "to": "c4", - "flags": "n", - "piece": "p", - "originalString": "c4" - } - ], - [ - { - "color": "w", - "from": "e2", - "to": "e4", - "flags": "b", - "piece": "p", - "originalString": "e4" - }, - { - "color": "b", - "from": "e7", - "to": "e6", - "flags": "n", - "piece": "p", - "originalString": "e6" - }, - { - "color": "w", - "from": "f1", - "to": "c4", - "flags": "n", - "piece": "b", - "originalString": "Bc4" - }, - { - "color": "b", - "from": "d7", - "to": "d5", - "flags": "b", - "piece": "p", - "originalString": "d5" - }, - { - "color": "w", - "captured": "p", - "from": "e4", - "to": "d5", - "flags": "c", - "piece": "p", - "originalString": "exd5" - }, - { - "color": "b", - "captured": "p", - "from": "e6", - "to": "d5", - "flags": "c", - "piece": "p", - "originalString": "exd5" - }, - { - "color": "w", - "from": "c4", - "to": "b3", - "flags": "n", - "piece": "b", - "originalString": "Bb3" - }, - { - "color": "b", - "from": "g8", - "to": "f6", - "flags": "n", - "piece": "n", - "originalString": "Nf6" - }, - { - "color": "w", - "from": "d2", - "to": "d4", - "flags": "b", - "piece": "p", - "originalString": "d4" - }, - { - "color": "b", - "from": "f8", - "to": "e7", - "flags": "n", - "piece": "b", - "originalString": "Be7" - }, - { - "color": "w", - "from": "g1", - "to": "f3", - "flags": "n", - "piece": "n", - "originalString": "Nf3" - }, - { - "color": "b", - "from": "e8", - "to": "g8", - "flags": "k", - "piece": "k", - "originalString": "O-O" - }, - { - "color": "w", - "from": "c1", - "to": "g5", - "flags": "n", - "piece": "b", - "originalString": "Bg5" - }, - { - "color": "b", - "from": "h7", - "to": "h6", - "flags": "n", - "piece": "p", - "originalString": "h6" - }, - { - "color": "w", - "captured": "n", - "from": "g5", - "to": "f6", - "flags": "c", - "piece": "b", - "originalString": "Bxf6" - }, - { - "color": "b", - "captured": "b", - "from": "e7", - "to": "f6", - "flags": "c", - "piece": "b", - "originalString": "Bxf6" - }, - { - "color": "w", - "from": "e1", - "to": "g1", - "flags": "k", - "piece": "k", - "originalString": "O-O" - }, - { - "color": "b", - "from": "c7", - "to": "c6", - "flags": "n", - "piece": "p", - "originalString": "c6" - }, - { - "color": "w", - "from": "f1", - "to": "e1", - "flags": "n", - "piece": "r", - "originalString": "Re1" - }, - { - "color": "b", - "from": "c8", - "to": "f5", - "flags": "n", - "piece": "b", - "originalString": "Bf5" - }, - { - "color": "w", - "from": "c2", - "to": "c4", - "flags": "b", - "piece": "p", - "originalString": "c4?!" - }, - { - "color": "b", - "captured": "p", - "from": "d5", - "to": "c4", - "flags": "c", - "piece": "p", - "originalString": "dxc4" - }, - { - "color": "w", - "captured": "p", - "from": "b3", - "to": "c4", - "flags": "c", - "piece": "b", - "originalString": "Bxc4" - }, - { - "color": "b", - "from": "b8", - "to": "d7", - "flags": "n", - "piece": "n", - "originalString": "Nd7?!" - }, - { - "color": "w", - "from": "b1", - "to": "c3", - "flags": "n", - "piece": "n", - "originalString": "Nc3" - }, - { - "color": "b", - "from": "d7", - "to": "b6", - "flags": "n", - "piece": "n", - "originalString": "Nb6" - }, - { - "color": "w", - "from": "b2", - "to": "b3", - "flags": "n", - "piece": "p", - "originalString": "b3?!" - }, - { - "color": "b", - "captured": "b", - "from": "b6", - "to": "c4", - "flags": "c", - "piece": "n", - "originalString": "Nxc4" - }, - { - "color": "w", - "captured": "n", - "from": "b3", - "to": "c4", - "flags": "c", - "piece": "p", - "originalString": "bxc4" - }, - { - "color": "b", - "from": "d8", - "to": "a5", - "flags": "n", - "piece": "q", - "originalString": "Qa5" - }, - { - "color": "w", - "from": "a1", - "to": "c1", - "flags": "n", - "piece": "r", - "originalString": "Rc1" - }, - { - "color": "b", - "from": "a8", - "to": "d8", - "flags": "n", - "piece": "r", - "originalString": "Rad8" - }, - { - "color": "w", - "from": "d4", - "to": "d5", - "flags": "n", - "piece": "p", - "originalString": "d5??" - }, - { - "color": "b", - "captured": "n", - "from": "f6", - "to": "c3", - "flags": "c", - "piece": "b", - "originalString": "Bxc3" - }, - { - "color": "w", - "from": "e1", - "to": "e5", - "flags": "n", - "piece": "r", - "originalString": "Re5?" - }, - { - "color": "b", - "captured": "r", - "from": "c3", - "to": "e5", - "flags": "c", - "piece": "b", - "originalString": "Bxe5" - }, - { - "color": "w", - "captured": "b", - "from": "f3", - "to": "e5", - "flags": "c", - "piece": "n", - "originalString": "Nxe5" - }, - { - "color": "b", - "captured": "p", - "from": "c6", - "to": "d5", - "flags": "c", - "piece": "p", - "originalString": "cxd5" - }, - { - "color": "w", - "from": "d1", - "to": "e1", - "flags": "n", - "piece": "q", - "originalString": "Qe1?" - }, - { - "color": "b", - "from": "f5", - "to": "e6", - "flags": "n", - "piece": "b", - "originalString": "Be6??" - }, - { - "color": "w", - "from": "c1", - "to": "d1", - "flags": "n", - "piece": "r", - "originalString": "Rd1??" - }, - { - "color": "b", - "captured": "p", - "from": "d5", - "to": "c4", - "flags": "c", - "piece": "p", - "originalString": "dxc4" - }, - { - "color": "w", - "captured": "r", - "from": "d1", - "to": "d8", - "flags": "c", - "piece": "r", - "originalString": "Rxd8?!" - }, - { - "color": "b", - "captured": "r", - "from": "f8", - "to": "d8", - "flags": "c", - "piece": "r", - "originalString": "Rxd8?!" - }, - { - "color": "w", - "from": "e1", - "to": "c3", - "flags": "n", - "piece": "q", - "originalString": "Qc3?!" - }, - { - "color": "b", - "captured": "q", - "from": "a5", - "to": "c3", - "flags": "c", - "piece": "q", - "originalString": "Qxc3?!" - }, - { - "color": "w", - "from": "g2", - "to": "g3", - "flags": "n", - "piece": "p", - "originalString": "g3" - }, - { - "color": "b", - "from": "d8", - "to": "d1", - "flags": "n", - "piece": "r", - "originalString": "Rd1+?!" - }, - { - "color": "w", - "from": "g1", - "to": "g2", - "flags": "n", - "piece": "k", - "originalString": "Kg2" - }, - { - "color": "b", - "from": "c3", - "to": "e1", - "flags": "n", - "piece": "q", - "originalString": "Qe1?!" - }, - { - "color": "w", - "from": "g2", - "to": "f3", - "flags": "n", - "piece": "k", - "originalString": "Kf3" - }, - { - "color": "b", - "captured": "n", - "from": "e1", - "to": "e5", - "flags": "c", - "piece": "q", - "originalString": "Qxe5" - }, - { - "color": "w", - "from": "f3", - "to": "g2", - "flags": "n", - "piece": "k", - "originalString": "Kg2" - }, - { - "color": "b", - "from": "e6", - "to": "d5", - "flags": "n", - "piece": "b", - "originalString": "Bd5+?!" - }, - { - "color": "w", - "from": "g2", - "to": "h3", - "flags": "n", - "piece": "k", - "originalString": "Kh3" - }, - { - "color": "b", - "from": "e5", - "to": "h5", - "flags": "n", - "piece": "q", - "originalString": "Qh5#" - } - ] -] \ No newline at end of file diff --git a/cjsmin/src/chess.ts b/cjsmin/src/chess.ts index dd86d2a..22dc02a 100644 --- a/cjsmin/src/chess.ts +++ b/cjsmin/src/chess.ts @@ -50,10 +50,30 @@ export type PrettyMove = { capture?: Capture | undefined; promotion?: PieceType | undefined; flags: string; - uas: UnambiguousPieceSymbol; + uas: UASymbol; }; -export type UnambiguousPieceSymbol = +export type PromotablePiece = 'q' | 'r' | 'b' | 'n'; + +export type Pawns = + | 'pa' + | 'pb' + | 'pc' + | 'pd' + | 'pe' + | 'pf' + | 'pg' + | 'ph' + | 'PA' + | 'PB' + | 'PC' + | 'PD' + | 'PE' + | 'PF' + | 'PG' + | 'PH'; + +export type UASymbol = | 'RA' | 'NB' | 'BC' @@ -146,7 +166,7 @@ export const ALL_SQUARES: Square[] = [ ] // prettier-ignore -export const ALL_UNAMBIGUOUS_PIECE_SYMBOLS: UnambiguousPieceSymbol[] = [ +export const ALL_UNAMBIGUOUS_PIECE_SYMBOLS: UASymbol[] = [ "RA", "NB", "BC", "Q", "K", "BF", "NG", "RH", "PA", "PB", "PC", "PD", "PE", "PF", "PG", "PH", "ra", "nb", "bc", "q", "k", "bf", "ng", "rh", @@ -159,12 +179,12 @@ export const DEFAULT_POSITION = export type Piece = { color: Color; type: PieceType; - uas: UnambiguousPieceSymbol; + uas: UASymbol; }; type Capture = { type: PieceType; - uas: UnambiguousPieceSymbol; + uas: UASymbol; }; export type InternalMove = { @@ -172,7 +192,7 @@ export type InternalMove = { from: number; to: number; piece: PieceType; - uas: UnambiguousPieceSymbol; + uas: UASymbol; capture?: Capture; promotion?: PieceType; flags: number; @@ -197,7 +217,7 @@ export type Move = { capture?: Capture; promotion?: PieceType; flags: string; - umabiguousSymbol: UnambiguousPieceSymbol; + umabiguousSymbol: UASymbol; // san: string; // lan: string; // before: string; @@ -612,7 +632,7 @@ function addMove( from: number, to: number, piece: PieceType, - uas: UnambiguousPieceSymbol, + uas: UASymbol, capture: Capture | undefined = undefined, flags: number = BITS.NORMAL ) { @@ -867,9 +887,7 @@ export class Chess { square: Square ) { //@ts-ignore this breaks for non init - const uas = SQUARE_TO_STARTING_POSITION_MAP[ - square - ] as UnambiguousPieceSymbol; + const uas = SQUARE_TO_STARTING_POSITION_MAP[square] as UASymbol; // check for piece if (SYMBOLS.indexOf(type.toLowerCase()) === -1) { @@ -1306,7 +1324,7 @@ export class Chess { this._board[from].uas, { type: PAWN, - uas: uas as UnambiguousPieceSymbol, + uas: uas as UASymbol, }, BITS.EP_CAPTURE ); @@ -1548,14 +1566,6 @@ export class Chess { this._turn = them; } - private _makeAndReturnMove( - move: InternalMove, - originalString?: string - ): InternalMove { - this._makeMove(move, originalString); - return move; - } - private _undoMove() { const old = this._history.pop(); if (old === undefined) { @@ -1733,6 +1743,58 @@ export class Chess { } } + historyGeneratorArr( + pgnMoveLine: string, + { strict = false }: { strict?: boolean; newlineChar?: string } = {} + ): { move: PrettyMove; board: Array }[] { + this.load(DEFAULT_POSITION); + const result: any[] = []; + + // We don't mind destructive deletion of the comments + let ms = pgnMoveLine.replace(new RegExp(`({[^}]*})+?`, 'g'), ''); + + // delete move numbers + ms = ms.replace(/\d+\.(\.\.)?/g, ''); + + // delete ... indicating black to move + ms = ms.replace('...', ''); + + /* delete numeric annotation glyphs */ + ms = ms.replace(/\$\d+/g, ''); + + // trim and get array of moves + // let moves = ms.trim().split(new RegExp(/\s+/)); + let moves = ms.trim().split(' '); + + // delete empty entries + moves = moves.filter((move) => move !== ''); + + for (let halfMove = 0; halfMove < moves.length; halfMove++) { + const move = this._moveFromSan(moves[halfMove], strict); + + // invalid move + if (move == null) { + // was the move an end of game marker + if (!(TERMINATION_MARKERS.indexOf(moves[halfMove]) > -1)) { + throw new Error(`Invalid move in PGN: ${moves[halfMove]}`); + } + } else { + // reset the end of game marker if making a valid move + this._makeMove(move, moves[halfMove]); + const prettyMove = { + ...this._makePretty(move, moves[halfMove]), + originalString: moves[halfMove], + }; + result.push({ + move: prettyMove, + board: this._board, + }); + } + } + + return result; + } + /* * Convert a move from 0x88 coordinates to Standard Algebraic Notation * (SAN) diff --git a/historiesShort.json b/historiesShort.json index 6b5a95c..aca27d3 100644 --- a/historiesShort.json +++ b/historiesShort.json @@ -8,7 +8,7 @@ "to": "e4", "flags": "b", "piece": "p", - "unambiguousSymbol": "PE", + "uas": "PE", "originalString": "e4" }, { @@ -19,7 +19,7 @@ "to": "e6", "flags": "n", "piece": "p", - "unambiguousSymbol": "pe", + "uas": "pe", "originalString": "e6" }, { @@ -30,7 +30,7 @@ "to": "d4", "flags": "b", "piece": "p", - "unambiguousSymbol": "PD", + "uas": "PD", "originalString": "d4" }, { @@ -41,7 +41,7 @@ "to": "b6", "flags": "n", "piece": "p", - "unambiguousSymbol": "pb", + "uas": "pb", "originalString": "b6" }, { @@ -52,7 +52,7 @@ "to": "a3", "flags": "n", "piece": "p", - "unambiguousSymbol": "PA", + "uas": "PA", "originalString": "a3" }, { @@ -63,7 +63,7 @@ "to": "b7", "flags": "n", "piece": "b", - "unambiguousSymbol": "bc", + "uas": "bc", "originalString": "Bb7" }, { @@ -74,7 +74,7 @@ "to": "c3", "flags": "n", "piece": "n", - "unambiguousSymbol": "NB", + "uas": "NB", "originalString": "Nc3" }, { @@ -85,7 +85,7 @@ "to": "h6", "flags": "n", "piece": "n", - "unambiguousSymbol": "ng", + "uas": "ng", "originalString": "Nh6" }, { @@ -96,9 +96,9 @@ "to": "h6", "flags": "c", "piece": "b", - "unambiguousSymbol": "BC", + "uas": "BC", "originalString": "Bxh6", - "capture": { "type": "n", "unambiguousSymbol": "ng" } + "capture": { "type": "n", "uas": "ng" } }, { "color": "b", @@ -108,9 +108,9 @@ "to": "h6", "flags": "c", "piece": "p", - "unambiguousSymbol": "pg", + "uas": "pg", "originalString": "gxh6", - "capture": { "type": "b", "unambiguousSymbol": "pg" } + "capture": { "type": "b", "uas": "BC" } }, { "color": "w", @@ -120,7 +120,7 @@ "to": "e2", "flags": "n", "piece": "b", - "unambiguousSymbol": "BF", + "uas": "BF", "originalString": "Be2" }, { @@ -131,7 +131,7 @@ "to": "g5", "flags": "n", "piece": "q", - "unambiguousSymbol": "q", + "uas": "q", "originalString": "Qg5" }, { @@ -142,7 +142,7 @@ "to": "g4", "flags": "n", "piece": "b", - "unambiguousSymbol": "BF", + "uas": "BF", "originalString": "Bg4" }, { @@ -153,7 +153,7 @@ "to": "h5", "flags": "n", "piece": "p", - "unambiguousSymbol": "pg", + "uas": "pg", "originalString": "h5" }, { @@ -164,7 +164,7 @@ "to": "f3", "flags": "n", "piece": "n", - "unambiguousSymbol": "NG", + "uas": "NG", "originalString": "Nf3" }, { @@ -175,7 +175,7 @@ "to": "g6", "flags": "n", "piece": "q", - "unambiguousSymbol": "q", + "uas": "q", "originalString": "Qg6" }, { @@ -186,7 +186,7 @@ "to": "h4", "flags": "n", "piece": "n", - "unambiguousSymbol": "NG", + "uas": "NG", "originalString": "Nh4" }, { @@ -197,7 +197,7 @@ "to": "g5", "flags": "n", "piece": "q", - "unambiguousSymbol": "q", + "uas": "q", "originalString": "Qg5" }, { @@ -208,9 +208,9 @@ "to": "h5", "flags": "c", "piece": "b", - "unambiguousSymbol": "BF", + "uas": "BF", "originalString": "Bxh5", - "capture": { "type": "p", "unambiguousSymbol": "pg" } + "capture": { "type": "p", "uas": "pg" } }, { "color": "b", @@ -220,9 +220,9 @@ "to": "h4", "flags": "c", "piece": "q", - "unambiguousSymbol": "q", + "uas": "q", "originalString": "Qxh4", - "capture": { "type": "n", "unambiguousSymbol": "NG" } + "capture": { "type": "n", "uas": "NG" } }, { "color": "w", @@ -232,7 +232,7 @@ "to": "f3", "flags": "n", "piece": "q", - "unambiguousSymbol": "Q", + "uas": "Q", "originalString": "Qf3" }, { @@ -243,7 +243,7 @@ "to": "d8", "flags": "n", "piece": "k", - "unambiguousSymbol": "k", + "uas": "k", "originalString": "Kd8" }, { @@ -254,9 +254,9 @@ "to": "f7", "flags": "c", "piece": "q", - "unambiguousSymbol": "Q", + "uas": "Q", "originalString": "Qxf7", - "capture": { "type": "p", "unambiguousSymbol": "pf" } + "capture": { "type": "p", "uas": "pf" } }, { "color": "b", @@ -266,7 +266,7 @@ "to": "c6", "flags": "n", "piece": "n", - "unambiguousSymbol": "nb", + "uas": "nb", "originalString": "Nc6" }, { @@ -277,7 +277,7 @@ "to": "e8", "flags": "n", "piece": "q", - "unambiguousSymbol": "Q", + "uas": "Q", "originalString": "Qe8#" } ], @@ -290,7 +290,7 @@ "to": "d4", "flags": "b", "piece": "p", - "unambiguousSymbol": "PD", + "uas": "PD", "originalString": "d4" }, { @@ -301,7 +301,7 @@ "to": "d5", "flags": "b", "piece": "p", - "unambiguousSymbol": "pd", + "uas": "pd", "originalString": "d5" }, { @@ -312,7 +312,7 @@ "to": "f3", "flags": "n", "piece": "n", - "unambiguousSymbol": "NG", + "uas": "NG", "originalString": "Nf3" }, { @@ -323,7 +323,7 @@ "to": "f6", "flags": "n", "piece": "n", - "unambiguousSymbol": "ng", + "uas": "ng", "originalString": "Nf6" }, { @@ -334,7 +334,7 @@ "to": "e3", "flags": "n", "piece": "p", - "unambiguousSymbol": "PE", + "uas": "PE", "originalString": "e3" }, { @@ -345,7 +345,7 @@ "to": "f5", "flags": "n", "piece": "b", - "unambiguousSymbol": "bc", + "uas": "bc", "originalString": "Bf5" }, { @@ -356,7 +356,7 @@ "to": "h4", "flags": "n", "piece": "n", - "unambiguousSymbol": "NG", + "uas": "NG", "originalString": "Nh4" }, { @@ -367,7 +367,7 @@ "to": "g6", "flags": "n", "piece": "b", - "unambiguousSymbol": "bc", + "uas": "bc", "originalString": "Bg6" }, { @@ -378,9 +378,9 @@ "to": "g6", "flags": "c", "piece": "n", - "unambiguousSymbol": "NG", + "uas": "NG", "originalString": "Nxg6", - "capture": { "type": "b", "unambiguousSymbol": "bc" } + "capture": { "type": "b", "uas": "bc" } }, { "color": "b", @@ -390,9 +390,9 @@ "to": "g6", "flags": "c", "piece": "p", - "unambiguousSymbol": "ph", + "uas": "ph", "originalString": "hxg6", - "capture": { "type": "n", "unambiguousSymbol": "ph" } + "capture": { "type": "n", "uas": "ph" } }, { "color": "w", @@ -402,7 +402,7 @@ "to": "d2", "flags": "n", "piece": "n", - "unambiguousSymbol": "NB", + "uas": "NB", "originalString": "Nd2" }, { @@ -413,7 +413,7 @@ "to": "e6", "flags": "n", "piece": "p", - "unambiguousSymbol": "pe", + "uas": "pe", "originalString": "e6" }, { @@ -424,7 +424,7 @@ "to": "d3", "flags": "n", "piece": "b", - "unambiguousSymbol": "BF", + "uas": "BF", "originalString": "Bd3" }, { @@ -435,7 +435,7 @@ "to": "d6", "flags": "n", "piece": "b", - "unambiguousSymbol": "bf", + "uas": "bf", "originalString": "Bd6" }, { @@ -446,7 +446,7 @@ "to": "e4", "flags": "n", "piece": "p", - "unambiguousSymbol": "PE", + "uas": "PE", "originalString": "e4" }, { @@ -457,9 +457,9 @@ "to": "e4", "flags": "c", "piece": "p", - "unambiguousSymbol": "pd", + "uas": "pd", "originalString": "dxe4", - "capture": { "type": "p", "unambiguousSymbol": "pd" } + "capture": { "type": "p", "uas": "pd" } }, { "color": "w", @@ -469,9 +469,9 @@ "to": "e4", "flags": "c", "piece": "n", - "unambiguousSymbol": "NB", + "uas": "NB", "originalString": "Nxe4", - "capture": { "type": "p", "unambiguousSymbol": "pd" } + "capture": { "type": "p", "uas": "pd" } }, { "color": "b", @@ -481,9 +481,9 @@ "to": "h2", "flags": "c", "piece": "r", - "unambiguousSymbol": "rh", + "uas": "rh", "originalString": "Rxh2", - "capture": { "type": "p", "unambiguousSymbol": "PH" } + "capture": { "type": "p", "uas": "PH" } }, { "color": "w", @@ -493,7 +493,7 @@ "to": "e2", "flags": "n", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Ke2" }, { @@ -504,9 +504,9 @@ "to": "h1", "flags": "c", "piece": "r", - "unambiguousSymbol": "rh", + "uas": "rh", "originalString": "Rxh1", - "capture": { "type": "r", "unambiguousSymbol": "RH" } + "capture": { "type": "r", "uas": "RH" } }, { "color": "w", @@ -516,9 +516,9 @@ "to": "h1", "flags": "c", "piece": "q", - "unambiguousSymbol": "Q", + "uas": "Q", "originalString": "Qxh1", - "capture": { "type": "r", "unambiguousSymbol": "rh" } + "capture": { "type": "r", "uas": "rh" } }, { "color": "b", @@ -528,7 +528,7 @@ "to": "c6", "flags": "n", "piece": "n", - "unambiguousSymbol": "nb", + "uas": "nb", "originalString": "Nc6" }, { @@ -539,7 +539,7 @@ "to": "g5", "flags": "n", "piece": "b", - "unambiguousSymbol": "BC", + "uas": "BC", "originalString": "Bg5" }, { @@ -550,7 +550,7 @@ "to": "e7", "flags": "n", "piece": "k", - "unambiguousSymbol": "k", + "uas": "k", "originalString": "Ke7" }, { @@ -561,7 +561,7 @@ "to": "h7", "flags": "n", "piece": "q", - "unambiguousSymbol": "Q", + "uas": "Q", "originalString": "Qh7" }, { @@ -572,9 +572,9 @@ "to": "d4", "flags": "c", "piece": "n", - "unambiguousSymbol": "nb", + "uas": "nb", "originalString": "Nxd4+", - "capture": { "type": "p", "unambiguousSymbol": "PD" } + "capture": { "type": "p", "uas": "PD" } }, { "color": "w", @@ -584,7 +584,7 @@ "to": "d2", "flags": "n", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Kd2" }, { @@ -595,7 +595,7 @@ "to": "e8", "flags": "n", "piece": "q", - "unambiguousSymbol": "q", + "uas": "q", "originalString": "Qe8" }, { @@ -606,9 +606,9 @@ "to": "g7", "flags": "c", "piece": "q", - "unambiguousSymbol": "Q", + "uas": "Q", "originalString": "Qxg7", - "capture": { "type": "p", "unambiguousSymbol": "pg" } + "capture": { "type": "p", "uas": "pg" } }, { "color": "b", @@ -618,7 +618,7 @@ "to": "h8", "flags": "n", "piece": "q", - "unambiguousSymbol": "q", + "uas": "q", "originalString": "Qh8" }, { @@ -629,9 +629,9 @@ "to": "f6", "flags": "c", "piece": "b", - "unambiguousSymbol": "BC", + "uas": "BC", "originalString": "Bxf6+", - "capture": { "type": "n", "unambiguousSymbol": "ng" } + "capture": { "type": "n", "uas": "ng" } }, { "color": "b", @@ -641,7 +641,7 @@ "to": "d7", "flags": "n", "piece": "k", - "unambiguousSymbol": "k", + "uas": "k", "originalString": "Kd7" }, { @@ -652,9 +652,9 @@ "to": "h8", "flags": "c", "piece": "q", - "unambiguousSymbol": "Q", + "uas": "Q", "originalString": "Qxh8", - "capture": { "type": "q", "unambiguousSymbol": "q" } + "capture": { "type": "q", "uas": "q" } }, { "color": "b", @@ -664,9 +664,9 @@ "to": "h8", "flags": "c", "piece": "r", - "unambiguousSymbol": "ra", + "uas": "ra", "originalString": "Rxh8", - "capture": { "type": "q", "unambiguousSymbol": "Q" } + "capture": { "type": "q", "uas": "Q" } }, { "color": "w", @@ -676,9 +676,9 @@ "to": "h8", "flags": "c", "piece": "b", - "unambiguousSymbol": "BC", + "uas": "BC", "originalString": "Bxh8", - "capture": { "type": "r", "unambiguousSymbol": "ra" } + "capture": { "type": "r", "uas": "ra" } } ], [ @@ -690,7 +690,7 @@ "to": "e4", "flags": "b", "piece": "p", - "unambiguousSymbol": "PE", + "uas": "PE", "originalString": "e4" }, { @@ -701,7 +701,7 @@ "to": "e5", "flags": "b", "piece": "p", - "unambiguousSymbol": "pe", + "uas": "pe", "originalString": "e5" }, { @@ -712,7 +712,7 @@ "to": "f3", "flags": "n", "piece": "n", - "unambiguousSymbol": "NG", + "uas": "NG", "originalString": "Nf3" }, { @@ -723,7 +723,7 @@ "to": "c6", "flags": "n", "piece": "n", - "unambiguousSymbol": "nb", + "uas": "nb", "originalString": "Nc6" }, { @@ -734,7 +734,7 @@ "to": "c4", "flags": "n", "piece": "b", - "unambiguousSymbol": "BF", + "uas": "BF", "originalString": "Bc4" }, { @@ -745,7 +745,7 @@ "to": "f6", "flags": "n", "piece": "n", - "unambiguousSymbol": "ng", + "uas": "ng", "originalString": "Nf6" }, { @@ -756,7 +756,7 @@ "to": "c3", "flags": "n", "piece": "n", - "unambiguousSymbol": "NB", + "uas": "NB", "originalString": "Nc3" }, { @@ -767,7 +767,7 @@ "to": "c5", "flags": "n", "piece": "b", - "unambiguousSymbol": "bf", + "uas": "bf", "originalString": "Bc5" }, { @@ -778,7 +778,7 @@ "to": "a3", "flags": "n", "piece": "p", - "unambiguousSymbol": "PA", + "uas": "PA", "originalString": "a3" }, { @@ -789,9 +789,9 @@ "to": "f2", "flags": "c", "piece": "b", - "unambiguousSymbol": "bf", + "uas": "bf", "originalString": "Bxf2+", - "capture": { "type": "p", "unambiguousSymbol": "PF" } + "capture": { "type": "p", "uas": "PF" } }, { "color": "w", @@ -801,9 +801,9 @@ "to": "f2", "flags": "c", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Kxf2", - "capture": { "type": "b", "unambiguousSymbol": "bf" } + "capture": { "type": "b", "uas": "bf" } }, { "color": "b", @@ -813,7 +813,7 @@ "to": "d4", "flags": "n", "piece": "n", - "unambiguousSymbol": "nb", + "uas": "nb", "originalString": "Nd4" }, { @@ -824,7 +824,7 @@ "to": "d3", "flags": "n", "piece": "p", - "unambiguousSymbol": "PD", + "uas": "PD", "originalString": "d3" }, { @@ -835,7 +835,7 @@ "to": "g4", "flags": "n", "piece": "n", - "unambiguousSymbol": "ng", + "uas": "ng", "originalString": "Ng4+" }, { @@ -846,7 +846,7 @@ "to": "f1", "flags": "n", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Kf1" }, { @@ -857,7 +857,7 @@ "to": "f6", "flags": "n", "piece": "q", - "unambiguousSymbol": "q", + "uas": "q", "originalString": "Qf6" }, { @@ -868,7 +868,7 @@ "to": "h3", "flags": "n", "piece": "p", - "unambiguousSymbol": "PH", + "uas": "PH", "originalString": "h3" }, { @@ -879,7 +879,7 @@ "to": "d5", "flags": "b", "piece": "p", - "unambiguousSymbol": "pd", + "uas": "pd", "originalString": "d5" }, { @@ -890,9 +890,9 @@ "to": "d5", "flags": "c", "piece": "n", - "unambiguousSymbol": "NB", + "uas": "NB", "originalString": "Nxd5", - "capture": { "type": "p", "unambiguousSymbol": "pd" } + "capture": { "type": "p", "uas": "pd" } }, { "color": "b", @@ -902,7 +902,7 @@ "to": "e6", "flags": "n", "piece": "q", - "unambiguousSymbol": "q", + "uas": "q", "originalString": "Qe6" }, { @@ -913,9 +913,9 @@ "to": "c7", "flags": "c", "piece": "n", - "unambiguousSymbol": "NB", + "uas": "NB", "originalString": "Nxc7+", - "capture": { "type": "p", "unambiguousSymbol": "pc" } + "capture": { "type": "p", "uas": "pc" } } ], [ @@ -927,7 +927,7 @@ "to": "e4", "flags": "b", "piece": "p", - "unambiguousSymbol": "PE", + "uas": "PE", "originalString": "e4" }, { @@ -938,7 +938,7 @@ "to": "c6", "flags": "n", "piece": "p", - "unambiguousSymbol": "pc", + "uas": "pc", "originalString": "c6" }, { @@ -949,7 +949,7 @@ "to": "c3", "flags": "n", "piece": "n", - "unambiguousSymbol": "NB", + "uas": "NB", "originalString": "Nc3" }, { @@ -960,7 +960,7 @@ "to": "d5", "flags": "b", "piece": "p", - "unambiguousSymbol": "pd", + "uas": "pd", "originalString": "d5" }, { @@ -971,7 +971,7 @@ "to": "f3", "flags": "n", "piece": "q", - "unambiguousSymbol": "Q", + "uas": "Q", "originalString": "Qf3" }, { @@ -982,9 +982,9 @@ "to": "e4", "flags": "c", "piece": "p", - "unambiguousSymbol": "pd", + "uas": "pd", "originalString": "dxe4", - "capture": { "type": "p", "unambiguousSymbol": "pd" } + "capture": { "type": "p", "uas": "pd" } }, { "color": "w", @@ -994,9 +994,9 @@ "to": "e4", "flags": "c", "piece": "n", - "unambiguousSymbol": "NB", + "uas": "NB", "originalString": "Nxe4", - "capture": { "type": "p", "unambiguousSymbol": "pd" } + "capture": { "type": "p", "uas": "pd" } }, { "color": "b", @@ -1006,7 +1006,7 @@ "to": "d7", "flags": "n", "piece": "n", - "unambiguousSymbol": "nb", + "uas": "nb", "originalString": "Nd7" }, { @@ -1017,7 +1017,7 @@ "to": "c4", "flags": "n", "piece": "b", - "unambiguousSymbol": "BF", + "uas": "BF", "originalString": "Bc4" }, { @@ -1028,7 +1028,7 @@ "to": "f6", "flags": "n", "piece": "n", - "unambiguousSymbol": "ng", + "uas": "ng", "originalString": "Ngf6" }, { @@ -1039,9 +1039,9 @@ "to": "f6", "flags": "c", "piece": "n", - "unambiguousSymbol": "NB", + "uas": "NB", "originalString": "Nxf6+", - "capture": { "type": "n", "unambiguousSymbol": "ng" } + "capture": { "type": "n", "uas": "ng" } }, { "color": "b", @@ -1051,9 +1051,9 @@ "to": "f6", "flags": "c", "piece": "n", - "unambiguousSymbol": "nb", + "uas": "nb", "originalString": "Nxf6", - "capture": { "type": "n", "unambiguousSymbol": "pg" } + "capture": { "type": "n", "uas": "pg" } }, { "color": "w", @@ -1063,7 +1063,7 @@ "to": "g3", "flags": "n", "piece": "q", - "unambiguousSymbol": "Q", + "uas": "Q", "originalString": "Qg3" }, { @@ -1074,7 +1074,7 @@ "to": "f5", "flags": "n", "piece": "b", - "unambiguousSymbol": "bc", + "uas": "bc", "originalString": "Bf5" }, { @@ -1085,7 +1085,7 @@ "to": "d3", "flags": "n", "piece": "p", - "unambiguousSymbol": "PD", + "uas": "PD", "originalString": "d3" }, { @@ -1096,7 +1096,7 @@ "to": "g6", "flags": "n", "piece": "b", - "unambiguousSymbol": "bc", + "uas": "bc", "originalString": "Bg6" }, { @@ -1107,7 +1107,7 @@ "to": "e2", "flags": "n", "piece": "n", - "unambiguousSymbol": "NG", + "uas": "NG", "originalString": "Ne2" }, { @@ -1118,7 +1118,7 @@ "to": "e6", "flags": "n", "piece": "p", - "unambiguousSymbol": "pe", + "uas": "pe", "originalString": "e6" }, { @@ -1129,7 +1129,7 @@ "to": "f4", "flags": "n", "piece": "b", - "unambiguousSymbol": "BC", + "uas": "BC", "originalString": "Bf4" }, { @@ -1140,7 +1140,7 @@ "to": "h5", "flags": "n", "piece": "n", - "unambiguousSymbol": "nb", + "uas": "nb", "originalString": "Nh5" }, { @@ -1151,7 +1151,7 @@ "to": "f3", "flags": "n", "piece": "q", - "unambiguousSymbol": "pb", + "uas": "pb", "originalString": "Qf3" }, { @@ -1162,9 +1162,9 @@ "to": "f4", "flags": "c", "piece": "n", - "unambiguousSymbol": "nb", + "uas": "nb", "originalString": "Nxf4", - "capture": { "type": "b", "unambiguousSymbol": "BC" } + "capture": { "type": "b", "uas": "BC" } }, { "color": "w", @@ -1174,9 +1174,9 @@ "to": "f4", "flags": "c", "piece": "n", - "unambiguousSymbol": "NG", + "uas": "NG", "originalString": "Nxf4", - "capture": { "type": "n", "unambiguousSymbol": "nb" } + "capture": { "type": "n", "uas": "nb" } }, { "color": "b", @@ -1186,7 +1186,7 @@ "to": "e7", "flags": "n", "piece": "b", - "unambiguousSymbol": "bf", + "uas": "bf", "originalString": "Be7" }, { @@ -1197,9 +1197,9 @@ "to": "e6", "flags": "c", "piece": "b", - "unambiguousSymbol": "BF", + "uas": "BF", "originalString": "Bxe6", - "capture": { "type": "p", "unambiguousSymbol": "pe" } + "capture": { "type": "p", "uas": "pe" } }, { "color": "b", @@ -1209,9 +1209,9 @@ "to": "e6", "flags": "c", "piece": "p", - "unambiguousSymbol": "pf", + "uas": "pf", "originalString": "fxe6", - "capture": { "type": "b", "unambiguousSymbol": "pf" } + "capture": { "type": "b", "uas": "pf" } }, { "color": "w", @@ -1221,9 +1221,9 @@ "to": "e6", "flags": "c", "piece": "n", - "unambiguousSymbol": "NG", + "uas": "NG", "originalString": "Nxe6", - "capture": { "type": "p", "unambiguousSymbol": "pf" } + "capture": { "type": "p", "uas": "pf" } }, { "color": "b", @@ -1233,7 +1233,7 @@ "to": "a5", "flags": "n", "piece": "q", - "unambiguousSymbol": "q", + "uas": "q", "originalString": "Qa5+" }, { @@ -1244,7 +1244,7 @@ "to": "c3", "flags": "n", "piece": "p", - "unambiguousSymbol": "PC", + "uas": "PC", "originalString": "c3" }, { @@ -1255,7 +1255,7 @@ "to": "e5", "flags": "n", "piece": "q", - "unambiguousSymbol": "q", + "uas": "q", "originalString": "Qe5+" }, { @@ -1266,7 +1266,7 @@ "to": "e3", "flags": "n", "piece": "q", - "unambiguousSymbol": "pb", + "uas": "pb", "originalString": "Qe3" }, { @@ -1277,9 +1277,9 @@ "to": "e3", "flags": "c", "piece": "q", - "unambiguousSymbol": "q", + "uas": "q", "originalString": "Qxe3+", - "capture": { "type": "q", "unambiguousSymbol": "pb" } + "capture": { "type": "q", "uas": "pb" } }, { "color": "w", @@ -1289,9 +1289,9 @@ "to": "e3", "flags": "c", "piece": "p", - "unambiguousSymbol": "PF", + "uas": "PF", "originalString": "fxe3", - "capture": { "type": "q", "unambiguousSymbol": "PF" } + "capture": { "type": "q", "uas": "PF" } }, { "color": "b", @@ -1301,7 +1301,7 @@ "to": "d7", "flags": "n", "piece": "k", - "unambiguousSymbol": "k", + "uas": "k", "originalString": "Kd7" }, { @@ -1312,7 +1312,7 @@ "to": "f4", "flags": "n", "piece": "n", - "unambiguousSymbol": "NG", + "uas": "NG", "originalString": "Nf4" }, { @@ -1323,7 +1323,7 @@ "to": "d6", "flags": "n", "piece": "b", - "unambiguousSymbol": "bf", + "uas": "bf", "originalString": "Bd6" }, { @@ -1334,9 +1334,9 @@ "to": "g6", "flags": "c", "piece": "n", - "unambiguousSymbol": "NG", + "uas": "NG", "originalString": "Nxg6", - "capture": { "type": "b", "unambiguousSymbol": "bc" } + "capture": { "type": "b", "uas": "bc" } }, { "color": "b", @@ -1346,9 +1346,9 @@ "to": "g6", "flags": "c", "piece": "p", - "unambiguousSymbol": "ph", + "uas": "ph", "originalString": "hxg6", - "capture": { "type": "n", "unambiguousSymbol": "ph" } + "capture": { "type": "n", "uas": "ph" } }, { "color": "w", @@ -1358,7 +1358,7 @@ "to": "h3", "flags": "n", "piece": "p", - "unambiguousSymbol": "PH", + "uas": "PH", "originalString": "h3" }, { @@ -1369,7 +1369,7 @@ "to": "g3", "flags": "n", "piece": "b", - "unambiguousSymbol": "bf", + "uas": "bf", "originalString": "Bg3+" }, { @@ -1380,7 +1380,7 @@ "to": "d2", "flags": "n", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Kd2" }, { @@ -1391,7 +1391,7 @@ "to": "f8", "flags": "n", "piece": "r", - "unambiguousSymbol": "ra", + "uas": "ra", "originalString": "Raf8" }, { @@ -1402,7 +1402,7 @@ "to": "f1", "flags": "n", "piece": "r", - "unambiguousSymbol": "RH", + "uas": "RH", "originalString": "Rhf1" }, { @@ -1413,7 +1413,7 @@ "to": "e7", "flags": "n", "piece": "k", - "unambiguousSymbol": "k", + "uas": "k", "originalString": "Ke7" }, { @@ -1424,7 +1424,7 @@ "to": "d4", "flags": "n", "piece": "p", - "unambiguousSymbol": "PD", + "uas": "PD", "originalString": "d4" }, { @@ -1435,9 +1435,9 @@ "to": "f1", "flags": "c", "piece": "r", - "unambiguousSymbol": "ra", + "uas": "ra", "originalString": "Rxf1", - "capture": { "type": "r", "unambiguousSymbol": "RH" } + "capture": { "type": "r", "uas": "RH" } }, { "color": "w", @@ -1447,9 +1447,9 @@ "to": "f1", "flags": "c", "piece": "r", - "unambiguousSymbol": "RA", + "uas": "RA", "originalString": "Rxf1", - "capture": { "type": "r", "unambiguousSymbol": "ra" } + "capture": { "type": "r", "uas": "ra" } }, { "color": "b", @@ -1459,7 +1459,7 @@ "to": "f8", "flags": "n", "piece": "r", - "unambiguousSymbol": "rh", + "uas": "rh", "originalString": "Rf8" }, { @@ -1470,9 +1470,9 @@ "to": "f8", "flags": "c", "piece": "r", - "unambiguousSymbol": "RA", + "uas": "RA", "originalString": "Rxf8", - "capture": { "type": "r", "unambiguousSymbol": "rh" } + "capture": { "type": "r", "uas": "rh" } }, { "color": "b", @@ -1482,9 +1482,9 @@ "to": "f8", "flags": "c", "piece": "k", - "unambiguousSymbol": "k", + "uas": "k", "originalString": "Kxf8", - "capture": { "type": "r", "unambiguousSymbol": "RA" } + "capture": { "type": "r", "uas": "RA" } }, { "color": "w", @@ -1494,7 +1494,7 @@ "to": "e4", "flags": "n", "piece": "p", - "unambiguousSymbol": "PF", + "uas": "PF", "originalString": "e4" }, { @@ -1505,7 +1505,7 @@ "to": "e7", "flags": "n", "piece": "k", - "unambiguousSymbol": "k", + "uas": "k", "originalString": "Ke7" }, { @@ -1516,7 +1516,7 @@ "to": "e3", "flags": "n", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Ke3" }, { @@ -1527,7 +1527,7 @@ "to": "g5", "flags": "n", "piece": "p", - "unambiguousSymbol": "ph", + "uas": "ph", "originalString": "g5" }, { @@ -1538,7 +1538,7 @@ "to": "f3", "flags": "n", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Kf3" }, { @@ -1549,7 +1549,7 @@ "to": "e1", "flags": "n", "piece": "b", - "unambiguousSymbol": "bf", + "uas": "bf", "originalString": "Be1" }, { @@ -1560,7 +1560,7 @@ "to": "g4", "flags": "n", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Kg4" }, { @@ -1571,7 +1571,7 @@ "to": "d2", "flags": "n", "piece": "b", - "unambiguousSymbol": "bf", + "uas": "bf", "originalString": "Bd2" }, { @@ -1582,7 +1582,7 @@ "to": "f5", "flags": "n", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Kf5" }, { @@ -1593,7 +1593,7 @@ "to": "c1", "flags": "n", "piece": "b", - "unambiguousSymbol": "bf", + "uas": "bf", "originalString": "Bc1" }, { @@ -1604,7 +1604,7 @@ "to": "g6", "flags": "n", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Kg6" }, { @@ -1615,7 +1615,7 @@ "to": "f8", "flags": "n", "piece": "k", - "unambiguousSymbol": "k", + "uas": "k", "originalString": "Kf8" }, { @@ -1626,7 +1626,7 @@ "to": "e5", "flags": "n", "piece": "p", - "unambiguousSymbol": "PF", + "uas": "PF", "originalString": "e5" }, { @@ -1637,9 +1637,9 @@ "to": "b2", "flags": "c", "piece": "b", - "unambiguousSymbol": "bf", + "uas": "bf", "originalString": "Bxb2", - "capture": { "type": "p", "unambiguousSymbol": "PB" } + "capture": { "type": "p", "uas": "PB" } }, { "color": "w", @@ -1649,9 +1649,9 @@ "to": "g5", "flags": "c", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Kxg5", - "capture": { "type": "p", "unambiguousSymbol": "ph" } + "capture": { "type": "p", "uas": "ph" } }, { "color": "b", @@ -1661,9 +1661,9 @@ "to": "c3", "flags": "c", "piece": "b", - "unambiguousSymbol": "bf", + "uas": "bf", "originalString": "Bxc3", - "capture": { "type": "p", "unambiguousSymbol": "PC" } + "capture": { "type": "p", "uas": "PC" } }, { "color": "w", @@ -1673,7 +1673,7 @@ "to": "h4", "flags": "n", "piece": "p", - "unambiguousSymbol": "PH", + "uas": "PH", "originalString": "h4" }, { @@ -1684,9 +1684,9 @@ "to": "d4", "flags": "c", "piece": "b", - "unambiguousSymbol": "bf", + "uas": "bf", "originalString": "Bxd4", - "capture": { "type": "p", "unambiguousSymbol": "PD" } + "capture": { "type": "p", "uas": "PD" } }, { "color": "w", @@ -1696,7 +1696,7 @@ "to": "h5", "flags": "n", "piece": "p", - "unambiguousSymbol": "PH", + "uas": "PH", "originalString": "h5" }, { @@ -1707,9 +1707,9 @@ "to": "e5", "flags": "c", "piece": "b", - "unambiguousSymbol": "bf", + "uas": "bf", "originalString": "Bxe5", - "capture": { "type": "p", "unambiguousSymbol": "PF" } + "capture": { "type": "p", "uas": "PF" } }, { "color": "w", @@ -1719,7 +1719,7 @@ "to": "g4", "flags": "b", "piece": "p", - "unambiguousSymbol": "PG", + "uas": "PG", "originalString": "g4" }, { @@ -1730,7 +1730,7 @@ "to": "b2", "flags": "n", "piece": "b", - "unambiguousSymbol": "bf", + "uas": "bf", "originalString": "Bb2" }, { @@ -1741,7 +1741,7 @@ "to": "f5", "flags": "n", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Kf5" }, { @@ -1752,7 +1752,7 @@ "to": "f7", "flags": "n", "piece": "k", - "unambiguousSymbol": "k", + "uas": "k", "originalString": "Kf7" }, { @@ -1763,7 +1763,7 @@ "to": "g5", "flags": "n", "piece": "p", - "unambiguousSymbol": "PG", + "uas": "PG", "originalString": "g5" }, { @@ -1774,7 +1774,7 @@ "to": "c1", "flags": "n", "piece": "b", - "unambiguousSymbol": "bf", + "uas": "bf", "originalString": "Bc1" }, { @@ -1785,7 +1785,7 @@ "to": "g6", "flags": "n", "piece": "p", - "unambiguousSymbol": "PG", + "uas": "PG", "originalString": "g6+" }, { @@ -1796,7 +1796,7 @@ "to": "e7", "flags": "n", "piece": "k", - "unambiguousSymbol": "k", + "uas": "k", "originalString": "Ke7" }, { @@ -1807,7 +1807,7 @@ "to": "e5", "flags": "n", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Ke5" }, { @@ -1818,7 +1818,7 @@ "to": "b5", "flags": "b", "piece": "p", - "unambiguousSymbol": "pb", + "uas": "pb", "originalString": "b5" }, { @@ -1829,7 +1829,7 @@ "to": "d4", "flags": "n", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Kd4" }, { @@ -1840,7 +1840,7 @@ "to": "d6", "flags": "n", "piece": "k", - "unambiguousSymbol": "k", + "uas": "k", "originalString": "Kd6" }, { @@ -1851,7 +1851,7 @@ "to": "c3", "flags": "n", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Kc3" }, { @@ -1862,7 +1862,7 @@ "to": "c5", "flags": "n", "piece": "p", - "unambiguousSymbol": "pc", + "uas": "pc", "originalString": "c5" }, { @@ -1873,7 +1873,7 @@ "to": "a3", "flags": "n", "piece": "p", - "unambiguousSymbol": "PA", + "uas": "PA", "originalString": "a3" }, { @@ -1884,7 +1884,7 @@ "to": "g5", "flags": "n", "piece": "b", - "unambiguousSymbol": "bf", + "uas": "bf", "originalString": "Bg5" }, { @@ -1895,7 +1895,7 @@ "to": "a4", "flags": "n", "piece": "p", - "unambiguousSymbol": "PA", + "uas": "PA", "originalString": "a4" }, { @@ -1906,9 +1906,9 @@ "to": "a4", "flags": "c", "piece": "p", - "unambiguousSymbol": "pb", + "uas": "pb", "originalString": "bxa4", - "capture": { "type": "p", "unambiguousSymbol": "pb" } + "capture": { "type": "p", "uas": "pb" } }, { "color": "w", @@ -1918,7 +1918,7 @@ "to": "b2", "flags": "n", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Kb2" }, { @@ -1929,7 +1929,7 @@ "to": "d5", "flags": "n", "piece": "k", - "unambiguousSymbol": "k", + "uas": "k", "originalString": "Kd5" }, { @@ -1940,7 +1940,7 @@ "to": "a3", "flags": "n", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Ka3" }, { @@ -1951,7 +1951,7 @@ "to": "d4", "flags": "n", "piece": "k", - "unambiguousSymbol": "k", + "uas": "k", "originalString": "Kd4" }, { @@ -1962,9 +1962,9 @@ "to": "a4", "flags": "c", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Kxa4", - "capture": { "type": "p", "unambiguousSymbol": "pb" } + "capture": { "type": "p", "uas": "pb" } }, { "color": "b", @@ -1974,7 +1974,7 @@ "to": "c4", "flags": "n", "piece": "p", - "unambiguousSymbol": "pc", + "uas": "pc", "originalString": "c4" } ], @@ -1987,7 +1987,7 @@ "to": "e4", "flags": "b", "piece": "p", - "unambiguousSymbol": "PE", + "uas": "PE", "originalString": "e4" }, { @@ -1998,7 +1998,7 @@ "to": "e6", "flags": "n", "piece": "p", - "unambiguousSymbol": "pe", + "uas": "pe", "originalString": "e6" }, { @@ -2009,7 +2009,7 @@ "to": "c4", "flags": "n", "piece": "b", - "unambiguousSymbol": "BF", + "uas": "BF", "originalString": "Bc4" }, { @@ -2020,7 +2020,7 @@ "to": "d5", "flags": "b", "piece": "p", - "unambiguousSymbol": "pd", + "uas": "pd", "originalString": "d5" }, { @@ -2031,9 +2031,9 @@ "to": "d5", "flags": "c", "piece": "p", - "unambiguousSymbol": "PE", + "uas": "PE", "originalString": "exd5", - "capture": { "type": "p", "unambiguousSymbol": "PE" } + "capture": { "type": "p", "uas": "PE" } }, { "color": "b", @@ -2043,9 +2043,9 @@ "to": "d5", "flags": "c", "piece": "p", - "unambiguousSymbol": "pe", + "uas": "pe", "originalString": "exd5", - "capture": { "type": "p", "unambiguousSymbol": "pe" } + "capture": { "type": "p", "uas": "pe" } }, { "color": "w", @@ -2055,7 +2055,7 @@ "to": "b3", "flags": "n", "piece": "b", - "unambiguousSymbol": "BF", + "uas": "BF", "originalString": "Bb3" }, { @@ -2066,7 +2066,7 @@ "to": "f6", "flags": "n", "piece": "n", - "unambiguousSymbol": "ng", + "uas": "ng", "originalString": "Nf6" }, { @@ -2077,7 +2077,7 @@ "to": "d4", "flags": "b", "piece": "p", - "unambiguousSymbol": "PD", + "uas": "PD", "originalString": "d4" }, { @@ -2088,7 +2088,7 @@ "to": "e7", "flags": "n", "piece": "b", - "unambiguousSymbol": "bf", + "uas": "bf", "originalString": "Be7" }, { @@ -2099,7 +2099,7 @@ "to": "f3", "flags": "n", "piece": "n", - "unambiguousSymbol": "NG", + "uas": "NG", "originalString": "Nf3" }, { @@ -2110,7 +2110,7 @@ "to": "g8", "flags": "k", "piece": "k", - "unambiguousSymbol": "k", + "uas": "k", "originalString": "O-O" }, { @@ -2121,7 +2121,7 @@ "to": "g5", "flags": "n", "piece": "b", - "unambiguousSymbol": "BC", + "uas": "BC", "originalString": "Bg5" }, { @@ -2132,7 +2132,7 @@ "to": "h6", "flags": "n", "piece": "p", - "unambiguousSymbol": "ph", + "uas": "ph", "originalString": "h6" }, { @@ -2143,9 +2143,9 @@ "to": "f6", "flags": "c", "piece": "b", - "unambiguousSymbol": "BC", + "uas": "BC", "originalString": "Bxf6", - "capture": { "type": "n", "unambiguousSymbol": "ng" } + "capture": { "type": "n", "uas": "ng" } }, { "color": "b", @@ -2155,9 +2155,9 @@ "to": "f6", "flags": "c", "piece": "b", - "unambiguousSymbol": "bf", + "uas": "bf", "originalString": "Bxf6", - "capture": { "type": "b", "unambiguousSymbol": "BC" } + "capture": { "type": "b", "uas": "BC" } }, { "color": "w", @@ -2167,7 +2167,7 @@ "to": "g1", "flags": "k", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "O-O" }, { @@ -2178,7 +2178,7 @@ "to": "c6", "flags": "n", "piece": "p", - "unambiguousSymbol": "pc", + "uas": "pc", "originalString": "c6" }, { @@ -2189,7 +2189,7 @@ "to": "e1", "flags": "n", "piece": "r", - "unambiguousSymbol": "RH", + "uas": "RH", "originalString": "Re1" }, { @@ -2200,7 +2200,7 @@ "to": "f5", "flags": "n", "piece": "b", - "unambiguousSymbol": "bc", + "uas": "bc", "originalString": "Bf5" }, { @@ -2211,7 +2211,7 @@ "to": "c4", "flags": "b", "piece": "p", - "unambiguousSymbol": "PC", + "uas": "PC", "originalString": "c4?!" }, { @@ -2222,9 +2222,9 @@ "to": "c4", "flags": "c", "piece": "p", - "unambiguousSymbol": "pe", + "uas": "pe", "originalString": "dxc4", - "capture": { "type": "p", "unambiguousSymbol": "pe" } + "capture": { "type": "p", "uas": "pe" } }, { "color": "w", @@ -2234,9 +2234,9 @@ "to": "c4", "flags": "c", "piece": "b", - "unambiguousSymbol": "BF", + "uas": "BF", "originalString": "Bxc4", - "capture": { "type": "p", "unambiguousSymbol": "pe" } + "capture": { "type": "p", "uas": "pe" } }, { "color": "b", @@ -2246,7 +2246,7 @@ "to": "d7", "flags": "n", "piece": "n", - "unambiguousSymbol": "nb", + "uas": "nb", "originalString": "Nd7?!" }, { @@ -2257,7 +2257,7 @@ "to": "c3", "flags": "n", "piece": "n", - "unambiguousSymbol": "NB", + "uas": "NB", "originalString": "Nc3" }, { @@ -2268,7 +2268,7 @@ "to": "b6", "flags": "n", "piece": "n", - "unambiguousSymbol": "nb", + "uas": "nb", "originalString": "Nb6" }, { @@ -2279,7 +2279,7 @@ "to": "b3", "flags": "n", "piece": "p", - "unambiguousSymbol": "PB", + "uas": "PB", "originalString": "b3?!" }, { @@ -2290,9 +2290,9 @@ "to": "c4", "flags": "c", "piece": "n", - "unambiguousSymbol": "nb", + "uas": "nb", "originalString": "Nxc4", - "capture": { "type": "b", "unambiguousSymbol": "BF" } + "capture": { "type": "b", "uas": "BF" } }, { "color": "w", @@ -2302,9 +2302,9 @@ "to": "c4", "flags": "c", "piece": "p", - "unambiguousSymbol": "PB", + "uas": "PB", "originalString": "bxc4", - "capture": { "type": "n", "unambiguousSymbol": "PB" } + "capture": { "type": "n", "uas": "PB" } }, { "color": "b", @@ -2314,7 +2314,7 @@ "to": "a5", "flags": "n", "piece": "q", - "unambiguousSymbol": "q", + "uas": "q", "originalString": "Qa5" }, { @@ -2325,7 +2325,7 @@ "to": "c1", "flags": "n", "piece": "r", - "unambiguousSymbol": "RA", + "uas": "RA", "originalString": "Rc1" }, { @@ -2336,7 +2336,7 @@ "to": "d8", "flags": "n", "piece": "r", - "unambiguousSymbol": "ra", + "uas": "ra", "originalString": "Rad8" }, { @@ -2347,7 +2347,7 @@ "to": "d5", "flags": "n", "piece": "p", - "unambiguousSymbol": "PD", + "uas": "PD", "originalString": "d5??" }, { @@ -2358,9 +2358,9 @@ "to": "c3", "flags": "c", "piece": "b", - "unambiguousSymbol": "bf", + "uas": "bf", "originalString": "Bxc3", - "capture": { "type": "n", "unambiguousSymbol": "NB" } + "capture": { "type": "n", "uas": "NB" } }, { "color": "w", @@ -2370,7 +2370,7 @@ "to": "e5", "flags": "n", "piece": "r", - "unambiguousSymbol": "RH", + "uas": "RH", "originalString": "Re5?" }, { @@ -2381,9 +2381,9 @@ "to": "e5", "flags": "c", "piece": "b", - "unambiguousSymbol": "bf", + "uas": "bf", "originalString": "Bxe5", - "capture": { "type": "r", "unambiguousSymbol": "RH" } + "capture": { "type": "r", "uas": "RH" } }, { "color": "w", @@ -2393,9 +2393,9 @@ "to": "e5", "flags": "c", "piece": "n", - "unambiguousSymbol": "NG", + "uas": "NG", "originalString": "Nxe5", - "capture": { "type": "b", "unambiguousSymbol": "bf" } + "capture": { "type": "b", "uas": "bf" } }, { "color": "b", @@ -2405,9 +2405,9 @@ "to": "d5", "flags": "c", "piece": "p", - "unambiguousSymbol": "pc", + "uas": "pc", "originalString": "cxd5", - "capture": { "type": "p", "unambiguousSymbol": "pc" } + "capture": { "type": "p", "uas": "pc" } }, { "color": "w", @@ -2417,7 +2417,7 @@ "to": "e1", "flags": "n", "piece": "q", - "unambiguousSymbol": "Q", + "uas": "Q", "originalString": "Qe1?" }, { @@ -2428,7 +2428,7 @@ "to": "e6", "flags": "n", "piece": "b", - "unambiguousSymbol": "bc", + "uas": "bc", "originalString": "Be6??" }, { @@ -2439,7 +2439,7 @@ "to": "d1", "flags": "n", "piece": "r", - "unambiguousSymbol": "RA", + "uas": "RA", "originalString": "Rd1??" }, { @@ -2450,9 +2450,9 @@ "to": "c4", "flags": "c", "piece": "p", - "unambiguousSymbol": "pc", + "uas": "pc", "originalString": "dxc4", - "capture": { "type": "p", "unambiguousSymbol": "pc" } + "capture": { "type": "p", "uas": "pc" } }, { "color": "w", @@ -2462,9 +2462,9 @@ "to": "d8", "flags": "c", "piece": "r", - "unambiguousSymbol": "RA", + "uas": "RA", "originalString": "Rxd8?!", - "capture": { "type": "r", "unambiguousSymbol": "ra" } + "capture": { "type": "r", "uas": "ra" } }, { "color": "b", @@ -2474,9 +2474,9 @@ "to": "d8", "flags": "c", "piece": "r", - "unambiguousSymbol": "rh", + "uas": "rh", "originalString": "Rxd8?!", - "capture": { "type": "r", "unambiguousSymbol": "RA" } + "capture": { "type": "r", "uas": "RA" } }, { "color": "w", @@ -2486,7 +2486,7 @@ "to": "c3", "flags": "n", "piece": "q", - "unambiguousSymbol": "Q", + "uas": "Q", "originalString": "Qc3?!" }, { @@ -2497,9 +2497,9 @@ "to": "c3", "flags": "c", "piece": "q", - "unambiguousSymbol": "q", + "uas": "q", "originalString": "Qxc3?!", - "capture": { "type": "q", "unambiguousSymbol": "Q" } + "capture": { "type": "q", "uas": "Q" } }, { "color": "w", @@ -2509,7 +2509,7 @@ "to": "g3", "flags": "n", "piece": "p", - "unambiguousSymbol": "PG", + "uas": "PG", "originalString": "g3" }, { @@ -2520,7 +2520,7 @@ "to": "d1", "flags": "n", "piece": "r", - "unambiguousSymbol": "rh", + "uas": "rh", "originalString": "Rd1+?!" }, { @@ -2531,7 +2531,7 @@ "to": "g2", "flags": "n", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Kg2" }, { @@ -2542,7 +2542,7 @@ "to": "e1", "flags": "n", "piece": "q", - "unambiguousSymbol": "q", + "uas": "q", "originalString": "Qe1?!" }, { @@ -2553,7 +2553,7 @@ "to": "f3", "flags": "n", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Kf3" }, { @@ -2564,9 +2564,9 @@ "to": "e5", "flags": "c", "piece": "q", - "unambiguousSymbol": "PH", + "uas": "PH", "originalString": "Qxe5", - "capture": { "type": "n", "unambiguousSymbol": "NG" } + "capture": { "type": "n", "uas": "NG" } }, { "color": "w", @@ -2576,7 +2576,7 @@ "to": "g2", "flags": "n", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Kg2" }, { @@ -2587,7 +2587,7 @@ "to": "d5", "flags": "n", "piece": "b", - "unambiguousSymbol": "bc", + "uas": "bc", "originalString": "Bd5+?!" }, { @@ -2598,7 +2598,7 @@ "to": "h3", "flags": "n", "piece": "k", - "unambiguousSymbol": "K", + "uas": "K", "originalString": "Kh3" }, { @@ -2609,7 +2609,7 @@ "to": "h5", "flags": "n", "piece": "q", - "unambiguousSymbol": "PF", + "uas": "PF", "originalString": "Qh5#" } ] diff --git a/historiestst.json b/historiestst.json deleted file mode 100644 index 8cc3ace..0000000 --- a/historiestst.json +++ /dev/null @@ -1,2616 +0,0 @@ -[ - [ - { - "color": "w", - "fromIndex": 100, - "toIndex": 68, - "from": "e2", - "to": "e4", - "flags": "b", - "piece": "p", - "unambiguousSymbol": "PE", - "originalString": "e4" - }, - { - "color": "b", - "fromIndex": 20, - "toIndex": 36, - "from": "e7", - "to": "e6", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "pe", - "originalString": "e6" - }, - { - "color": "w", - "fromIndex": 99, - "toIndex": 67, - "from": "d2", - "to": "d4", - "flags": "b", - "piece": "p", - "unambiguousSymbol": "PD", - "originalString": "d4" - }, - { - "color": "b", - "fromIndex": 17, - "toIndex": 33, - "from": "b7", - "to": "b6", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "pb", - "originalString": "b6" - }, - { - "color": "w", - "fromIndex": 96, - "toIndex": 80, - "from": "a2", - "to": "a3", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PA", - "originalString": "a3" - }, - { - "color": "b", - "fromIndex": 2, - "toIndex": 17, - "from": "c8", - "to": "b7", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "bc", - "originalString": "Bb7" - }, - { - "color": "w", - "fromIndex": 113, - "toIndex": 82, - "from": "b1", - "to": "c3", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "NB", - "originalString": "Nc3" - }, - { - "color": "b", - "fromIndex": 6, - "toIndex": 39, - "from": "g8", - "to": "h6", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "ng", - "originalString": "Nh6" - }, - { - "color": "w", - "fromIndex": 114, - "toIndex": 39, - "from": "c1", - "to": "h6", - "flags": "c", - "piece": "b", - "unambiguousSymbol": "BC", - "originalString": "Bxh6", - "capture": { "type": "n", "unambiguousSymbol": "ng" } - }, - { - "color": "b", - "fromIndex": 22, - "toIndex": 39, - "from": "g7", - "to": "h6", - "flags": "c", - "piece": "p", - "unambiguousSymbol": "pg", - "originalString": "gxh6", - "capture": { "type": "b", "unambiguousSymbol": "BC" } - }, - { - "color": "w", - "fromIndex": 117, - "toIndex": 100, - "from": "f1", - "to": "e2", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "BF", - "originalString": "Be2" - }, - { - "color": "b", - "fromIndex": 3, - "toIndex": 54, - "from": "d8", - "to": "g5", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "q", - "originalString": "Qg5" - }, - { - "color": "w", - "fromIndex": 100, - "toIndex": 70, - "from": "e2", - "to": "g4", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "BF", - "originalString": "Bg4" - }, - { - "color": "b", - "fromIndex": 39, - "toIndex": 55, - "from": "h6", - "to": "h5", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "pg", - "originalString": "h5" - }, - { - "color": "w", - "fromIndex": 118, - "toIndex": 85, - "from": "g1", - "to": "f3", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "NG", - "originalString": "Nf3" - }, - { - "color": "b", - "fromIndex": 54, - "toIndex": 38, - "from": "g5", - "to": "g6", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "q", - "originalString": "Qg6" - }, - { - "color": "w", - "fromIndex": 85, - "toIndex": 71, - "from": "f3", - "to": "h4", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "NG", - "originalString": "Nh4" - }, - { - "color": "b", - "fromIndex": 38, - "toIndex": 54, - "from": "g6", - "to": "g5", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "q", - "originalString": "Qg5" - }, - { - "color": "w", - "fromIndex": 70, - "toIndex": 55, - "from": "g4", - "to": "h5", - "flags": "c", - "piece": "b", - "unambiguousSymbol": "BF", - "originalString": "Bxh5", - "capture": { "type": "p", "unambiguousSymbol": "pg" } - }, - { - "color": "b", - "fromIndex": 54, - "toIndex": 71, - "from": "g5", - "to": "h4", - "flags": "c", - "piece": "q", - "unambiguousSymbol": "q", - "originalString": "Qxh4", - "capture": { "type": "n", "unambiguousSymbol": "NG" } - }, - { - "color": "w", - "fromIndex": 115, - "toIndex": 85, - "from": "d1", - "to": "f3", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "Q", - "originalString": "Qf3" - }, - { - "color": "b", - "fromIndex": 4, - "toIndex": 3, - "from": "e8", - "to": "d8", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "k", - "originalString": "Kd8" - }, - { - "color": "w", - "fromIndex": 85, - "toIndex": 21, - "from": "f3", - "to": "f7", - "flags": "c", - "piece": "q", - "unambiguousSymbol": "Q", - "originalString": "Qxf7", - "capture": { "type": "p", "unambiguousSymbol": "pf" } - }, - { - "color": "b", - "fromIndex": 1, - "toIndex": 34, - "from": "b8", - "to": "c6", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "nb", - "originalString": "Nc6" - }, - { - "color": "w", - "fromIndex": 21, - "toIndex": 4, - "from": "f7", - "to": "e8", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "Q", - "originalString": "Qe8#" - } - ], - [ - { - "color": "w", - "fromIndex": 99, - "toIndex": 67, - "from": "d2", - "to": "d4", - "flags": "b", - "piece": "p", - "unambiguousSymbol": "PD", - "originalString": "d4" - }, - { - "color": "b", - "fromIndex": 19, - "toIndex": 51, - "from": "d7", - "to": "d5", - "flags": "b", - "piece": "p", - "unambiguousSymbol": "pd", - "originalString": "d5" - }, - { - "color": "w", - "fromIndex": 118, - "toIndex": 85, - "from": "g1", - "to": "f3", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "NG", - "originalString": "Nf3" - }, - { - "color": "b", - "fromIndex": 6, - "toIndex": 37, - "from": "g8", - "to": "f6", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "ng", - "originalString": "Nf6" - }, - { - "color": "w", - "fromIndex": 100, - "toIndex": 84, - "from": "e2", - "to": "e3", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PE", - "originalString": "e3" - }, - { - "color": "b", - "fromIndex": 2, - "toIndex": 53, - "from": "c8", - "to": "f5", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "bc", - "originalString": "Bf5" - }, - { - "color": "w", - "fromIndex": 85, - "toIndex": 71, - "from": "f3", - "to": "h4", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "NG", - "originalString": "Nh4" - }, - { - "color": "b", - "fromIndex": 53, - "toIndex": 38, - "from": "f5", - "to": "g6", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "bc", - "originalString": "Bg6" - }, - { - "color": "w", - "fromIndex": 71, - "toIndex": 38, - "from": "h4", - "to": "g6", - "flags": "c", - "piece": "n", - "unambiguousSymbol": "NG", - "originalString": "Nxg6", - "capture": { "type": "b", "unambiguousSymbol": "bc" } - }, - { - "color": "b", - "fromIndex": 23, - "toIndex": 38, - "from": "h7", - "to": "g6", - "flags": "c", - "piece": "p", - "unambiguousSymbol": "ph", - "originalString": "hxg6", - "capture": { "type": "n", "unambiguousSymbol": "NG" } - }, - { - "color": "w", - "fromIndex": 113, - "toIndex": 99, - "from": "b1", - "to": "d2", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "NB", - "originalString": "Nd2" - }, - { - "color": "b", - "fromIndex": 20, - "toIndex": 36, - "from": "e7", - "to": "e6", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "pe", - "originalString": "e6" - }, - { - "color": "w", - "fromIndex": 117, - "toIndex": 83, - "from": "f1", - "to": "d3", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "BF", - "originalString": "Bd3" - }, - { - "color": "b", - "fromIndex": 5, - "toIndex": 35, - "from": "f8", - "to": "d6", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "bf", - "originalString": "Bd6" - }, - { - "color": "w", - "fromIndex": 84, - "toIndex": 68, - "from": "e3", - "to": "e4", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PE", - "originalString": "e4" - }, - { - "color": "b", - "fromIndex": 51, - "toIndex": 68, - "from": "d5", - "to": "e4", - "flags": "c", - "piece": "p", - "unambiguousSymbol": "pd", - "originalString": "dxe4", - "capture": { "type": "p", "unambiguousSymbol": "PE" } - }, - { - "color": "w", - "fromIndex": 99, - "toIndex": 68, - "from": "d2", - "to": "e4", - "flags": "c", - "piece": "n", - "unambiguousSymbol": "NB", - "originalString": "Nxe4", - "capture": { "type": "p", "unambiguousSymbol": "pd" } - }, - { - "color": "b", - "fromIndex": 7, - "toIndex": 103, - "from": "h8", - "to": "h2", - "flags": "c", - "piece": "r", - "unambiguousSymbol": "rh", - "originalString": "Rxh2", - "capture": { "type": "p", "unambiguousSymbol": "PH" } - }, - { - "color": "w", - "fromIndex": 116, - "toIndex": 100, - "from": "e1", - "to": "e2", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Ke2" - }, - { - "color": "b", - "fromIndex": 103, - "toIndex": 119, - "from": "h2", - "to": "h1", - "flags": "c", - "piece": "r", - "unambiguousSymbol": "rh", - "originalString": "Rxh1", - "capture": { "type": "r", "unambiguousSymbol": "RH" } - }, - { - "color": "w", - "fromIndex": 115, - "toIndex": 119, - "from": "d1", - "to": "h1", - "flags": "c", - "piece": "q", - "unambiguousSymbol": "Q", - "originalString": "Qxh1", - "capture": { "type": "r", "unambiguousSymbol": "rh" } - }, - { - "color": "b", - "fromIndex": 1, - "toIndex": 34, - "from": "b8", - "to": "c6", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "nb", - "originalString": "Nc6" - }, - { - "color": "w", - "fromIndex": 114, - "toIndex": 54, - "from": "c1", - "to": "g5", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "BC", - "originalString": "Bg5" - }, - { - "color": "b", - "fromIndex": 4, - "toIndex": 20, - "from": "e8", - "to": "e7", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "k", - "originalString": "Ke7" - }, - { - "color": "w", - "fromIndex": 119, - "toIndex": 23, - "from": "h1", - "to": "h7", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "Q", - "originalString": "Qh7" - }, - { - "color": "b", - "fromIndex": 34, - "toIndex": 67, - "from": "c6", - "to": "d4", - "flags": "c", - "piece": "n", - "unambiguousSymbol": "nb", - "originalString": "Nxd4+", - "capture": { "type": "p", "unambiguousSymbol": "PD" } - }, - { - "color": "w", - "fromIndex": 100, - "toIndex": 99, - "from": "e2", - "to": "d2", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Kd2" - }, - { - "color": "b", - "fromIndex": 3, - "toIndex": 4, - "from": "d8", - "to": "e8", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "q", - "originalString": "Qe8" - }, - { - "color": "w", - "fromIndex": 23, - "toIndex": 22, - "from": "h7", - "to": "g7", - "flags": "c", - "piece": "q", - "unambiguousSymbol": "Q", - "originalString": "Qxg7", - "capture": { "type": "p", "unambiguousSymbol": "pg" } - }, - { - "color": "b", - "fromIndex": 4, - "toIndex": 7, - "from": "e8", - "to": "h8", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "q", - "originalString": "Qh8" - }, - { - "color": "w", - "fromIndex": 54, - "toIndex": 37, - "from": "g5", - "to": "f6", - "flags": "c", - "piece": "b", - "unambiguousSymbol": "BC", - "originalString": "Bxf6+", - "capture": { "type": "n", "unambiguousSymbol": "ng" } - }, - { - "color": "b", - "fromIndex": 20, - "toIndex": 19, - "from": "e7", - "to": "d7", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "k", - "originalString": "Kd7" - }, - { - "color": "w", - "fromIndex": 22, - "toIndex": 7, - "from": "g7", - "to": "h8", - "flags": "c", - "piece": "q", - "unambiguousSymbol": "Q", - "originalString": "Qxh8", - "capture": { "type": "q", "unambiguousSymbol": "q" } - }, - { - "color": "b", - "fromIndex": 0, - "toIndex": 7, - "from": "a8", - "to": "h8", - "flags": "c", - "piece": "r", - "unambiguousSymbol": "ra", - "originalString": "Rxh8", - "capture": { "type": "q", "unambiguousSymbol": "Q" } - }, - { - "color": "w", - "fromIndex": 37, - "toIndex": 7, - "from": "f6", - "to": "h8", - "flags": "c", - "piece": "b", - "unambiguousSymbol": "BC", - "originalString": "Bxh8", - "capture": { "type": "r", "unambiguousSymbol": "ra" } - } - ], - [ - { - "color": "w", - "fromIndex": 100, - "toIndex": 68, - "from": "e2", - "to": "e4", - "flags": "b", - "piece": "p", - "unambiguousSymbol": "PE", - "originalString": "e4" - }, - { - "color": "b", - "fromIndex": 20, - "toIndex": 52, - "from": "e7", - "to": "e5", - "flags": "b", - "piece": "p", - "unambiguousSymbol": "pe", - "originalString": "e5" - }, - { - "color": "w", - "fromIndex": 118, - "toIndex": 85, - "from": "g1", - "to": "f3", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "NG", - "originalString": "Nf3" - }, - { - "color": "b", - "fromIndex": 1, - "toIndex": 34, - "from": "b8", - "to": "c6", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "nb", - "originalString": "Nc6" - }, - { - "color": "w", - "fromIndex": 117, - "toIndex": 66, - "from": "f1", - "to": "c4", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "BF", - "originalString": "Bc4" - }, - { - "color": "b", - "fromIndex": 6, - "toIndex": 37, - "from": "g8", - "to": "f6", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "ng", - "originalString": "Nf6" - }, - { - "color": "w", - "fromIndex": 113, - "toIndex": 82, - "from": "b1", - "to": "c3", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "NB", - "originalString": "Nc3" - }, - { - "color": "b", - "fromIndex": 5, - "toIndex": 50, - "from": "f8", - "to": "c5", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "bf", - "originalString": "Bc5" - }, - { - "color": "w", - "fromIndex": 96, - "toIndex": 80, - "from": "a2", - "to": "a3", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PA", - "originalString": "a3" - }, - { - "color": "b", - "fromIndex": 50, - "toIndex": 101, - "from": "c5", - "to": "f2", - "flags": "c", - "piece": "b", - "unambiguousSymbol": "bf", - "originalString": "Bxf2+", - "capture": { "type": "p", "unambiguousSymbol": "PF" } - }, - { - "color": "w", - "fromIndex": 116, - "toIndex": 101, - "from": "e1", - "to": "f2", - "flags": "c", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Kxf2", - "capture": { "type": "b", "unambiguousSymbol": "bf" } - }, - { - "color": "b", - "fromIndex": 34, - "toIndex": 67, - "from": "c6", - "to": "d4", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "nb", - "originalString": "Nd4" - }, - { - "color": "w", - "fromIndex": 99, - "toIndex": 83, - "from": "d2", - "to": "d3", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PD", - "originalString": "d3" - }, - { - "color": "b", - "fromIndex": 37, - "toIndex": 70, - "from": "f6", - "to": "g4", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "ng", - "originalString": "Ng4+" - }, - { - "color": "w", - "fromIndex": 101, - "toIndex": 117, - "from": "f2", - "to": "f1", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Kf1" - }, - { - "color": "b", - "fromIndex": 3, - "toIndex": 37, - "from": "d8", - "to": "f6", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "q", - "originalString": "Qf6" - }, - { - "color": "w", - "fromIndex": 103, - "toIndex": 87, - "from": "h2", - "to": "h3", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PH", - "originalString": "h3" - }, - { - "color": "b", - "fromIndex": 19, - "toIndex": 51, - "from": "d7", - "to": "d5", - "flags": "b", - "piece": "p", - "unambiguousSymbol": "pd", - "originalString": "d5" - }, - { - "color": "w", - "fromIndex": 82, - "toIndex": 51, - "from": "c3", - "to": "d5", - "flags": "c", - "piece": "n", - "unambiguousSymbol": "NB", - "originalString": "Nxd5", - "capture": { "type": "p", "unambiguousSymbol": "pd" } - }, - { - "color": "b", - "fromIndex": 37, - "toIndex": 36, - "from": "f6", - "to": "e6", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "q", - "originalString": "Qe6" - }, - { - "color": "w", - "fromIndex": 51, - "toIndex": 18, - "from": "d5", - "to": "c7", - "flags": "c", - "piece": "n", - "unambiguousSymbol": "NB", - "originalString": "Nxc7+", - "capture": { "type": "p", "unambiguousSymbol": "pc" } - } - ], - [ - { - "color": "w", - "fromIndex": 100, - "toIndex": 68, - "from": "e2", - "to": "e4", - "flags": "b", - "piece": "p", - "unambiguousSymbol": "PE", - "originalString": "e4" - }, - { - "color": "b", - "fromIndex": 18, - "toIndex": 34, - "from": "c7", - "to": "c6", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "pc", - "originalString": "c6" - }, - { - "color": "w", - "fromIndex": 113, - "toIndex": 82, - "from": "b1", - "to": "c3", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "NB", - "originalString": "Nc3" - }, - { - "color": "b", - "fromIndex": 19, - "toIndex": 51, - "from": "d7", - "to": "d5", - "flags": "b", - "piece": "p", - "unambiguousSymbol": "pd", - "originalString": "d5" - }, - { - "color": "w", - "fromIndex": 115, - "toIndex": 85, - "from": "d1", - "to": "f3", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "Q", - "originalString": "Qf3" - }, - { - "color": "b", - "fromIndex": 51, - "toIndex": 68, - "from": "d5", - "to": "e4", - "flags": "c", - "piece": "p", - "unambiguousSymbol": "pd", - "originalString": "dxe4", - "capture": { "type": "p", "unambiguousSymbol": "PE" } - }, - { - "color": "w", - "fromIndex": 82, - "toIndex": 68, - "from": "c3", - "to": "e4", - "flags": "c", - "piece": "n", - "unambiguousSymbol": "NB", - "originalString": "Nxe4", - "capture": { "type": "p", "unambiguousSymbol": "pd" } - }, - { - "color": "b", - "fromIndex": 1, - "toIndex": 19, - "from": "b8", - "to": "d7", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "nb", - "originalString": "Nd7" - }, - { - "color": "w", - "fromIndex": 117, - "toIndex": 66, - "from": "f1", - "to": "c4", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "BF", - "originalString": "Bc4" - }, - { - "color": "b", - "fromIndex": 6, - "toIndex": 37, - "from": "g8", - "to": "f6", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "ng", - "originalString": "Ngf6" - }, - { - "color": "w", - "fromIndex": 68, - "toIndex": 37, - "from": "e4", - "to": "f6", - "flags": "c", - "piece": "n", - "unambiguousSymbol": "NB", - "originalString": "Nxf6+", - "capture": { "type": "n", "unambiguousSymbol": "ng" } - }, - { - "color": "b", - "fromIndex": 19, - "toIndex": 37, - "from": "d7", - "to": "f6", - "flags": "c", - "piece": "n", - "unambiguousSymbol": "nb", - "originalString": "Nxf6", - "capture": { "type": "n", "unambiguousSymbol": "NB" } - }, - { - "color": "w", - "fromIndex": 85, - "toIndex": 86, - "from": "f3", - "to": "g3", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "Q", - "originalString": "Qg3" - }, - { - "color": "b", - "fromIndex": 2, - "toIndex": 53, - "from": "c8", - "to": "f5", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "bc", - "originalString": "Bf5" - }, - { - "color": "w", - "fromIndex": 99, - "toIndex": 83, - "from": "d2", - "to": "d3", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PD", - "originalString": "d3" - }, - { - "color": "b", - "fromIndex": 53, - "toIndex": 38, - "from": "f5", - "to": "g6", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "bc", - "originalString": "Bg6" - }, - { - "color": "w", - "fromIndex": 118, - "toIndex": 100, - "from": "g1", - "to": "e2", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "NG", - "originalString": "Ne2" - }, - { - "color": "b", - "fromIndex": 20, - "toIndex": 36, - "from": "e7", - "to": "e6", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "pe", - "originalString": "e6" - }, - { - "color": "w", - "fromIndex": 114, - "toIndex": 69, - "from": "c1", - "to": "f4", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "BC", - "originalString": "Bf4" - }, - { - "color": "b", - "fromIndex": 37, - "toIndex": 55, - "from": "f6", - "to": "h5", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "nb", - "originalString": "Nh5" - }, - { - "color": "w", - "fromIndex": 86, - "toIndex": 85, - "from": "g3", - "to": "f3", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "Q", - "originalString": "Qf3" - }, - { - "color": "b", - "fromIndex": 55, - "toIndex": 69, - "from": "h5", - "to": "f4", - "flags": "c", - "piece": "n", - "unambiguousSymbol": "nb", - "originalString": "Nxf4", - "capture": { "type": "b", "unambiguousSymbol": "BC" } - }, - { - "color": "w", - "fromIndex": 100, - "toIndex": 69, - "from": "e2", - "to": "f4", - "flags": "c", - "piece": "n", - "unambiguousSymbol": "NG", - "originalString": "Nxf4", - "capture": { "type": "n", "unambiguousSymbol": "nb" } - }, - { - "color": "b", - "fromIndex": 5, - "toIndex": 20, - "from": "f8", - "to": "e7", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "bf", - "originalString": "Be7" - }, - { - "color": "w", - "fromIndex": 66, - "toIndex": 36, - "from": "c4", - "to": "e6", - "flags": "c", - "piece": "b", - "unambiguousSymbol": "BF", - "originalString": "Bxe6", - "capture": { "type": "p", "unambiguousSymbol": "pe" } - }, - { - "color": "b", - "fromIndex": 21, - "toIndex": 36, - "from": "f7", - "to": "e6", - "flags": "c", - "piece": "p", - "unambiguousSymbol": "pf", - "originalString": "fxe6", - "capture": { "type": "b", "unambiguousSymbol": "BF" } - }, - { - "color": "w", - "fromIndex": 69, - "toIndex": 36, - "from": "f4", - "to": "e6", - "flags": "c", - "piece": "n", - "unambiguousSymbol": "NG", - "originalString": "Nxe6", - "capture": { "type": "p", "unambiguousSymbol": "pf" } - }, - { - "color": "b", - "fromIndex": 3, - "toIndex": 48, - "from": "d8", - "to": "a5", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "q", - "originalString": "Qa5+" - }, - { - "color": "w", - "fromIndex": 98, - "toIndex": 82, - "from": "c2", - "to": "c3", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PC", - "originalString": "c3" - }, - { - "color": "b", - "fromIndex": 48, - "toIndex": 52, - "from": "a5", - "to": "e5", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "q", - "originalString": "Qe5+" - }, - { - "color": "w", - "fromIndex": 85, - "toIndex": 84, - "from": "f3", - "to": "e3", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "Q", - "originalString": "Qe3" - }, - { - "color": "b", - "fromIndex": 52, - "toIndex": 84, - "from": "e5", - "to": "e3", - "flags": "c", - "piece": "q", - "unambiguousSymbol": "q", - "originalString": "Qxe3+", - "capture": { "type": "q", "unambiguousSymbol": "Q" } - }, - { - "color": "w", - "fromIndex": 101, - "toIndex": 84, - "from": "f2", - "to": "e3", - "flags": "c", - "piece": "p", - "unambiguousSymbol": "PF", - "originalString": "fxe3", - "capture": { "type": "q", "unambiguousSymbol": "q" } - }, - { - "color": "b", - "fromIndex": 4, - "toIndex": 19, - "from": "e8", - "to": "d7", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "k", - "originalString": "Kd7" - }, - { - "color": "w", - "fromIndex": 36, - "toIndex": 69, - "from": "e6", - "to": "f4", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "NG", - "originalString": "Nf4" - }, - { - "color": "b", - "fromIndex": 20, - "toIndex": 35, - "from": "e7", - "to": "d6", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "bf", - "originalString": "Bd6" - }, - { - "color": "w", - "fromIndex": 69, - "toIndex": 38, - "from": "f4", - "to": "g6", - "flags": "c", - "piece": "n", - "unambiguousSymbol": "NG", - "originalString": "Nxg6", - "capture": { "type": "b", "unambiguousSymbol": "bc" } - }, - { - "color": "b", - "fromIndex": 23, - "toIndex": 38, - "from": "h7", - "to": "g6", - "flags": "c", - "piece": "p", - "unambiguousSymbol": "ph", - "originalString": "hxg6", - "capture": { "type": "n", "unambiguousSymbol": "NG" } - }, - { - "color": "w", - "fromIndex": 103, - "toIndex": 87, - "from": "h2", - "to": "h3", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PH", - "originalString": "h3" - }, - { - "color": "b", - "fromIndex": 35, - "toIndex": 86, - "from": "d6", - "to": "g3", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "bf", - "originalString": "Bg3+" - }, - { - "color": "w", - "fromIndex": 116, - "toIndex": 99, - "from": "e1", - "to": "d2", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Kd2" - }, - { - "color": "b", - "fromIndex": 0, - "toIndex": 5, - "from": "a8", - "to": "f8", - "flags": "n", - "piece": "r", - "unambiguousSymbol": "ra", - "originalString": "Raf8" - }, - { - "color": "w", - "fromIndex": 119, - "toIndex": 117, - "from": "h1", - "to": "f1", - "flags": "n", - "piece": "r", - "unambiguousSymbol": "RH", - "originalString": "Rhf1" - }, - { - "color": "b", - "fromIndex": 19, - "toIndex": 20, - "from": "d7", - "to": "e7", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "k", - "originalString": "Ke7" - }, - { - "color": "w", - "fromIndex": 83, - "toIndex": 67, - "from": "d3", - "to": "d4", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PD", - "originalString": "d4" - }, - { - "color": "b", - "fromIndex": 5, - "toIndex": 117, - "from": "f8", - "to": "f1", - "flags": "c", - "piece": "r", - "unambiguousSymbol": "ra", - "originalString": "Rxf1", - "capture": { "type": "r", "unambiguousSymbol": "RH" } - }, - { - "color": "w", - "fromIndex": 112, - "toIndex": 117, - "from": "a1", - "to": "f1", - "flags": "c", - "piece": "r", - "unambiguousSymbol": "RA", - "originalString": "Rxf1", - "capture": { "type": "r", "unambiguousSymbol": "ra" } - }, - { - "color": "b", - "fromIndex": 7, - "toIndex": 5, - "from": "h8", - "to": "f8", - "flags": "n", - "piece": "r", - "unambiguousSymbol": "rh", - "originalString": "Rf8" - }, - { - "color": "w", - "fromIndex": 117, - "toIndex": 5, - "from": "f1", - "to": "f8", - "flags": "c", - "piece": "r", - "unambiguousSymbol": "RA", - "originalString": "Rxf8", - "capture": { "type": "r", "unambiguousSymbol": "rh" } - }, - { - "color": "b", - "fromIndex": 20, - "toIndex": 5, - "from": "e7", - "to": "f8", - "flags": "c", - "piece": "k", - "unambiguousSymbol": "k", - "originalString": "Kxf8", - "capture": { "type": "r", "unambiguousSymbol": "RA" } - }, - { - "color": "w", - "fromIndex": 84, - "toIndex": 68, - "from": "e3", - "to": "e4", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PF", - "originalString": "e4" - }, - { - "color": "b", - "fromIndex": 5, - "toIndex": 20, - "from": "f8", - "to": "e7", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "k", - "originalString": "Ke7" - }, - { - "color": "w", - "fromIndex": 99, - "toIndex": 84, - "from": "d2", - "to": "e3", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Ke3" - }, - { - "color": "b", - "fromIndex": 38, - "toIndex": 54, - "from": "g6", - "to": "g5", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "ph", - "originalString": "g5" - }, - { - "color": "w", - "fromIndex": 84, - "toIndex": 85, - "from": "e3", - "to": "f3", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Kf3" - }, - { - "color": "b", - "fromIndex": 86, - "toIndex": 116, - "from": "g3", - "to": "e1", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "bf", - "originalString": "Be1" - }, - { - "color": "w", - "fromIndex": 85, - "toIndex": 70, - "from": "f3", - "to": "g4", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Kg4" - }, - { - "color": "b", - "fromIndex": 116, - "toIndex": 99, - "from": "e1", - "to": "d2", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "bf", - "originalString": "Bd2" - }, - { - "color": "w", - "fromIndex": 70, - "toIndex": 53, - "from": "g4", - "to": "f5", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Kf5" - }, - { - "color": "b", - "fromIndex": 99, - "toIndex": 114, - "from": "d2", - "to": "c1", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "bf", - "originalString": "Bc1" - }, - { - "color": "w", - "fromIndex": 53, - "toIndex": 38, - "from": "f5", - "to": "g6", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Kg6" - }, - { - "color": "b", - "fromIndex": 20, - "toIndex": 5, - "from": "e7", - "to": "f8", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "k", - "originalString": "Kf8" - }, - { - "color": "w", - "fromIndex": 68, - "toIndex": 52, - "from": "e4", - "to": "e5", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PF", - "originalString": "e5" - }, - { - "color": "b", - "fromIndex": 114, - "toIndex": 97, - "from": "c1", - "to": "b2", - "flags": "c", - "piece": "b", - "unambiguousSymbol": "bf", - "originalString": "Bxb2", - "capture": { "type": "p", "unambiguousSymbol": "PB" } - }, - { - "color": "w", - "fromIndex": 38, - "toIndex": 54, - "from": "g6", - "to": "g5", - "flags": "c", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Kxg5", - "capture": { "type": "p", "unambiguousSymbol": "ph" } - }, - { - "color": "b", - "fromIndex": 97, - "toIndex": 82, - "from": "b2", - "to": "c3", - "flags": "c", - "piece": "b", - "unambiguousSymbol": "bf", - "originalString": "Bxc3", - "capture": { "type": "p", "unambiguousSymbol": "PC" } - }, - { - "color": "w", - "fromIndex": 87, - "toIndex": 71, - "from": "h3", - "to": "h4", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PH", - "originalString": "h4" - }, - { - "color": "b", - "fromIndex": 82, - "toIndex": 67, - "from": "c3", - "to": "d4", - "flags": "c", - "piece": "b", - "unambiguousSymbol": "bf", - "originalString": "Bxd4", - "capture": { "type": "p", "unambiguousSymbol": "PD" } - }, - { - "color": "w", - "fromIndex": 71, - "toIndex": 55, - "from": "h4", - "to": "h5", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PH", - "originalString": "h5" - }, - { - "color": "b", - "fromIndex": 67, - "toIndex": 52, - "from": "d4", - "to": "e5", - "flags": "c", - "piece": "b", - "unambiguousSymbol": "bf", - "originalString": "Bxe5", - "capture": { "type": "p", "unambiguousSymbol": "PF" } - }, - { - "color": "w", - "fromIndex": 102, - "toIndex": 70, - "from": "g2", - "to": "g4", - "flags": "b", - "piece": "p", - "unambiguousSymbol": "PG", - "originalString": "g4" - }, - { - "color": "b", - "fromIndex": 52, - "toIndex": 97, - "from": "e5", - "to": "b2", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "bf", - "originalString": "Bb2" - }, - { - "color": "w", - "fromIndex": 54, - "toIndex": 53, - "from": "g5", - "to": "f5", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Kf5" - }, - { - "color": "b", - "fromIndex": 5, - "toIndex": 21, - "from": "f8", - "to": "f7", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "k", - "originalString": "Kf7" - }, - { - "color": "w", - "fromIndex": 70, - "toIndex": 54, - "from": "g4", - "to": "g5", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PG", - "originalString": "g5" - }, - { - "color": "b", - "fromIndex": 97, - "toIndex": 114, - "from": "b2", - "to": "c1", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "bf", - "originalString": "Bc1" - }, - { - "color": "w", - "fromIndex": 54, - "toIndex": 38, - "from": "g5", - "to": "g6", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PG", - "originalString": "g6+" - }, - { - "color": "b", - "fromIndex": 21, - "toIndex": 20, - "from": "f7", - "to": "e7", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "k", - "originalString": "Ke7" - }, - { - "color": "w", - "fromIndex": 53, - "toIndex": 52, - "from": "f5", - "to": "e5", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Ke5" - }, - { - "color": "b", - "fromIndex": 17, - "toIndex": 49, - "from": "b7", - "to": "b5", - "flags": "b", - "piece": "p", - "unambiguousSymbol": "pb", - "originalString": "b5" - }, - { - "color": "w", - "fromIndex": 52, - "toIndex": 67, - "from": "e5", - "to": "d4", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Kd4" - }, - { - "color": "b", - "fromIndex": 20, - "toIndex": 35, - "from": "e7", - "to": "d6", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "k", - "originalString": "Kd6" - }, - { - "color": "w", - "fromIndex": 67, - "toIndex": 82, - "from": "d4", - "to": "c3", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Kc3" - }, - { - "color": "b", - "fromIndex": 34, - "toIndex": 50, - "from": "c6", - "to": "c5", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "pc", - "originalString": "c5" - }, - { - "color": "w", - "fromIndex": 96, - "toIndex": 80, - "from": "a2", - "to": "a3", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PA", - "originalString": "a3" - }, - { - "color": "b", - "fromIndex": 114, - "toIndex": 54, - "from": "c1", - "to": "g5", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "bf", - "originalString": "Bg5" - }, - { - "color": "w", - "fromIndex": 80, - "toIndex": 64, - "from": "a3", - "to": "a4", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PA", - "originalString": "a4" - }, - { - "color": "b", - "fromIndex": 49, - "toIndex": 64, - "from": "b5", - "to": "a4", - "flags": "c", - "piece": "p", - "unambiguousSymbol": "pb", - "originalString": "bxa4", - "capture": { "type": "p", "unambiguousSymbol": "PA" } - }, - { - "color": "w", - "fromIndex": 82, - "toIndex": 97, - "from": "c3", - "to": "b2", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Kb2" - }, - { - "color": "b", - "fromIndex": 35, - "toIndex": 51, - "from": "d6", - "to": "d5", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "k", - "originalString": "Kd5" - }, - { - "color": "w", - "fromIndex": 97, - "toIndex": 80, - "from": "b2", - "to": "a3", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Ka3" - }, - { - "color": "b", - "fromIndex": 51, - "toIndex": 67, - "from": "d5", - "to": "d4", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "k", - "originalString": "Kd4" - }, - { - "color": "w", - "fromIndex": 80, - "toIndex": 64, - "from": "a3", - "to": "a4", - "flags": "c", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Kxa4", - "capture": { "type": "p", "unambiguousSymbol": "pb" } - }, - { - "color": "b", - "fromIndex": 50, - "toIndex": 66, - "from": "c5", - "to": "c4", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "pc", - "originalString": "c4" - } - ], - [ - { - "color": "w", - "fromIndex": 100, - "toIndex": 68, - "from": "e2", - "to": "e4", - "flags": "b", - "piece": "p", - "unambiguousSymbol": "PE", - "originalString": "e4" - }, - { - "color": "b", - "fromIndex": 20, - "toIndex": 36, - "from": "e7", - "to": "e6", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "pe", - "originalString": "e6" - }, - { - "color": "w", - "fromIndex": 117, - "toIndex": 66, - "from": "f1", - "to": "c4", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "BF", - "originalString": "Bc4" - }, - { - "color": "b", - "fromIndex": 19, - "toIndex": 51, - "from": "d7", - "to": "d5", - "flags": "b", - "piece": "p", - "unambiguousSymbol": "pd", - "originalString": "d5" - }, - { - "color": "w", - "fromIndex": 68, - "toIndex": 51, - "from": "e4", - "to": "d5", - "flags": "c", - "piece": "p", - "unambiguousSymbol": "PE", - "originalString": "exd5", - "capture": { "type": "p", "unambiguousSymbol": "pd" } - }, - { - "color": "b", - "fromIndex": 36, - "toIndex": 51, - "from": "e6", - "to": "d5", - "flags": "c", - "piece": "p", - "unambiguousSymbol": "pe", - "originalString": "exd5", - "capture": { "type": "p", "unambiguousSymbol": "PE" } - }, - { - "color": "w", - "fromIndex": 66, - "toIndex": 81, - "from": "c4", - "to": "b3", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "BF", - "originalString": "Bb3" - }, - { - "color": "b", - "fromIndex": 6, - "toIndex": 37, - "from": "g8", - "to": "f6", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "ng", - "originalString": "Nf6" - }, - { - "color": "w", - "fromIndex": 99, - "toIndex": 67, - "from": "d2", - "to": "d4", - "flags": "b", - "piece": "p", - "unambiguousSymbol": "PD", - "originalString": "d4" - }, - { - "color": "b", - "fromIndex": 5, - "toIndex": 20, - "from": "f8", - "to": "e7", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "bf", - "originalString": "Be7" - }, - { - "color": "w", - "fromIndex": 118, - "toIndex": 85, - "from": "g1", - "to": "f3", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "NG", - "originalString": "Nf3" - }, - { - "color": "b", - "fromIndex": 4, - "toIndex": 6, - "from": "e8", - "to": "g8", - "flags": "k", - "piece": "k", - "unambiguousSymbol": "k", - "originalString": "O-O" - }, - { - "color": "w", - "fromIndex": 114, - "toIndex": 54, - "from": "c1", - "to": "g5", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "BC", - "originalString": "Bg5" - }, - { - "color": "b", - "fromIndex": 23, - "toIndex": 39, - "from": "h7", - "to": "h6", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "ph", - "originalString": "h6" - }, - { - "color": "w", - "fromIndex": 54, - "toIndex": 37, - "from": "g5", - "to": "f6", - "flags": "c", - "piece": "b", - "unambiguousSymbol": "BC", - "originalString": "Bxf6", - "capture": { "type": "n", "unambiguousSymbol": "ng" } - }, - { - "color": "b", - "fromIndex": 20, - "toIndex": 37, - "from": "e7", - "to": "f6", - "flags": "c", - "piece": "b", - "unambiguousSymbol": "bf", - "originalString": "Bxf6", - "capture": { "type": "b", "unambiguousSymbol": "BC" } - }, - { - "color": "w", - "fromIndex": 116, - "toIndex": 118, - "from": "e1", - "to": "g1", - "flags": "k", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "O-O" - }, - { - "color": "b", - "fromIndex": 18, - "toIndex": 34, - "from": "c7", - "to": "c6", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "pc", - "originalString": "c6" - }, - { - "color": "w", - "fromIndex": 117, - "toIndex": 116, - "from": "f1", - "to": "e1", - "flags": "n", - "piece": "r", - "unambiguousSymbol": "RH", - "originalString": "Re1" - }, - { - "color": "b", - "fromIndex": 2, - "toIndex": 53, - "from": "c8", - "to": "f5", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "bc", - "originalString": "Bf5" - }, - { - "color": "w", - "fromIndex": 98, - "toIndex": 66, - "from": "c2", - "to": "c4", - "flags": "b", - "piece": "p", - "unambiguousSymbol": "PC", - "originalString": "c4?!" - }, - { - "color": "b", - "fromIndex": 51, - "toIndex": 66, - "from": "d5", - "to": "c4", - "flags": "c", - "piece": "p", - "unambiguousSymbol": "pe", - "originalString": "dxc4", - "capture": { "type": "p", "unambiguousSymbol": "PC" } - }, - { - "color": "w", - "fromIndex": 81, - "toIndex": 66, - "from": "b3", - "to": "c4", - "flags": "c", - "piece": "b", - "unambiguousSymbol": "BF", - "originalString": "Bxc4", - "capture": { "type": "p", "unambiguousSymbol": "pe" } - }, - { - "color": "b", - "fromIndex": 1, - "toIndex": 19, - "from": "b8", - "to": "d7", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "nb", - "originalString": "Nd7?!" - }, - { - "color": "w", - "fromIndex": 113, - "toIndex": 82, - "from": "b1", - "to": "c3", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "NB", - "originalString": "Nc3" - }, - { - "color": "b", - "fromIndex": 19, - "toIndex": 33, - "from": "d7", - "to": "b6", - "flags": "n", - "piece": "n", - "unambiguousSymbol": "nb", - "originalString": "Nb6" - }, - { - "color": "w", - "fromIndex": 97, - "toIndex": 81, - "from": "b2", - "to": "b3", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PB", - "originalString": "b3?!" - }, - { - "color": "b", - "fromIndex": 33, - "toIndex": 66, - "from": "b6", - "to": "c4", - "flags": "c", - "piece": "n", - "unambiguousSymbol": "nb", - "originalString": "Nxc4", - "capture": { "type": "b", "unambiguousSymbol": "BF" } - }, - { - "color": "w", - "fromIndex": 81, - "toIndex": 66, - "from": "b3", - "to": "c4", - "flags": "c", - "piece": "p", - "unambiguousSymbol": "PB", - "originalString": "bxc4", - "capture": { "type": "n", "unambiguousSymbol": "nb" } - }, - { - "color": "b", - "fromIndex": 3, - "toIndex": 48, - "from": "d8", - "to": "a5", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "q", - "originalString": "Qa5" - }, - { - "color": "w", - "fromIndex": 112, - "toIndex": 114, - "from": "a1", - "to": "c1", - "flags": "n", - "piece": "r", - "unambiguousSymbol": "RA", - "originalString": "Rc1" - }, - { - "color": "b", - "fromIndex": 0, - "toIndex": 3, - "from": "a8", - "to": "d8", - "flags": "n", - "piece": "r", - "unambiguousSymbol": "ra", - "originalString": "Rad8" - }, - { - "color": "w", - "fromIndex": 67, - "toIndex": 51, - "from": "d4", - "to": "d5", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PD", - "originalString": "d5??" - }, - { - "color": "b", - "fromIndex": 37, - "toIndex": 82, - "from": "f6", - "to": "c3", - "flags": "c", - "piece": "b", - "unambiguousSymbol": "bf", - "originalString": "Bxc3", - "capture": { "type": "n", "unambiguousSymbol": "NB" } - }, - { - "color": "w", - "fromIndex": 116, - "toIndex": 52, - "from": "e1", - "to": "e5", - "flags": "n", - "piece": "r", - "unambiguousSymbol": "RH", - "originalString": "Re5?" - }, - { - "color": "b", - "fromIndex": 82, - "toIndex": 52, - "from": "c3", - "to": "e5", - "flags": "c", - "piece": "b", - "unambiguousSymbol": "bf", - "originalString": "Bxe5", - "capture": { "type": "r", "unambiguousSymbol": "RH" } - }, - { - "color": "w", - "fromIndex": 85, - "toIndex": 52, - "from": "f3", - "to": "e5", - "flags": "c", - "piece": "n", - "unambiguousSymbol": "NG", - "originalString": "Nxe5", - "capture": { "type": "b", "unambiguousSymbol": "bf" } - }, - { - "color": "b", - "fromIndex": 34, - "toIndex": 51, - "from": "c6", - "to": "d5", - "flags": "c", - "piece": "p", - "unambiguousSymbol": "pc", - "originalString": "cxd5", - "capture": { "type": "p", "unambiguousSymbol": "PD" } - }, - { - "color": "w", - "fromIndex": 115, - "toIndex": 116, - "from": "d1", - "to": "e1", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "Q", - "originalString": "Qe1?" - }, - { - "color": "b", - "fromIndex": 53, - "toIndex": 36, - "from": "f5", - "to": "e6", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "bc", - "originalString": "Be6??" - }, - { - "color": "w", - "fromIndex": 114, - "toIndex": 115, - "from": "c1", - "to": "d1", - "flags": "n", - "piece": "r", - "unambiguousSymbol": "RA", - "originalString": "Rd1??" - }, - { - "color": "b", - "fromIndex": 51, - "toIndex": 66, - "from": "d5", - "to": "c4", - "flags": "c", - "piece": "p", - "unambiguousSymbol": "pc", - "originalString": "dxc4", - "capture": { "type": "p", "unambiguousSymbol": "PB" } - }, - { - "color": "w", - "fromIndex": 115, - "toIndex": 3, - "from": "d1", - "to": "d8", - "flags": "c", - "piece": "r", - "unambiguousSymbol": "RA", - "originalString": "Rxd8?!", - "capture": { "type": "r", "unambiguousSymbol": "ra" } - }, - { - "color": "b", - "fromIndex": 5, - "toIndex": 3, - "from": "f8", - "to": "d8", - "flags": "c", - "piece": "r", - "unambiguousSymbol": "rh", - "originalString": "Rxd8?!", - "capture": { "type": "r", "unambiguousSymbol": "RA" } - }, - { - "color": "w", - "fromIndex": 116, - "toIndex": 82, - "from": "e1", - "to": "c3", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "Q", - "originalString": "Qc3?!" - }, - { - "color": "b", - "fromIndex": 48, - "toIndex": 82, - "from": "a5", - "to": "c3", - "flags": "c", - "piece": "q", - "unambiguousSymbol": "q", - "originalString": "Qxc3?!", - "capture": { "type": "q", "unambiguousSymbol": "Q" } - }, - { - "color": "w", - "fromIndex": 102, - "toIndex": 86, - "from": "g2", - "to": "g3", - "flags": "n", - "piece": "p", - "unambiguousSymbol": "PG", - "originalString": "g3" - }, - { - "color": "b", - "fromIndex": 3, - "toIndex": 115, - "from": "d8", - "to": "d1", - "flags": "n", - "piece": "r", - "unambiguousSymbol": "rh", - "originalString": "Rd1+?!" - }, - { - "color": "w", - "fromIndex": 118, - "toIndex": 102, - "from": "g1", - "to": "g2", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Kg2" - }, - { - "color": "b", - "fromIndex": 82, - "toIndex": 116, - "from": "c3", - "to": "e1", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "q", - "originalString": "Qe1?!" - }, - { - "color": "w", - "fromIndex": 102, - "toIndex": 85, - "from": "g2", - "to": "f3", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Kf3" - }, - { - "color": "b", - "fromIndex": 116, - "toIndex": 52, - "from": "e1", - "to": "e5", - "flags": "c", - "piece": "q", - "unambiguousSymbol": "q", - "originalString": "Qxe5", - "capture": { "type": "n", "unambiguousSymbol": "NG" } - }, - { - "color": "w", - "fromIndex": 85, - "toIndex": 102, - "from": "f3", - "to": "g2", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Kg2" - }, - { - "color": "b", - "fromIndex": 36, - "toIndex": 51, - "from": "e6", - "to": "d5", - "flags": "n", - "piece": "b", - "unambiguousSymbol": "bc", - "originalString": "Bd5+?!" - }, - { - "color": "w", - "fromIndex": 102, - "toIndex": 87, - "from": "g2", - "to": "h3", - "flags": "n", - "piece": "k", - "unambiguousSymbol": "K", - "originalString": "Kh3" - }, - { - "color": "b", - "fromIndex": 52, - "toIndex": 55, - "from": "e5", - "to": "h5", - "flags": "n", - "piece": "q", - "unambiguousSymbol": "q", - "originalString": "Qh5#" - } - ] -] diff --git a/history.json b/history.json deleted file mode 100644 index a17b702..0000000 --- a/history.json +++ /dev/null @@ -1,199 +0,0 @@ -[ - { - "color": "w", - "from": "e2", - "to": "e4", - "flags": "b", - "piece": "p", - "originalString": "e4" - }, - { - "color": "b", - "from": "e7", - "to": "e5", - "flags": "b", - "piece": "p", - "originalString": "e5" - }, - { - "color": "w", - "from": "d2", - "to": "d4", - "flags": "b", - "piece": "p", - "originalString": "d4" - }, - { - "color": "b", - "captured": "p", - "from": "e5", - "to": "d4", - "flags": "c", - "piece": "p", - "originalString": "exd4" - }, - { - "color": "w", - "captured": "p", - "from": "d1", - "to": "d4", - "flags": "c", - "piece": "q", - "originalString": "Qxd4" - }, - { - "color": "b", - "from": "b8", - "to": "c6", - "flags": "n", - "piece": "n", - "originalString": "Nc6" - }, - { - "color": "w", - "from": "d4", - "to": "a4", - "flags": "n", - "piece": "q", - "originalString": "Qa4" - }, - { - "color": "b", - "from": "g8", - "to": "f6", - "flags": "n", - "piece": "n", - "originalString": "Nf6" - }, - { - "color": "w", - "from": "b1", - "to": "c3", - "flags": "n", - "piece": "n", - "originalString": "Nc3" - }, - { - "color": "b", - "from": "d7", - "to": "d5", - "flags": "b", - "piece": "p", - "originalString": "d5" - }, - { - "color": "w", - "captured": "p", - "from": "e4", - "to": "d5", - "flags": "c", - "piece": "p", - "originalString": "exd5" - }, - { - "color": "b", - "from": "d8", - "to": "e7", - "flags": "n", - "piece": "q", - "originalString": "Qe7+" - }, - { - "color": "w", - "from": "e1", - "to": "d1", - "flags": "n", - "piece": "k", - "originalString": "Kd1" - }, - { - "color": "b", - "from": "c8", - "to": "g4", - "flags": "n", - "piece": "b", - "originalString": "Bg4+" - }, - { - "color": "w", - "from": "d1", - "to": "d2", - "flags": "n", - "piece": "k", - "originalString": "Kd2" - }, - { - "color": "b", - "captured": "p", - "from": "f6", - "to": "d5", - "flags": "c", - "piece": "n", - "originalString": "Nxd5" - }, - { - "color": "w", - "from": "c3", - "to": "b5", - "flags": "n", - "piece": "n", - "originalString": "Nb5" - }, - { - "color": "b", - "from": "c6", - "to": "b4", - "flags": "n", - "piece": "n", - "originalString": "Ncb4" - }, - { - "color": "w", - "from": "c2", - "to": "c3", - "flags": "n", - "piece": "p", - "originalString": "c3" - }, - { - "color": "b", - "from": "e8", - "to": "c8", - "flags": "q", - "piece": "k", - "originalString": "O-O-O" - }, - { - "color": "w", - "from": "f2", - "to": "f3", - "flags": "n", - "piece": "p", - "originalString": "f3" - }, - { - "color": "b", - "from": "e7", - "to": "e3", - "flags": "n", - "piece": "q", - "originalString": "Qe3+" - }, - { - "color": "w", - "from": "d2", - "to": "d1", - "flags": "n", - "piece": "k", - "originalString": "Kd1" - }, - { - "color": "b", - "captured": "p", - "from": "d5", - "to": "c3", - "flags": "c", - "piece": "n", - "originalString": "Nxc3#" - } -] \ No newline at end of file diff --git a/src/gameHistory.ts b/src/gameHistory.ts deleted file mode 100644 index 85b7fad..0000000 --- a/src/gameHistory.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Chess } from '../cjsmin/src/chess'; -import { gameChunks } from './fileReader'; - -export async function* getHistoriesFromFilePath(path: string) { - const chess = new Chess(); - const gamesGenerator = gameChunks(path); - for await (const game of gamesGenerator) { - chess.loadPgn(game.moves); - yield chess.history(); - } -} diff --git a/src/index.ts b/src/index.ts index b4ef200..04e8d68 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,13 +1,12 @@ -import { Piece, PrettyMove } from '../cjsmin/src/chess'; +import { Chess } from '../cjsmin/src/chess'; import { gameChunks } from './fileReader'; -import { KDRatioMetric } from './metrics/captures'; +import { KDRatioMetric, MateAndAssistMetric } from './metrics/captures'; +import { MoveDistanceMetric } from './metrics/distances'; import { - getAverageDistance, - getMoveDistanceSetOfGames, -} from './metrics/distances'; -import { getGameWithMostMoves, getPieceLevelMoveInfo } from './metrics/moves'; -import { getPiecePromotionInfo } from './metrics/promotions'; -import { FileReaderGame } from './types'; + GameWithMostMovesMetric, + PieceLevelMoveInfoMetric, +} from './metrics/moves'; +import { PromotionMetric } from './metrics/promotions'; /** * @@ -16,53 +15,50 @@ import { FileReaderGame } from './types'; */ export async function main(path: string) { console.time('Total Execution Time'); - console.time('Task 1: FileReader'); + await gameIterator(path); + console.timeEnd('Total Execution Time'); +} +/** + * Metric functions will ingest a single game at a time + * @param metricFunctions + */ +async function gameIterator(path) { const gamesGenerator = gameChunks(path); - const games: FileReaderGame[] = []; + const kdRatioMetric = new KDRatioMetric(); + const killStreakMetric = new MoveDistanceMetric(); + const mateAndAssistMetric = new MateAndAssistMetric(); + const promotionMetric = new PromotionMetric(); + const moveDistanceMetric = new MoveDistanceMetric(); + const gameWithMostMovesMetric = new GameWithMostMovesMetric(); + const pieceLevelMoveInfoMetric = new PieceLevelMoveInfoMetric(); + const metrics = [ + kdRatioMetric, + killStreakMetric, + mateAndAssistMetric, + promotionMetric, + moveDistanceMetric, + gameWithMostMovesMetric, + pieceLevelMoveInfoMetric, + ]; + + const cjsmin = new Chess(); let gameCounter = 0; - for await (const game of gamesGenerator) { + for await (const { moves, metadata } of gamesGenerator) { gameCounter++; if (gameCounter % 20 == 0) { console.log('number of games ingested: ', gameCounter); } - games.push(game); - // const siteLink = game.metadata[1].match(/"(.*?)"/)[1]; - // console.log(`lichess link to game played: ${siteLink}`); + for (const metric of metrics) { + // with array creation + const historyGenerator = cjsmin.historyGeneratorArr(moves); + metric.processGame(Array.from(historyGenerator), metadata); + } } - console.timeEnd('Task 1: FileReader'); - - const { gameCount, totalDistanceMap } = await getMoveDistanceSetOfGames( - games - ); - - getAverageDistance(totalDistanceMap, gameCount); - getGameWithMostMoves(games); - getPieceLevelMoveInfo(games); - getPiecePromotionInfo(games); - - console.log(`Total number of games analyzed: ${gameCount}`); - console.log('\n'); - - console.log('=============================================================='); - console.log('\n'); - - console.timeEnd('Total Execution Time'); - console.log('\n'); -} - -/** - * Metric functions will ingest a single game at a time - * @param metricFunctions - */ -function gameIterator( - metricFunctions: ((game: { move: PrettyMove; board: Piece[] }[]) => void)[] -) { - const KDRatio = new KDRatioMetric(); } if (require.main === module) { - main(`data/10.10.23_test_set`).then(({}) => {}); + main(`data/lichess_db_standard_rated_2013-01.pgn`).then((a) => {}); } diff --git a/src/metrics/captures.ts b/src/metrics/captures.ts index f4f4225..6448846 100644 --- a/src/metrics/captures.ts +++ b/src/metrics/captures.ts @@ -1,85 +1,14 @@ import { ALL_SQUARES, - ALL_UNAMBIGUOUS_PIECE_SYMBOLS, - Chess, Piece, PrettyMove, - UnambiguousPieceSymbol, + Square, + UASymbol, } from '../../cjsmin/src/chess'; +import { BoardMap, UAPMap } from '../types'; +import { createBoardMap, createUAPMap } from '../utils'; import { Metric } from './metric'; -export function createBoardMap(): BoardMap { - /** - * i.e. - * a1: { - * k: { - * captured: 0, - * captures: 0, - * }, - * }, - */ - const squareCaptureInfo: { - [key: string]: { - [key: string]: { - captured: number; - captures: number; - revengeKills: number; - }; - }; - } = {}; - - for (const square of ALL_SQUARES) { - squareCaptureInfo[square] = {}; - for (const piece of ALL_UNAMBIGUOUS_PIECE_SYMBOLS) { - squareCaptureInfo[square][piece] = { - captured: 0, - captures: 0, - revengeKills: 0, - }; - } - } - - return squareCaptureInfo; -} - -interface BoardMap { - [key: string]: { - [key: string]: { - captured: number; - captures: number; - revengeKills: number; - }; - }; -} - -export function trackCaptures(boardMap: BoardMap, moves: PrettyMove[]) { - let lastMove: PrettyMove; - let i = 0; - for (const move of moves) { - if (move.capture) { - boardMap[move.to][move.uas].captures++; - boardMap[move.to][move.capture.uas].captured++; - // revenge kills - if (lastMove.capture && move.to === lastMove.to) { - boardMap[move.to][move.uas].revengeKills++; - } - } - lastMove = move; - i++; - } -} - -/** - * A utitily function to create an object with unambiguous piece symbols as keys - */ -function createUAPMap(object: T): { [key: string]: T } { - const map = {}; - for (const uap of ALL_UNAMBIGUOUS_PIECE_SYMBOLS) { - map[uap] = { ...object }; - } - return map; -} - export class KillStreakMetric implements Metric { killStreakMap: { [key: string]: { @@ -91,12 +20,6 @@ export class KillStreakMetric implements Metric { this.killStreakMap = createUAPMap({ killStreaks: 0 }); } - logResults(): void {} - - aggregate() { - return this.killStreakMap; - } - clear(): void { this.killStreakMap = createUAPMap({ killStreaks: 0 }); } @@ -107,7 +30,7 @@ export class KillStreakMetric implements Metric { ) { let i = startingIndex; let streakLength = 0; - let streakPiece: UnambiguousPieceSymbol; + let streakPiece: UASymbol; while (i < game.length) { const move = game[i].move; @@ -142,21 +65,18 @@ export class KillStreakMetric implements Metric { export class KDRatioMetric implements Metric { // create an object to track kills, deaths, and assists of each piece // The kDAssistsMap is an object where each key is a piece and the value is another object with kills, deaths, and assists properties. - KDAssistsMap: { - [key: string]: { - kills: number; - deaths: number; - assists: number; - }; - }; + KDAssistsMap: UAPMap<{ + kills: number; + deaths: number; + assists: number; + revengeKills: number; + }>; pieceWithHighestKDRatio: string; - KDRatios: { - [key: string]: number; - }; + // KDRatios is a convenience object for aggregation + kdRatios: UAPMap; constructor() { - this.KDAssistsMap = {}; - this.KDRatios = {}; + this.clear(); } logResults(): void { @@ -169,17 +89,18 @@ export class KDRatioMetric implements Metric { console.table(this.KDAssistsMap); console.log( 'Kill Death Ratios for each unambiguous piece: ' + - JSON.stringify(this.KDRatios, null, 2) + JSON.stringify(this.kdRatios, null, 2) ); } aggregate() { + const KDRatios = createUAPMap(0); // calculate the KD ratios of each piece - for (const piece of Object.keys(this.KDAssistsMap)) { - const kills = this.KDAssistsMap[piece].kills; - const deaths = this.KDAssistsMap[piece].deaths || 0; + for (const uas of Object.keys(this.KDAssistsMap)) { + const kills = this.KDAssistsMap[uas].kills; + const deaths = this.KDAssistsMap[uas].deaths || 0; if (deaths !== 0) { - this.KDRatios[piece] = kills / deaths; + KDRatios[uas] = kills / deaths; } } @@ -187,137 +108,222 @@ export class KDRatioMetric implements Metric { let maxKDRatio = 0; let pieceWithHighestKDRatio = null; - for (const piece of Object.keys(this.KDRatios)) { - if (this.KDRatios[piece] > maxKDRatio) { - maxKDRatio = pieceWithHighestKDRatio = this.KDRatios[piece]; + for (const uas of Object.keys(KDRatios)) { + if (KDRatios[uas] > maxKDRatio) { + maxKDRatio = pieceWithHighestKDRatio = KDRatios[uas]; } } return { maxKDRatio, pieceWithHighestKDRatio, - KDRatios: this.KDRatios, + KDRatios: KDRatios, }; } clear(): void { - this.KDAssistsMap = {}; - this.KDRatios = {}; + // KDRatios is reset JIT since it is only used in aggregation + this.KDAssistsMap = createUAPMap({ + kills: 0, + deaths: 0, + assists: 0, + revengeKills: 0, + }); } // calculates piece with highest K/D ratio and also contains assists by that piece - processGame(game: { move: PrettyMove; board: Piece[] }[]) { + processGame( + game: { move: PrettyMove; board: Piece[] }[], + metadata?: string[] + ) { + // @ts-ignore initialize with no capture + let previousMove: PrettyMove = {}; for (const { move } of game) { - if (!this.KDAssistsMap[move.uas]) { - this.KDAssistsMap[move.uas] = { - kills: 0, - deaths: 0, - assists: 0, - }; - } - if (move.capture) { this.KDAssistsMap[move.uas].kills++; + this.KDAssistsMap[move.capture.uas].deaths++; - // capture stores which piece was captured - if (!this.KDAssistsMap[move.capture.uas]) { - this.KDAssistsMap[move.capture.uas] = { - kills: 0, - deaths: 0, - assists: 0, - }; + if (previousMove.capture && move.to === previousMove.to) { + this.KDAssistsMap[move.uas].revengeKills++; } - this.KDAssistsMap[move.capture.uas].deaths++; + previousMove = move; } } + const lastMove = game[game.length - 1].move; // Check if the game is in checkmate after the last move - if (game[game.length - 1].move.originalString.includes('#')) { - const unambigMatingPiece = game[game.length - 1].move.uas; + if (lastMove.originalString.includes('#')) { + const unambigMatingPiece = lastMove.uas; this.KDAssistsMap[unambigMatingPiece].kills++; // only kings can get mated, and we know whose move it is - const matedKing = game[game.length - 1].move.color === 'w' ? 'k' : 'K'; + const matedKing = lastMove.color === 'w' ? 'k' : 'K'; this.KDAssistsMap[matedKing].deaths++; + + // A revenge kill can occur by checkmate too + const secondToLastMove = game[game.length - 2].move; + if (secondToLastMove.capture && secondToLastMove.uas === matedKing) { + this.KDAssistsMap[lastMove.uas].revengeKills++; + } } } } -// One edge case currently unaccounted for is when pieces "share" a mate, or check. This can be at most 2 due to discovery checks (currently we disregard this by just referring to whatever the PGN says. If the piece that moves causes checkmate, then it is the "mating piece") -export function getMateAndAssists(pgnMoveLine: string) { - const chess = new Chess(); - const moveGenerator = chess.historyGenerator(pgnMoveLine); - - let matingPiece, - assistingPiece, - hockeyAssist, - unambigMatingPiece, - unambigMatedPiece, - unambigAssistingPiece, - unambigHockeyAssistPiece, - lastPieceMoved; - - // Keep track of the last few moves - let lastFewMoves: PrettyMove[] = []; +export class MateAndAssistMetric implements Metric { + mateAndAssistMap: UAPMap<{ + mates: number; + assists: number; + hockeyAssists: number; + }>; + matedCounts: { + k: number; + K: number; + }; - for (let moveInfo of moveGenerator) { - const { move, board } = moveInfo; + // these are initialized as undefined + constructor() { + this.clear(); + } - // Add the current move to the start of the array - lastFewMoves.unshift(move); + // TODO: maybe slightly better if we don't recreate when clearing + clear(): void { + this.mateAndAssistMap = createUAPMap({ + mates: 0, + assists: 0, + hockeyAssists: 0, + }); + + // We delete kings because they cannot deliver checks and can only be mated + delete this.mateAndAssistMap.k; + delete this.mateAndAssistMap.K; + this.matedCounts = { + k: 0, + K: 0, + }; + } - // If we have more than 5 moves in the array, remove the oldest one - if (lastFewMoves.length > 5) { - lastFewMoves.pop(); + // One edge case currently unaccounted for is when pieces "share" a mate, or check. This can be at most 2 due to discovery + // checks (currently we disregard this by just saying the last piece to move is the "mating piece") + processGame(game: { move: PrettyMove; board: Piece[] }[]) { + // Take no action if the game didn't end in checkmate + if (!game[game.length - 1].move.originalString.includes('#')) { + return; } - if (move?.originalString.includes('#')) { - matingPiece = move.piece; - unambigMatingPiece = move.uas; + const lastMove = game[game.length - 1].move; + + // increment the mate count of the mating piece + this.mateAndAssistMap[lastMove.uas].mates++; + // increment the mated (death) count of the mated king + this.matedCounts[lastMove.color === 'w' ? 'k' : 'K']++; - // Determine the color of the mated king - const matedKingColor = move.color === 'w' ? 'b' : 'w'; - unambigMatedPiece = matedKingColor === 'w' ? 'K' : 'k'; + // The fastest possible checkmate is in 2 moves, so we do have to check for out of bounds - // If mate see if also assist + // Look back 2 moves to see if there was an assist + if (game.length > 2) { + const assistMove = game[game.length - 3].move; if ( - lastFewMoves[2] && - lastFewMoves[2].originalString.includes('+') && - lastFewMoves[2].uas !== unambigMatingPiece + assistMove.originalString.includes('+') && + assistMove.uas !== lastMove.uas ) { - assistingPiece = lastFewMoves[2].piece; - unambigAssistingPiece = lastFewMoves[2].uas; + this.mateAndAssistMap[assistMove.uas].assists++; + } - // If assist check for hockey assist + // hockey assist is only counted if there was also an assist + if (game.length > 4) { + const hockeyAssistMove = game[game.length - 5].move; if ( - lastFewMoves[4] && - lastFewMoves[4].originalString.includes('+') && - lastFewMoves[4].uas !== unambigAssistingPiece && - lastFewMoves[4].uas !== unambigMatingPiece + hockeyAssistMove.originalString.includes('+') && + assistMove.uas !== lastMove.uas ) { - hockeyAssist = lastFewMoves[4].piece; - unambigHockeyAssistPiece = lastFewMoves[4].uas; + this.mateAndAssistMap[hockeyAssistMove.uas].hockeyAssists++; } } } } - // console.log('mating piece: ', matingPiece); - // console.log('assisting piece: ', assistingPiece); - // console.log('hockey assisting piece: ', hockeyAssist); - // console.log('unambig mating piece: ', unambigMatingPiece); - // console.log('unambig mated piece: ', unambigMatedPiece); - // console.log('unambig assisting piece: ', unambigAssistingPiece); - // console.log('unambig hockey assisting piece: ', unambigHockeyAssistPiece); - // console.log('last piece moved: ', lastPieceMoved); - - return { - matingPiece, - assistingPiece, - hockeyAssist, - unambigMatingPiece, - unambigMatedPiece, - unambigAssistingPiece, - unambigHockeyAssistPiece, - lastPieceMoved, +} + +export class CaptureLocationMetric implements Metric { + captureLocationMap: { + [key in Square]: UAPMap<{ captures: number; captured: number }>; }; + + constructor() { + this.clear(); + } + + clear(): void { + const newMap = {}; + for (const square of ALL_SQUARES) { + newMap[square] = createUAPMap({ captures: 0, captured: 0 }); + } + this.captureLocationMap = newMap as any; + } + + processGame( + game: { move: PrettyMove; board: Piece[] }[], + metadata?: string[] + ) { + let lastMove: PrettyMove; + for (const { move, board } of game) { + if (move.capture) { + board[move.to][move.uas].captures++; + board[move.to][move.capture.uas].captured++; + } + lastMove = move; + } + } + + aggregate() { + // Gets a capture total for each square + const captureTotals = createUAPMap({ captures: 0, captured: 0 }); + for (const square of Object.keys(this.captureLocationMap)) { + for (const uas of Object.keys(this.captureLocationMap[square])) { + captureTotals[square] += this.captureLocationMap[square][uas].captures; + captureTotals[square] += this.captureLocationMap[square][uas].captured; + } + } + } } + +export class MatingSquareMetric implements Metric { + matingSquareMap: BoardMap<{ + mates: number; + assists: number; + hockeyAssists: number; + }>; + + // these are initialized as undefined + constructor() { + this.clear(); + } + + // TODO: maybe slightly better if we don't recreate when clearing + clear(): void { + this.matingSquareMap = createBoardMap({ + mates: 0, + assists: 0, + hockeyAssists: 0, + }); + } + + // One edge case currently unaccounted for is when pieces "share" a mate, or check. This can be at most 2 due to discovery + // checks (currently we disregard this by just saying the last piece to move is the "mating piece") + processGame(game: { move: PrettyMove; board: Piece[] }[]) { + // Take no action if the game didn't end in checkmate + if (!game[game.length - 1].move.originalString.includes('#')) { + return; + } + + const lastMove = game[game.length - 1].move; + // TODO: this is not properly tracking which pieces are delivering mates or asssits, because discovery checks can be delivered + // by pieces other than the last piece to move + this.matingSquareMap[lastMove.to][lastMove.uas].mates++; + } +} + +/** + * When determining discovery checks, we need to look at the ray that was revealed. That measn tracking the index of the king + * and the index of the moving piece, tracing that line back and seeing if a piece is now threatening. + * We also need to track the new piece and see if its movement has created a new threat ray + */ diff --git a/src/metrics/distances.ts b/src/metrics/distances.ts index edf51b9..194794c 100644 --- a/src/metrics/distances.ts +++ b/src/metrics/distances.ts @@ -1,190 +1,156 @@ -import { Chess, UnambiguousPieceSymbol } from '../../cjsmin/src/chess'; -import { FileReaderGame } from '../types'; - -// take a start and end board position and return the distances moved -export async function getMoveDistanceSingleGame(game: FileReaderGame) { - const chess = new Chess(); - const moveGenerator = chess.historyGenerator(game.moves); - - // create an object to track distance value for each piece - const distanceMap: { [key: string]: number } = {}; - - // Initialize variables to keep track of the maximum distance and the piece - let maxDistance = -1; - let maxDistancePiece: UnambiguousPieceSymbol; - let singleGameDistanceTotal = 0; - - // evaluate each move, update the correct unambiguous piece's distance - for (let moveInfo of moveGenerator) { - const { move, board } = moveInfo; - - if (!distanceMap[move.uas]) { - distanceMap[move.uas] = 0; - } - - const fromMove = moveInfo.move.from; - const toMove = moveInfo.move.to; +import { Piece, PrettyMove, UASymbol } from '../../cjsmin/src/chess'; +import { UAPMap } from '../types'; +import { createUAPMap } from '../utils'; +import { Metric } from './metric'; + +export class MoveDistanceMetric implements Metric { + distanceMap: UAPMap<{ total: number; maxSingleGame: number }>; + pieceWithHighestAvg: UASymbol; + pieceWithLowestAvg: UASymbol; + maxAvgDistance: number; + minAvgDistance: number; + totalDistance: number; + maxSingleGameTotal: number; + // This has arrays to account for ties. Postions connect link to uas + pieceMaxes: { + distance: number; + uasArray: UASymbol[]; + linkArray: string[]; + }; + gamesProcessed: number; - let distance = 0; + constructor() { + this.clear(); + } - // Check if the move is a castling move - if (moveInfo.move.flags === 'k' || moveInfo.move.flags === 'q') { - let movingKing = 'k'; - let movingRook, rookDistance; + clear(): void { + this.distanceMap = createUAPMap({ + total: 0, + maxSingleGame: 0, + }); + this.pieceWithHighestAvg = undefined; + this.pieceWithLowestAvg = undefined; + this.maxAvgDistance = 0; + this.minAvgDistance = Infinity; // Set high so first will overwrite + this.totalDistance = 0; + this.pieceMaxes = { + distance: 0, + uasArray: [], + linkArray: [], + }; + this.gamesProcessed = 0; + } - if (moveInfo.move.flags === 'k') { - rookDistance = 2; - movingRook = 'rh'; - } else { - rookDistance = 3; - movingRook = 'ra'; + aggregate() { + // reset just the total aggregates, the others don't need a reset + this.totalDistance = 0; + for (const uas of Object.keys(this.distanceMap)) { + // increment the total distance by adding all pieces + this.totalDistance += this.distanceMap[uas].total; + + const avgDistance = this.distanceMap[uas].total / this.gamesProcessed; + if (avgDistance > this.maxAvgDistance) { + this.maxAvgDistance = avgDistance; + this.pieceWithHighestAvg = uas as UASymbol; } - - if (moveInfo.move.color === 'w') { - movingRook = movingRook.toUpperCase(); - movingKing = movingKing.toUpperCase(); + if (avgDistance < this.minAvgDistance) { + this.minAvgDistance = avgDistance; + this.pieceWithLowestAvg = uas as UASymbol; } - - distanceMap[movingKing] += 2; - distanceMap[movingRook] += rookDistance; - singleGameDistanceTotal += 2; - singleGameDistanceTotal += rookDistance; - } else { - // Calculate the file (column) distance by subtracting ASCII values - const fileDist = Math.abs(fromMove.charCodeAt(0) - toMove.charCodeAt(0)); - // Calculate the rank (row) distance by subtracting numeric values - const rankDist = Math.abs(Number(fromMove[1]) - Number(toMove[1])); - // The distance moved is the maximum of fileDist and rankDist - distance = Math.max(fileDist, rankDist); - - distanceMap[move.uas] += distance; - singleGameDistanceTotal += distance; - } - - if (distanceMap[move.uas] > maxDistance) { - maxDistance = distanceMap[move.uas]; - maxDistancePiece = move.uas; } } - return { - maxDistancePiece, - maxDistance, - distanceMap, - singleGameDistanceTotal, - }; -} + logResults(): void { + console.timeEnd('Task 2: getMoveDistanceSetOfGames'); + + // distance facts + console.log('DISTANCE FACTS:'); + console.log( + '==============================================================\n' + ); + console.log( + `Piece with highest avg distance for games analyzed: ${this.pieceWithHighestAvg}` + ); + console.log( + `That piece's (${this.pieceWithHighestAvg}'s) average distance moved per game: ${this.maxAvgDistance}` + ); + + // Facts + console.log(`Piece that moved the furthest: ${this.pieceMaxes.uasArray}`); + // Game link support will come later + // console.log( + // `Game in which that piece (${this.maxSingleGameDistancePiece}) moved the furthest: ${siteWithFurthestPiece}` + // ); + console.log( + `Distance that piece moved in the game: ${this.pieceMaxes.distance}` + ); + // console.log( + // `Game with the furthest collective distance moved: ${gameLinkWithFurthestCollectiveDistance}` + // ); + console.log( + `Collective distance moved in that game: ${this.maxSingleGameTotal}` + ); + } -// returns the piece that moved the furthest, the game it moved the furthest in, the distance it moved, and the number of games analyzed in the set -export async function getMoveDistanceSetOfGames(games: FileReaderGame[]) { - console.time('Task 2: getMoveDistanceSetOfGames'); - let maxDistance = 0; - let pieceThatMovedTheFurthest = null; - let totalDistanceMap: { [key: string]: number } = {}; - let gameWithFurthestPiece = null; - let siteWithFurthestPiece = null; - let lastGame; - let furthestCollectiveDistance = 0; - let gameLinkWithFurthestCollectiveDistance = null; - - let gameCount = 0; - for await (const game of games) { - // progress tracker - gameCount++; - - const { - maxDistancePiece, - maxDistance: distance, - distanceMap, - singleGameDistanceTotal, - } = await getMoveDistanceSingleGame(game); - - if (distance > maxDistance) { - maxDistance = distance; - pieceThatMovedTheFurthest = maxDistancePiece; - gameWithFurthestPiece = game; - let site = game.metadata - .find((item) => item.startsWith('[Site "')) - ?.replace('[Site "', '') - .replace('"]', ''); - siteWithFurthestPiece = site; + processGame(game: { move: PrettyMove; board: Piece[] }[]) { + // Initialize variables to keep track of the maximum distance and the piece + const singleGameMap = createUAPMap({ total: 0 }); + + for (const { move } of game) { + // Check if the move is a castling move + if (move.flags === 'k' || move.flags === 'q') { + let movingKing = 'k'; + let movingRook, rookDistance; + + if (move.flags === 'k') { + rookDistance = 2; + movingRook = 'rh'; + } else { + rookDistance = 3; + movingRook = 'ra'; + } + + if (move.color === 'w') { + movingRook = movingRook.toUpperCase(); + movingKing = movingKing.toUpperCase(); + } + + // 2 for king + rook distance + singleGameMap[movingKing].total += 2; + singleGameMap[movingRook].total += rookDistance; + } else { + // Calculate the file (column) distance by subtracting ASCII values + const fileDist = Math.abs( + move.from.charCodeAt(0) - move.to.charCodeAt(0) + ); + // Calculate the rank (row) distance by subtracting numeric values + const rankDist = Math.abs(Number(move.from[1]) - Number(move.to[1])); + // The distance moved is the maximum of fileDist and rankDist + const distance = Math.max(fileDist, rankDist); + + singleGameMap[move.uas].total += distance; + } } - if (singleGameDistanceTotal > furthestCollectiveDistance) { - furthestCollectiveDistance = singleGameDistanceTotal; - gameLinkWithFurthestCollectiveDistance = game.metadata - .find((item) => item.startsWith('[Site "')) - ?.replace('[Site "', '') - .replace('"]', ''); - } + // add the single game aggregates to the state object + for (const uas of Object.keys(singleGameMap)) { + this.distanceMap[uas].total += singleGameMap[uas].total; + if ( + singleGameMap[uas].total > this.distanceMap[uas].maxSingleGameDistance + ) { + this.distanceMap[uas].maxSingleGameDistance = singleGameMap[uas].total; + } - for (const piece of Object.keys(distanceMap)) { - if (!totalDistanceMap[piece]) { - totalDistanceMap[piece] = 0; + // find the individual piece maxes + if (singleGameMap[uas].total > this.pieceMaxes.distance) { + this.pieceMaxes.uasArray = [uas as UASymbol]; + this.pieceMaxes.distance = singleGameMap[uas].total; + // this.singleGameMaxPiece.link = undefined; // TODO: add game link support + } else if (singleGameMap[uas].total === this.pieceMaxes.distance) { + this.pieceMaxes.uasArray.push(uas as UASymbol); } - totalDistanceMap[piece] += distanceMap[piece]; } - lastGame = game; + this.gamesProcessed++; } - - console.timeEnd('Task 2: getMoveDistanceSetOfGames'); - - // distance facts - console.log('DISTANCE FACTS:'); - console.log('=============================================================='); - console.log('\n'); - - // Facts - console.log(`Piece that moved the furthest: ${pieceThatMovedTheFurthest}`); - console.log( - `Game in which that piece (${pieceThatMovedTheFurthest}) moved the furthest: ${siteWithFurthestPiece}` - ); - console.log(`Distance that piece moved in the game: ${maxDistance}`); - console.log( - `Game with the furthest collective distance moved: ${gameLinkWithFurthestCollectiveDistance}` - ); - console.log( - `Collective distance moved in that game: ${furthestCollectiveDistance}` - ); - - return { - pieceThatMovedTheFurthest, - maxDistance, - gameCount, - gameWithFurthestPiece, - siteWithFurthestPiece, - totalDistanceMap, - lastGame, - furthestCollectiveDistance, - gameLinkWithFurthestCollectiveDistance, - }; -} - -// calculates piece with highest average distance and that piece's average distance covered per game in a set of games -export function getAverageDistance( - distanceMap: { [key: string]: number }, - gameCount: number -) { - console.time('Task 3: getAverageDistance'); - let maxAverageDistance = 0; - let pieceWithHighestAverageDistance = null; - - for (const piece of Object.keys(distanceMap)) { - const averageDistance = distanceMap[piece] / gameCount; - if (averageDistance > maxAverageDistance) { - maxAverageDistance = averageDistance; - pieceWithHighestAverageDistance = piece; - } - } - - console.log( - `Piece with highest avg distance for games analyzed: ${pieceWithHighestAverageDistance}` - ); - console.log( - `That piece's (${pieceWithHighestAverageDistance}'s) average distance moved per game: ${maxAverageDistance}` - ); - - console.timeEnd('Task 3: getAverageDistance'); - return { pieceWithHighestAverageDistance, maxAverageDistance }; } diff --git a/src/metrics/metric.ts b/src/metrics/metric.ts index 4fde925..b85ede3 100644 --- a/src/metrics/metric.ts +++ b/src/metrics/metric.ts @@ -1,7 +1,10 @@ import { Piece, PrettyMove } from '../../cjsmin/src/chess'; export interface Metric { - processGame(game: { move: PrettyMove; board: Piece[] }[]): any; + processGame( + game: { move: PrettyMove; board: Piece[] }[], + metadata?: string[] + ): any; logResults?(): void; @@ -9,5 +12,5 @@ export interface Metric { clear?(): void; // Aggregate the results of the metric - aggregate?(): any; + aggregate?(...args: any[]): any; } diff --git a/src/metrics/moves.ts b/src/metrics/moves.ts index 3177c04..0b79f7f 100644 --- a/src/metrics/moves.ts +++ b/src/metrics/moves.ts @@ -1,164 +1,108 @@ -import { Chess } from '../../cjsmin/src/chess'; -import { FileReaderGame } from '../types'; -export async function getGameWithMostMoves(games: FileReaderGame[]) { - console.time('Task 5: getGameWithMostMoves'); - let maxNumMoves = 0; - let gameWithMostMoves: FileReaderGame | null = null; - let gameLinkWithMostMoves = null; - - for await (const game of games) { - const chess = new Chess(); - - chess.loadPgn(game.moves); - const numMoves = chess.history().length; - - if (numMoves > maxNumMoves) { - maxNumMoves = numMoves; - gameWithMostMoves = game; - let site = game.metadata - .find((item) => item.startsWith('[Site "')) - ?.replace('[Site "', '') - .replace('"]', ''); - gameLinkWithMostMoves = site; - } +import { Piece, PrettyMove, UASymbol } from '../../cjsmin/src/chess'; +import { UAPMap } from '../types'; +import { createUAPMap } from '../utils'; +import { Metric } from './metric'; + +export class GameWithMostMovesMetric implements Metric { + link: string; + numMoves: number; + + constructor() { + this.clear(); } - console.timeEnd('Task 5: getGameWithMostMoves'); + clear(): void { + this.link = undefined; + this.numMoves = 0; + } - // moves facts - console.log('MOVES FACTS:'); - console.log(`The game with the most moves played: ${gameWithMostMoves}`); - console.log(`The number of moves played in that game: ${maxNumMoves}`); + processGame( + game: { move: PrettyMove; board: Piece[] }[], + metadata: string[] + ) { + if (game.length > this.numMoves) { + this.numMoves = game.length; + this.link = metadata[1].match(/"(.*?)"/)[1]; + } + } - console.log('=============================================================='); - console.log('\n'); + logResults(): void { + console.log('MOVES FACTS:'); + console.log(`The game with the most moves played: ${this.link}`); + console.log(`The number of moves played in that game: ${this.numMoves}`); - return { - gameLinkWithMostMoves, - maxNumMoves, - }; + console.log( + '==============================================================' + ); + console.log('\n'); + } } -export async function getPieceLevelMoveInfo(games: FileReaderGame[]) { - console.time('Task 6: getPieceLevelMoveInfo'); - const numMovesByPiece = {}; - let avgMovesByPiece = {}; - let piecesWithMostMovesInAGame = []; - let piecesWithHighestAvgMoves = []; - let linkWithMostMoves = []; - let maxMoves = 0; +export class PieceLevelMoveInfoMetric implements Metric { + totalMovesByPiece: UAPMap<{ numMoves: number }>; + singleGameMaxMoves: number; + uasWithMostMoves: UASymbol[]; + gamesWithMostMoves: string[]; + gamesProcessed: number; // this could be tracked externally also, in other metrics - let gameCount = 0; - - for (const game of games) { - gameCount++; - const chess = new Chess(); - const moveGenerator = chess.historyGenerator(game.moves); + constructor() { + this.clear(); + } - const numMovesByPieceThisGame = {}; + clear(): void { + this.totalMovesByPiece = createUAPMap({ numMoves: 0 }); + this.singleGameMaxMoves = 0; + this.uasWithMostMoves = []; + this.gamesProcessed = 0; + } + processGame( + game: { move: PrettyMove; board: Piece[] }[], + metadata: string[] + ) { // update move counts of each unambiguous piece - for (let moveInfo of moveGenerator) { - const { move } = moveInfo; - - let movedPiece = move.uas; - - if (movedPiece) { - if (!numMovesByPiece[movedPiece]) { - numMovesByPiece[movedPiece] = 0; - } - numMovesByPiece[movedPiece]++; - numMovesByPieceThisGame[movedPiece]++; - - // Check if the move is a castling move - if (moveInfo.move.flags === 'k' || moveInfo.move.flags === 'q') { - let movingRook = moveInfo.move.flags === 'k' ? 'rh' : 'ra'; - if (moveInfo.move.color === 'w') { - movingRook = movingRook.toUpperCase(); - } - - if (!numMovesByPiece[movingRook]) { - numMovesByPiece[movingRook] = 0; - } - - // duplicative action for the array capturing moves by piece for this game - if (!numMovesByPieceThisGame[movingRook]) { - numMovesByPieceThisGame[movingRook] = 0; - } - - numMovesByPiece[movingRook]++; - numMovesByPieceThisGame[movingRook]++; + const currentGameStats = createUAPMap({ numMoves: 0 }); + for (let { move } of game) { + currentGameStats[move.uas].numMoves++; + + // Check if the move is a castling move, if so we need to increment rook too + if (move.flags === 'k' || move.flags === 'q') { + let movingRook = move.flags === 'k' ? 'rh' : 'ra'; + if (move.color === 'w') { + movingRook = movingRook.toUpperCase(); } + + currentGameStats[movingRook].numMoves++; } } - for (const uahPiece of Object.keys(numMovesByPieceThisGame)) { - let maxMovesInGame = numMovesByPieceThisGame[uahPiece]; - - if (maxMovesInGame > maxMoves) { - maxMoves = maxMovesInGame; - piecesWithMostMovesInAGame = [uahPiece]; // New highest moves, reset the array - linkWithMostMoves = [ - game.metadata - .find((item) => item.startsWith('[Site "')) - ?.replace('[Site "', '') - .replace('"]', ''), - ]; // New highest moves, reset the array - } else if (maxMovesInGame === maxMoves) { - piecesWithMostMovesInAGame.push(uahPiece); // Tie, add to the array - linkWithMostMoves.push( - game.metadata - .find((item) => item.startsWith('[Site "')) - ?.replace('[Site "', '') - .replace('"]', '') - ); // Tie, add to the array + // Calculate single game maxes & add to global totals + for (const uas of Object.keys(currentGameStats)) { + // increment global totals + this.totalMovesByPiece[uas].numMoves += currentGameStats[uas].numMoves; + const gameLink = metadata[1].match(/"(.*?)"/)[1]; + + if (currentGameStats[uas].numMoves > this.singleGameMaxMoves) { + this.singleGameMaxMoves = currentGameStats[uas].numMoves; + this.uasWithMostMoves = [uas as UASymbol]; // New highest moves, reset the array + this.gamesWithMostMoves = [gameLink]; // New highest moves, reset the array + } else if (currentGameStats[uas] === this.singleGameMaxMoves) { + this.uasWithMostMoves.push(uas as UASymbol); // Tie, add to the array + this.gamesWithMostMoves.push(gameLink); } } - } - // calculate average num moves by piece - for (const uahPiece of Object.keys(numMovesByPiece)) { - avgMovesByPiece[uahPiece] = numMovesByPiece[uahPiece] / gameCount; + this.gamesProcessed++; } - let maxAverageNumMoves = 0; - - // find the piece with the highest average num moves - for (const uahPiece of Object.keys(avgMovesByPiece)) { - const averageNumMoves = avgMovesByPiece[uahPiece]; - if (averageNumMoves > maxAverageNumMoves) { - maxAverageNumMoves = averageNumMoves; - piecesWithHighestAvgMoves = [uahPiece]; // New highest average, reset the array - } else if (averageNumMoves === maxAverageNumMoves) { - piecesWithHighestAvgMoves.push(uahPiece); // Tie, add to the array + aggregate() { + const averagesMap = createUAPMap({ avgMoves: 0 }); + // Calculate averages + for (const uas of Object.keys(this.totalMovesByPiece)) { + averagesMap[uas].avgMoves = + this.totalMovesByPiece[uas].numMoves / this.gamesProcessed; } - } - console.log( - `The piece with the highest average number moves: ${piecesWithHighestAvgMoves}` - ); - console.log( - `The piece with the most moves in a single game: ${piecesWithMostMovesInAGame}` - ); - console.log('The total number of moves by piece in the set of games:'), - console.table(numMovesByPiece); - console.log('The average number of moves by piece in the set of games:'), - console.table(avgMovesByPiece); - console.log( - `The number of moves played by that piece in that game: ${maxMoves}` - ); - console.log( - `The game that piece made that many moves in: ${linkWithMostMoves}` - ); - - console.timeEnd('Task 6: getPieceLevelMoveInfo'); - - return { - numMovesByPiece, - avgMovesByPiece: avgMovesByPiece, - piecesWithHighestAvgMoves: piecesWithHighestAvgMoves, - piecesWithMostMovesInAGame, - linkWithMostMoves, - maxMoves, - }; + return averagesMap; + } } diff --git a/src/metrics/promotions.ts b/src/metrics/promotions.ts index 73fec04..708932e 100644 --- a/src/metrics/promotions.ts +++ b/src/metrics/promotions.ts @@ -1,54 +1,60 @@ -import { Chess } from '../../cjsmin/src/chess'; -import { FileReaderGame } from '../types'; - -export async function getPiecePromotionInfo(games: FileReaderGame[]) { - console.time('Task 7: getPiecePromotionInfo'); - let ambigPiecePromotedToMap = {}; - let promotingPieceMap = {}; - - for (const game of games) { - const chess = new Chess(); - chess.loadPgn(game.moves); - const chessHistory = chess.history(); +import { + Pawns, + Piece, + PrettyMove, + PromotablePiece, +} from '../../cjsmin/src/chess'; +import { Metric } from './metric'; + +export class PromotionMetric implements Metric { + //uas pawns mapped to count of promotions to each piece type + //prettier-ignore + promotionMap: { + [key in Pawns]: { + [key in PromotablePiece]: number; + } + }; - for (const moveInfo of chessHistory) { - if (moveInfo.originalString.includes('=')) { - // REGEX to only capture the piece type - const piecePromotedTo = moveInfo.originalString - .split('=')[1] - .match(/[a-zA-Z]/)[0]; + constructor() { + this.clear(); + } - const promotingPiece = moveInfo.uas; + clear(): void { + let promotionMap = {}; + //prettier-ignore + for (const pawn of ["pa", "pb", "pc", "pd", "pe", "pf", "pg", "ph", 'PA', 'PB', 'PC', 'PD', 'PE', 'PF', 'PG', 'PH']) { + promotionMap[pawn] = { q: 0, r: 0, b: 0, n: 0 }; + } + this.promotionMap = promotionMap as any; + } + processGame( + game: { move: PrettyMove; board: Piece[] }[], + metadata?: string[] + ) { + for (const { move } of game) { + // TODO: we can use flags instead of includes('=) + if (move.originalString.includes('=')) { // update ambigPiecePromotedToMap - if (!ambigPiecePromotedToMap[piecePromotedTo]) { - ambigPiecePromotedToMap[piecePromotedTo] = 0; - } - ambigPiecePromotedToMap[piecePromotedTo]++; - - // update promotingPieceMap - if (!promotingPieceMap[promotingPiece]) { - promotingPieceMap[promotingPiece] = 0; - } - promotingPieceMap[promotingPiece]++; + this.promotionMap[move.uas][move.promotion]++; } } } - // promotions facts - console.log('PROMOTIONS FACTS:'); - console.log( - 'How often a piece is promoted to different ambiguous piece types:' - ), - console.table(ambigPiecePromotedToMap); - console.log('How often unambiguous piece is promoted:'), - console.table(promotingPieceMap); - console.log('=============================================================='); - console.log('\n'); - - console.timeEnd('Task 7: getPiecePromotionInfo'); - return { - ambigPiecePromotedToMap, - promotingPieceMap, - }; + aggregate() {} + + logResults(): void { + // promotions facts + console.log('PROMOTIONS FACTS:'); + console.log( + 'How often a piece is promoted to different ambiguous piece types:' + ), + console.table(this.promotionMap); + console.log('How often unambiguous piece is promoted:'), + console.table(this.promotionMap); + console.log( + '==============================================================' + ); + console.log('\n'); + } } diff --git a/src/prepare.ts b/src/prepare.ts deleted file mode 100644 index 843d694..0000000 --- a/src/prepare.ts +++ /dev/null @@ -1,52 +0,0 @@ -// import { Chess } from 'chess.js'; - -import { type Chess } from '../cjsmin/src/chess'; - -// TODO: if needed we can overwrite the history code to store only what we need https://github.com/jhlywa/chess.js/blob/master/README.md#history-options- -export function getGameHistory(board: Chess, moves: string) { - board.loadPgn(moves); - return board.history(); -} - -// Should return an object for the metrics we want to track, not sure how best to structure so an exercise for the reader -export function initializeMetricMaps() { - // kd ratio, distances moved, - - const squareInfo = { - kills: { - p: 0, - n: 0, - b: 0, - r: 0, - q: 0, - k: 0, - }, - deaths: { - p: 0, - n: 0, - b: 0, - r: 0, - q: 0, - k: 0, - }, - }; - - // adapted some chatgpt code for this - const chessboard: { [key: string]: typeof squareInfo } = {}; - for (const rank of ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']) { - for (const file of ['1', '2', '3', '4', '5', '6', '7', '8']) { - chessboard[rank + file] = { ...squareInfo }; - } - } - - // return { - // pawn: {}, - // knight: {}, - // bishop: {}, - // rook: {}, - // queen: {}, - // king: {}, - // }; - - return chessboard; -} diff --git a/src/types.ts b/src/types.ts index 71b9c04..8aab493 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,8 +1,16 @@ -import { PieceType, Square } from '../cjsmin/src/chess'; +import { Square, UASymbol } from '../cjsmin/src/chess'; export interface FileReaderGame { moves: string; - metadata: string[]; + metadata?: string[]; } +export type UAPMap = { + [key in UASymbol]: T; +}; +export type BoardMap = { + [key in Square]: { + [key in UASymbol]: T; + }; +}; diff --git a/src/utils.ts b/src/utils.ts index 6062e89..a408ecd 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,3 +1,12 @@ +import { + ALL_SQUARES, + ALL_UNAMBIGUOUS_PIECE_SYMBOLS, + Chess, + UASymbol, +} from '../cjsmin/src/chess'; +import { gameChunks } from './fileReader'; +import { BoardMap, UAPMap } from './types'; + export function orderObject(unordered) { return Object.keys(unordered) .sort() @@ -6,3 +15,61 @@ export function orderObject(unordered) { return obj; }, {}); } + +export function createBoardMapOld(): BoardMap<{ + captured: number; + captures: number; + revengeKills: number; +}> { + /** + * i.e. + * a1: { + * k: { + * captured: 0, + * captures: 0, + * }, + * }, + */ + const squareCaptureInfo: any = {}; // make typing simpler + + for (const square of ALL_SQUARES) { + squareCaptureInfo[square] = {}; + for (const piece of ALL_UNAMBIGUOUS_PIECE_SYMBOLS) { + squareCaptureInfo[square][piece] = { + captured: 0, + captures: 0, + revengeKills: 0, + }; + } + } + + return squareCaptureInfo; +} + +/** + * A utitily function to create an object with unambiguous piece symbols as keys + */ +export function createUAPMap(object: T): UAPMap { + const map = {}; + for (const uap of ALL_UNAMBIGUOUS_PIECE_SYMBOLS) { + map[uap] = { ...object }; + } + return map as { [key in UASymbol]: T }; +} + +export function createBoardMap(object: T): BoardMap { + const map = {}; + for (const square of ALL_SQUARES) { + map[square] = createUAPMap(object); + } + return map as BoardMap; +} + +export async function* getHistoriesFromFilePath(path: string) { + const chess = new Chess(); + const gamesGenerator = gameChunks(path); + for await (const game of gamesGenerator) { + chess.loadPgn(game.moves); + yield chess.history(); + } +} diff --git a/tests/enPassant.test.ts b/tests/enPassant.test.ts index 8ce74a8..3412919 100644 --- a/tests/enPassant.test.ts +++ b/tests/enPassant.test.ts @@ -3,7 +3,7 @@ import { Chess } from '../cjsmin/src/chess'; const pgnEP = `1. d2d4 f7f5 2. b2b3 e7e6 3. c1b2 d7d5 4. g1f3 f8d6 5. e2e3 g8f6 6. b1d2 e8g8 7. c2c4 c7c6 8. f1d3 b8d7 9. e1g1 f6e4 10. a1c1 g7g5 11. h2h3 d8e8 12. d3e4 d5e4 13. f3g5 e8g6 14. h3h4 h7h6 15. g5h3 d7f6 16. f2f4 e4f3 17. d2f3 f6g4 18. d1e2 d6g3 19. h3f4 g6g7 20. d4d5 g7f7 21. d5e6 c8e6 22. f3e5 g4e5 23. b2e5 g8h7 24. h4h5 f8g8 25. e2f3 g3f4 26. e5f4 g8g4 27. g2g3 a8g8 28. c1c2 b7b5 29. c4b5 e6d5 30. f3d1 f7h5 31. c2h2 g4g3+ 32. f4g3 g8g3+ 33. g1f2 h5h2+ 34. f2e1 g3g2 35. d1d3 d5e4 36. d3d7+ h7g6 37. b5c6 g2e2+ 38. e1d1 e2a2 0-1`; -xdescribe('Game history for en passant move should show valid captured piece', () => { +describe('Game history for en passant move should show valid captured piece', () => { const chess = new Chess(); it('should return the correct captured piece', () => { const game = [ diff --git a/tests/historyGenerator.test.ts b/tests/historyGenerator.test.ts index 34cae70..433b362 100644 --- a/tests/historyGenerator.test.ts +++ b/tests/historyGenerator.test.ts @@ -3,7 +3,7 @@ import { Chess } from '../cjsmin/src/chess'; /** * @beta - this test was generated partially with chatGPT so might be an invalid PGN */ -xdescribe('Chess', () => { +describe('Chess', () => { describe('historyGenerator', () => { it('should generate the correct move history for a given PGN string', () => { const chess = new Chess(); @@ -14,8 +14,6 @@ xdescribe('Chess', () => { const expectedMoves = moveString.split(' ').filter((_, i) => i % 3 !== 0); expectedMoves.pop(); // remove the result from the end of the array for (const { move, board } of gen) { - // console.log(board); - console.log(move); // validate that the piece that was moved is of the same type as the destination square expect(move.piece).toEqual(board[move.toIndex].type); expect(move.uas).toEqual(board[move.toIndex].uas); diff --git a/tests/metrics.test.ts b/tests/metrics.test.ts index 1481900..6cf857c 100644 --- a/tests/metrics.test.ts +++ b/tests/metrics.test.ts @@ -3,10 +3,14 @@ import { Chess } from '../cjsmin/src/chess'; import { KDRatioMetric, KillStreakMetric, - getMateAndAssists, + MateAndAssistMetric, } from '../src/metrics/captures'; -import { getMoveDistanceSingleGame } from '../src/metrics/distances'; -import { getGameWithMostMoves } from '../src/metrics/moves'; +import { MoveDistanceMetric } from '../src/metrics/distances'; +import { + GameWithMostMovesMetric, + PieceLevelMoveInfoMetric, +} from '../src/metrics/moves'; +import { PromotionMetric } from '../src/metrics/promotions'; // convert PGN string to GameHistoryObject export function pgnToGameHistory(pgn: string) { @@ -53,19 +57,25 @@ describe('All Tests', () => { }); }); - xdescribe('tracks kills, deaths and revenge kills by square', () => { + describe('tracks kills, deaths and revenge kills by square', () => { it('should return the correct kill streaks', () => {}); }); - xdescribe('getMateAndAssists', () => { - it('should return empty objects if there is no mate or assist', () => { - const gameHistory: any[] = [ + describe('getMateAndAssists', () => { + const mateAndAssistMetric = new MateAndAssistMetric(); + + afterEach(() => { + mateAndAssistMetric.clear(); + }); + + it('should not modify if game ends early', () => { + const moves = [ { originalString: 'e4', color: 'w', from: 'e2', to: 'e4', - piece: 'P', + piece: 'p', flags: 'b', }, { @@ -81,7 +91,7 @@ describe('All Tests', () => { color: 'w', from: 'g1', to: 'f3', - piece: 'N', + piece: 'n', flags: 'b', }, { @@ -92,21 +102,25 @@ describe('All Tests', () => { piece: 'n', flags: 'n', }, - ]; + ].map((move) => { + return { + move: move as any, // cast to match type checks in the processGame handler + board: [], + }; + }); - const gameHistoryMoves = gameHistoryToPgn(gameHistory); + // const result = getMateAndAssists(gameHistoryMoves); + mateAndAssistMetric.processGame(moves); - const result = getMateAndAssists(gameHistoryMoves); + const result = { ...mateAndAssistMetric.mateAndAssistMap }; + // clear results before comparing + mateAndAssistMetric.clear(); - expect(result).toEqual({ - matingPiece: undefined, - assistingPiece: undefined, - hockeyAssist: undefined, - }); + expect(result).toEqual(mateAndAssistMetric.mateAndAssistMap); }); it('should return the mating piece if there is a mate but no assist', () => { - const gameHistory: any[] = [ + const moves: any[] = [ { originalString: 'e4', color: 'w', @@ -114,6 +128,7 @@ describe('All Tests', () => { to: 'e4', piece: 'P', flags: 'b', + uas: 'PE', }, { originalString: 'e5', @@ -122,6 +137,7 @@ describe('All Tests', () => { to: 'e5', piece: 'p', flags: 'n', + uas: 'pe', }, { originalString: 'Qh5', @@ -138,6 +154,7 @@ describe('All Tests', () => { to: 'c6', piece: 'n', flags: 'n', + uas: 'ng', }, { originalString: 'Qxf7#', @@ -147,22 +164,26 @@ describe('All Tests', () => { piece: 'Q', captured: 'p', flags: 't', + uas: 'Q', }, - ]; - - const gameHistoryMoves = gameHistoryToPgn(gameHistory); + ].map((move) => { + return { + move: move as any, // cast to match type checks in the processGame handler + board: [], + }; + }); - const result = getMateAndAssists(gameHistoryMoves); + mateAndAssistMetric.processGame(moves); - expect(result).toEqual({ - matingPiece: 'Q', - assistingPiece: undefined, - hockeyAssist: undefined, + expect(mateAndAssistMetric.mateAndAssistMap['Q']).toEqual({ + mates: 1, + assists: 0, + hockeyAssists: 0, }); }); - it('should return the mating piece and assist if there is a mate with assist', () => { - const gameHistory: any[] = [ + it('should return the mating piece and not count the same piece as assisting', () => { + const moves: any[] = [ { originalString: 'e4', color: 'w', @@ -203,6 +224,7 @@ describe('All Tests', () => { piece: 'Q', captured: 'p', flags: 't', + uas: 'Q', }, { originalString: 'Kd8', @@ -211,6 +233,7 @@ describe('All Tests', () => { to: 'd8', piece: 'k', flags: 'n', + uas: 'k', }, { originalString: 'Qf8#', @@ -220,156 +243,64 @@ describe('All Tests', () => { piece: 'Q', captured: 'k', flags: 't', + uas: 'Q', }, - ]; - - const gameHistoryMoves = gameHistoryToPgn(gameHistory); - - const result = getMateAndAssists(gameHistoryMoves); - - expect(result).toEqual({ - matingPiece: 'Q', - assistingPiece: undefined, - hockeyAssist: undefined, + ].map((move) => { + return { + move: move as any, // cast to match type checks in the processGame handler + board: [], + }; }); - }); - // TODO: gen with copilot so the game may not be valid - it('should return just mating piece if the checks are all from the same piece', () => { - const gameHistory: any[] = [ - { - originalString: 'e4', - color: 'w', - from: 'e2', - to: 'e4', - piece: 'P', - flags: 'b', - }, - { - originalString: 'e5', - color: 'b', - from: 'e7', - to: 'e5', - piece: 'p', - flags: 'n', - }, - { - originalString: 'Qh5', - color: 'w', - from: 'd1', - to: 'h5', - piece: 'Q', - flags: 'b', - }, - { - originalString: 'Nc6', - color: 'b', - from: 'b8', - to: 'c6', - piece: 'n', - flags: 'n', - }, - { - originalString: 'Qxf7+', - color: 'w', - from: 'h5', - to: 'f7', - piece: 'Q', - captured: 'p', - flags: 't', - }, - { - originalString: 'Kd8', - color: 'b', - from: 'e8', - to: 'd8', - piece: 'k', - flags: 'n', - }, - { - originalString: 'Qf8+', - color: 'w', - from: 'f7', - to: 'f8', - piece: 'Q', - flags: 'n', - }, - { - originalString: 'Rg8', - color: 'b', - from: 'h8', - to: 'g8', - piece: 'R', - flags: 'n', - }, - { - originalString: 'Qg8#', // can capture and mate happen in same? How is it represented? - color: 'w', - from: 'f8', - to: 'g8', - piece: 'Q', - captured: 'R', - flags: 't', - }, - ]; - - const gameHistoryMoves = gameHistoryToPgn(gameHistory); - - const result = getMateAndAssists(gameHistoryMoves); + mateAndAssistMetric.processGame(moves); - expect(result).toEqual({ - matingPiece: 'Q', - assistingPiece: undefined, - hockeyAssist: undefined, + expect(mateAndAssistMetric.mateAndAssistMap['Q']).toEqual({ + mates: 1, + assists: 0, + hockeyAssists: 0, }); }); }); - xdescribe('getMoveDistanceSingleGame', () => { - xit('should return the correct max distance and piece for a game', async () => { + describe('getMoveDistanceSingleGame', () => { + const moveDistanceMetric = new MoveDistanceMetric(); + it('should return the correct max distance and piece for a game', async () => { const game = '1. e4 e5 2. Qh5 Nc6 3. Bc4 Nf6 4. Qxf7#'; - const result = await getMoveDistanceSingleGame({ - metadata: [], - moves: game, - }); + moveDistanceMetric.processGame(Array.from(cjsmin.historyGenerator(game))); - expect(result.maxDistancePiece).toEqual('Q'); - expect(result.maxDistance).toEqual(6); + expect(moveDistanceMetric.pieceMaxes.distance).toEqual(6); + expect(moveDistanceMetric.pieceMaxes.uasArray[0]).toEqual('Q'); }); - xit('should return 2 distance for a game with one move', async () => { + it('should return 2 distance for a game with one move', async () => { const game = '1. e4 e5'; - const result = await getMoveDistanceSingleGame({ - metadata: [], - moves: game, - }); + moveDistanceMetric.clear(); + moveDistanceMetric.processGame(Array.from(cjsmin.historyGenerator(game))); - expect(result.maxDistancePiece).toBe('PE'); - expect(result.maxDistance).toEqual(2); + expect(moveDistanceMetric.pieceMaxes.distance).toEqual(2); + expect(moveDistanceMetric.pieceMaxes.uasArray).toEqual(['PE', 'pe']); }); it('should return a singleGameDistanceTotal equal to the addition of all distances in the distanceMap', async () => { const game = '1. e4 e5 2. Qh5 Nc6 3. Bc4 Nf6 4. Qxf7#'; - const result = await getMoveDistanceSingleGame({ - metadata: [], - moves: game, - }); + moveDistanceMetric.processGame(Array.from(cjsmin.historyGenerator(game))); + moveDistanceMetric.aggregate(); let totalDistance = 0; - for (const distance of Object.keys(result.distanceMap)) { - totalDistance += result.distanceMap[distance]; + for (const uas of Object.keys(moveDistanceMetric.distanceMap)) { + totalDistance += moveDistanceMetric.distanceMap[uas].total; } - expect(result.singleGameDistanceTotal).toEqual(totalDistance); + expect(moveDistanceMetric.totalDistance).toEqual(totalDistance); }); }); // game being tested: https://www.chess.com/analysis/game/pgn/4uURW4rJaa?tab=analysis - xdescribe('getKillDeathRatios', () => { + describe('getKillDeathRatios', () => { // this could be a beforeAll const kdrMetric = new KDRatioMetric(); @@ -386,7 +317,10 @@ describe('All Tests', () => { '1. e4 e5 2. d4 exd4 3. Qxd4 Nc6 4. Qa4 Nf6 5. Nc3 d5 6. exd5 Qe7+ 7. Kd1 Bg4+ 8. Kd2 Nxd5 9. Nb5 Ncb4 10. c3 O-O-O 11. f3 Qe3+ 12. Kd1 Nxc3# 0-1', }, ]; - kdrMetric.processGame(Array.from(cjsmin.historyGenerator(game[0].moves))); + kdrMetric.processGame( + Array.from(cjsmin.historyGenerator(game[0].moves)), + ['m', 'et'] + ); expect(kdrMetric.KDAssistsMap['pe'].kills).toEqual(1); expect(kdrMetric.KDAssistsMap['pe'].deaths).toEqual(1); @@ -402,15 +336,18 @@ describe('All Tests', () => { }, ]; - kdrMetric.processGame(Array.from(cjsmin.historyGenerator(game[0].moves))); + kdrMetric.processGame( + Array.from(cjsmin.historyGenerator(game[0].moves)), + ['m', 'et'] + ); - console.log(kdrMetric.KDAssistsMap['ng'].kills); expect(kdrMetric.KDAssistsMap['ng'].kills).toEqual(3); }); }); - xdescribe('getMateAndAssists', () => { - it('should return the correct mating piece', () => { + describe('getGameWithMostMoves', () => { + const mostMovesMetric = new GameWithMostMovesMetric(); + it('should return the correct number of moves made', async () => { const game = [ { metadata: [], @@ -419,49 +356,198 @@ describe('All Tests', () => { }, ]; - const result = getMateAndAssists(game[0].moves); - - expect(result.matingPiece).toEqual('ng'); - // expect(result).toEqual({ - // matingPiece: '', - // assistingPiece: '', - // hockeyAssist: , - // unambigAssistingPiece: , - // unambigMatingPiece: , - // unambigHockeyAssist: , - // lastPieceMoved: - // }); + mostMovesMetric.processGame( + Array.from(cjsmin.historyGenerator(game[0].moves)), + ['m', '"et"'] + ); + + expect(mostMovesMetric.numMoves).toEqual(24); }); + }); - it.only('should return the correct mating piece', () => { - // game: https://lichess.org/jo73x9y8 - const game = [ + describe('PieceLevelMoveInfoMetric', () => { + const cjsmin = new Chess(); + + describe('processGame', () => { + let plmiMetric = new PieceLevelMoveInfoMetric(); + + beforeEach(() => { + plmiMetric.clear(); + }); + + it('should update totalMovesByPiece correctly', () => { + const game = + '1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 d6 8. c3 O-O 9. h3 Na5 10. Bc2 c5 11. d4 Qc7 12. Nbd2 Bd7 13. Nf1 Rfc8 14. d5 Nc4 15. b3 Nb6 16. Ng3 g6 17. Nh2 c4 18. b4 a5 19. f4 axb4 20. cxb4 exf4 21. Bxf4 Be8 22. Rf1 Nfd7 23. Ng4 h5 24. Nh6+ Kg7 25. Nxh5+ gxh5 26. Qxh5 f5 27. Nxf5+ Kf6 28. Bg5+ Ke5 29. Qh8+ Bf6 30. Bxf6+ Nxf6 31. Ng7 Qf7 32. Rf5+ Kd4 33. Ne6+ Kc3 34. Rf3+ Kxc2 35. Nd4+ Kb2 36. Rf2+ Kxa1 37. Qh6 c3 38. Qc1#'; + + plmiMetric.processGame(Array.from(cjsmin.historyGenerator(game)), [ + 'm', + '"et"', + ]); + + expect(plmiMetric.totalMovesByPiece['Q'].numMoves).toEqual(4); + expect(plmiMetric.totalMovesByPiece['K'].numMoves).toEqual(1); + // This last one is not manually verified + expect( + plmiMetric.totalMovesByPiece['RA'].numMoves + + plmiMetric.totalMovesByPiece['RH'].numMoves + ).toEqual(6); + }); + + it('should update singleGameMaxMoves correctly', () => { + const game1 = + '1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 d6 8. c3 O-O 9. h3 Na5 10. Bc2 c5 11. d4 Qc7 12. Nbd2 Bd7 13. Nf1 Rfc8 14. d5 Nc4 15. b3 Nb6 16. Ng3 g6 17. Nh2 c4 18. b4 a5 19. f4 axb4 20. cxb4 exf4 21. Bxf4 Be8 22. Rf1 Nfd7 23. Ng4 h5 24. Nh6+ Kg7 25. Nxh5+ gxh5 26. Qxh5 f5 27. Nxf5+ Kf6 28. Bg5+ Ke5 29. Qh8+ Bf6 30. Bxf6+ Nxf6 31. Ng7 Qf7 32. Rf5+ Kd4 33. Ne6+ Kc3 34. Rf3+ Kxc2 35. Nd4+ Kb2 36. Rf2+ Kxa1 37. Qh6 c3 38. Qc1#'; + const game2 = + '1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 d6 8. c3 O-O 9. h3 Na5 10. Bc2 c5 11. d4 Qc7 12. Nbd2 Bd7 13. Nf1 Rfc8 14. d5 Nc4 15. b3 Nb6 16. Ng3 g6 17. Nh2 c4 18. b4 a5 19. f4 axb4 20. cxb4 exf4 21. Bxf4 Be8 22. Rf1 Nfd7 23. Ng4 h5 24. Nh6+ Kg7 25. Nxh5+ gxh5 26. Qxh5 f5 27. Nxf5+ Kf6 28. Bg5+ Ke5 29. Qh8+ Bf6 30. Bxf6+ Nxf6 31. Ng7 Qf7 32. Rf5+ Kd4 33. Ne6+ Kc3 34. Rf3+ Kxc2 35. Nd4+ Kb2 36. Rf2+ Kxa1 37. Qh6 c3 38. Qc1#'; + + plmiMetric.processGame(Array.from(cjsmin.historyGenerator(game1)), [ + 'm', + '"et"', + ]); + plmiMetric.processGame(Array.from(cjsmin.historyGenerator(game2)), [ + 'm', + '"et"', + ]); + + expect(plmiMetric.singleGameMaxMoves).toEqual(9); + expect(plmiMetric.uasWithMostMoves).toEqual(['k']); + expect(plmiMetric.gamesWithMostMoves).toEqual(['et']); + }); + }); + + describe('aggregate', () => { + let metric = new PieceLevelMoveInfoMetric(); + + beforeEach(() => { + metric.clear(); + }); + + it('should return the correct averages', () => { + const game1 = + '1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 d6 8. c3 O-O 9. h3 Na5 10. Bc2 c5 11. d4 Qc7 12. Nbd2 Bd7 13. Nf1 Rfc8 14. d5 Nc4 15. b3 Nb6 16. Ng3 g6 17. Nh2 c4 18. b4 a5 19. f4 axb4 20. cxb4 exf4 21. Bxf4 Be8 22. Rf1 Nfd7 23. Ng4 h5 24. Nh6+ Kg7 25. Nxh5+ gxh5 26. Qxh5 f5 27. Nxf5+ Kf6 28. Bg5+ Ke5 29. Qh8+ Bf6 30. Bxf6+ Nxf6 31. Ng7 Qf7 32. Rf5+ Kd4 33. Ne6+ Kc3 34. Rf3+ Kxc2 35. Nd4+ Kb2 36. Rf2+ Kxa1 37. Qh6 c3 38. Qc1#'; + const game2 = + '1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 d6 8. c3 O-O 9. h3 Na5 10. Bc2 c5 11. d4 Qc7 12. Nbd2 Bd7 13. Nf1 Rfc8 14. d5 Nc4 15. b3 Nb6 16. Ng3 g6 17. Nh2 c4 18. b4 a5 19. f4 axb4 20. cxb4 exf4 21. Bxf4 Be8 22. Rf1 Nfd7 23. Ng4 h5 24. Nh6+ Kg7 25. Nxh5+ gxh5 26. Qxh5 f5 27. Nxf5+ Kf6 28. Bg5+ Ke5 29. Qh8+ Bf6 30. Bxf6+ Nxf6 31. Ng7 Qf7 32. Rf5+ Kd4 33. Ne6+ Kc3 34. Rf3+ Kxc2 35. Nd4+ Kb2 36. Rf2+ Kxa1 37. Qh6 c3 38. Qc1#'; + + metric.processGame(Array.from(cjsmin.historyGenerator(game1)), [ + 'a', + '"l"', + ]); + metric.processGame(Array.from(cjsmin.historyGenerator(game2)), [ + 'a', + '"p"', + ]); + + const averages = metric.aggregate(); + + expect(averages['Q'].avgMoves).toEqual(4); + expect(averages['K'].avgMoves).toEqual(1); + expect(averages['pa'].avgMoves).toEqual(3); + }); + }); + }); + + describe('PromotionMetric', () => { + const promotionMetric = new PromotionMetric(); + + afterEach(() => { + promotionMetric.clear(); + }); + + it('should update the promotion map when a promotion occurs', () => { + const moves = [ { - metadata: [], - moves: - '1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. c3 Bc5 5. cxd4 Nxd4 6. Nxd4 Bxd4 7. Qxd4 d6 8. Qxg7 Qf6 9. Qxf6 Nxf6 10. Bc4 Be6 11. Bxe6 fxe6 12. Nc3 O-O-O 13. O-O Kb8 14. Bg5 Rhf8 15. Rad1 Rd7 16. e5 dxe5 17. Bxf6 Rxd1 18. Rxd1 a6 19. Bxe5 b5 20. Rd7 b4 21. Na4 Kb7 22. Rxc7+ Kb8 23. Rxh7+ Kc8 24. Rc7+ Kd8 25. Rc6 Ke7 26. Rxa6 Rd8 27. Ra7+ Ke8 28. Kf1 Rd2 29. Ra8+ Kd7 30. Rb8 Rd5 31. Bg3 Ra5 32. b3 Rd5 33. Rb7+ Kc6 34. Rb6+ Kd7 35. Rd6+ Rxd6 36. Bxd6 Kxd6 37. Ke2 Kc6 38. Kd3 Kb5 39. Ke4 Kc6 40. h4 Kd7 41. g4 Ke7 42. h5 Kf7 43. Ke5 Kg7 44. f4 Kh6 45. Kxe6 Kg7 46. g5 Kh7 47. Kf6 Kh8 48. g6 Kg8 49. h6 Kh8 50. Kg5 Kg8 51. f5 Kh8 52. f6 Kg8 53. g7 Kh7 54. Kf5 Kg8 55. Ke6 Kh7 56. f7 Kg6 57. f8=Q Kh7 58. g8=Q# 1-0', + move: { + originalString: 'e8=Q', + color: 'b', + from: 'e7', + to: 'e8', + piece: 'p', + flags: 'p', + promotion: 'q', + uas: 'pe', + }, + board: [], }, - ]; + { + move: { + originalString: 'a2=a1', + color: 'w', + from: 'a2', + to: 'a1', + piece: 'p', + flags: 'p', + promotion: 'q', + uas: 'PA', + }, + }, + { + move: { + originalString: 'b7=b8', + color: 'b', + from: 'b7', + to: 'b8', + piece: 'p', + flags: 'p', + promotion: 'r', + uas: 'pb', + }, + }, + ].map((entry) => { + return { + move: entry.move as any, // cast to match type checks in the processGame handler + board: [], + }; + }); - const result = getMateAndAssists(game[0].moves); + promotionMetric.processGame(moves); - expect(result.unambigMatingPiece).toEqual('PG'); + expect(promotionMetric.promotionMap.pe.q).toEqual(1); + expect(promotionMetric.promotionMap.PA.q).toEqual(1); + expect(promotionMetric.promotionMap.pb.r).toEqual(1); }); - }); - xdescribe('getGameWithMostMoves', () => { - it('should return the correct number of moves made', async () => { - const game = [ + it('should not update the promotion map when a promotion does not occur', () => { + const moves = [ { - metadata: [], - moves: - '1. e4 e5 2. d4 exd4 3. Qxd4 Nc6 4. Qa4 Nf6 5. Nc3 d5 6. exd5 Qe7+ 7. Kd1 Bg4+ 8. Kd2 Nxd5 9. Nb5 Ncb4 10. c3 O-O-O 11. f3 Qe3+ 12. Kd1 Nxc3# 0-1', + move: { + originalString: 'e4', + color: 'w', + from: 'e2', + to: 'e4', + piece: 'p', + flags: 'b', + uas: 'PE', + }, }, - ]; + { + move: { + originalString: 'e5', + color: 'b', + from: 'e7', + to: 'e5', + piece: 'p', + flags: 'n', + uas: 'pe', + }, + }, + ].map((entry) => { + return { + move: entry.move as any, // cast to match type checks in the processGame handler + board: [], + }; + }); - const result = await getGameWithMostMoves(game); + promotionMetric.processGame(moves); + let promoTotal = 0; + + for (const k of Object.keys(promotionMetric.promotionMap)) { + for (const promoCount of Object.values( + promotionMetric.promotionMap[k] + )) { + promoTotal += promoCount as number; + } + } - expect(result.maxNumMoves).toEqual(24); + expect(promoTotal).toEqual(0); }); }); }); diff --git a/tests/queensidecastle.test.ts b/tests/queensidecastle.test.ts index 82af376..a0442e8 100644 --- a/tests/queensidecastle.test.ts +++ b/tests/queensidecastle.test.ts @@ -1,6 +1,6 @@ import { Chess } from '../cjsmin/src/chess'; -xdescribe('Queenside castling is detected', () => { +describe('Queenside castling is detected', () => { const chess = new Chess(); chess.loadPgn( '1. e4 e5 2. d4 exd4 3. Qxd4 Nc6 4. Qa4 Nf6 5. Nc3 d5 6. exd5 Qe7+ 7. Kd1 Bg4+ 8. Kd2 Nxd5 9. Nb5 Ncb4 10. c3 O-O-O 11. f3 Qe3+ 12. Kd1 Nxc3# 0-1' diff --git a/tests/shortPgn.test.ts b/tests/shortPgn.test.ts index 95a0689..ccc5c2f 100644 --- a/tests/shortPgn.test.ts +++ b/tests/shortPgn.test.ts @@ -1,6 +1,16 @@ -import { getHistoriesFromFilePath } from '../src/gameHistory'; +import { Chess } from '../cjsmin/src/chess'; +import { gameChunks } from '../src/fileReader'; -xdescribe('Using modified cjsmin returns expected results', () => { +async function* getHistoriesFromFilePath(path: string) { + const chess = new Chess(); + const gamesGenerator = gameChunks(path); + for await (const game of gamesGenerator) { + chess.loadPgn(game.moves); + yield chess.history(); + } +} + +describe('Using modified cjsmin returns expected results', () => { it('should not throw an error', async () => { const histShort = JSON.parse( require('fs').readFileSync('historiesShort.json').toString().trim() @@ -12,8 +22,6 @@ xdescribe('Using modified cjsmin returns expected results', () => { histories.push(history); } - // require('fs').writeFileSync('historiestst.json', JSON.stringify(histories)); - expect(histShort[0]).toEqual(histories[0]); });