├── .gitattributes
├── .github
└── workflows
│ └── check_json_and_readme.yml
├── 2moves_v1.epd.zip
├── 2moves_v2.pgn.zip
├── 3moves_FRC.epd.zip
├── 4mvs_+90_+99.epd.zip
├── 6mvs_+90_+99.epd.zip
├── 8moves_v3.pgn.zip
├── 8mvs_+90_+99.epd.zip
├── 8mvs_big_+80_+109.epd.zip
├── DFRC_4852_v1.epd.zip
├── DFRC_openings.epd.zip
├── Drawkiller_balanced_big.epd.zip
├── FRC_openings.epd.zip
├── LICENSE
├── README.md
├── UHO_4060_v1.epd.zip
├── UHO_4060_v2.epd.zip
├── UHO_4060_v3.epd.zip
├── UHO_4060_v4.epd.zip
├── UHO_Lichess_4852_v1.epd.zip
├── UHO_MEGA_2022_+110_+149.pgn.zip
├── UHO_XXL_+0.80_+1.09.pgn.zip
├── UHO_XXL_+0.90_+1.19.pgn.zip
├── UHO_XXL_+1.00_+1.29.pgn.zip
├── UHO_XXL_2022_+100_+129.pgn.zip
├── UHO_XXL_2022_+110_+139.pgn.zip
├── UHO_XXL_2022_+120_+149.pgn.zip
├── bjbraams_chessdb_198350_lines.pgn.zip
├── books.json
├── closedpos.epd.zip
├── endgames.epd.zip
├── epd2pgn.py
├── hybrid_book_beta.epd.zip
├── noob_2moves.epd.zip
├── noob_3moves.epd.zip
├── noob_4moves.epd.zip
├── noob_5moves.epd.zip
├── pgn2epd.py
├── popularpos_lichess.epd.zip
├── popularpos_lichess_v2.epd.zip
├── popularpos_lichess_v3.epd.zip
├── stalemates_200d30_v1.epd.zip
├── startpos.epd.zip
├── update_json.py
└── update_readme.py
/.gitattributes:
--------------------------------------------------------------------------------
1 | # enforce end of line encoding is LF, needed for CI to run correctly
2 | * text=auto eol=lf
3 |
--------------------------------------------------------------------------------
/.github/workflows/check_json_and_readme.yml:
--------------------------------------------------------------------------------
1 | # This workflow will run update_json.py and update_readme.py on the PR
2 |
3 | name: check books.json and README.md
4 | on:
5 | push:
6 | branches:
7 | - master
8 | - github_ci
9 | pull_request:
10 | branches:
11 | - master
12 | jobs:
13 | check_json_and_readme:
14 | runs-on: ubuntu-24.04
15 | steps:
16 | - name: checkout repo
17 | uses: actions/checkout@v4
18 |
19 | - name: install deps
20 | run: pip install chess
21 |
22 | - name: run update_json.py
23 | run: rm -f books.json && python update_json.py
24 |
25 | - name: verify books.json
26 | run: |
27 | git diff --quiet --exit-code books.json || {
28 | git --no-pager diff --no-color books.json
29 | exit 1
30 | }
31 |
32 | - name: run update_readme.py
33 | run: python update_readme.py
34 |
35 | - name: verify README.md
36 | run: |
37 | git diff --quiet --exit-code README.md || {
38 | git --no-pager diff --no-color README.md
39 | exit 1
40 | }
41 |
--------------------------------------------------------------------------------
/2moves_v1.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/2moves_v1.epd.zip
--------------------------------------------------------------------------------
/2moves_v2.pgn.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/2moves_v2.pgn.zip
--------------------------------------------------------------------------------
/3moves_FRC.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/3moves_FRC.epd.zip
--------------------------------------------------------------------------------
/4mvs_+90_+99.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/4mvs_+90_+99.epd.zip
--------------------------------------------------------------------------------
/6mvs_+90_+99.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/6mvs_+90_+99.epd.zip
--------------------------------------------------------------------------------
/8moves_v3.pgn.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/8moves_v3.pgn.zip
--------------------------------------------------------------------------------
/8mvs_+90_+99.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/8mvs_+90_+99.epd.zip
--------------------------------------------------------------------------------
/8mvs_big_+80_+109.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/8mvs_big_+80_+109.epd.zip
--------------------------------------------------------------------------------
/DFRC_4852_v1.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/DFRC_4852_v1.epd.zip
--------------------------------------------------------------------------------
/DFRC_openings.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/DFRC_openings.epd.zip
--------------------------------------------------------------------------------
/Drawkiller_balanced_big.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/Drawkiller_balanced_big.epd.zip
--------------------------------------------------------------------------------
/FRC_openings.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/FRC_openings.epd.zip
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Creative Commons Legal Code
2 |
3 | CC0 1.0 Universal
4 |
5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
12 | HEREUNDER.
13 |
14 | Statement of Purpose
15 |
16 | The laws of most jurisdictions throughout the world automatically confer
17 | exclusive Copyright and Related Rights (defined below) upon the creator
18 | and subsequent owner(s) (each and all, an "owner") of an original work of
19 | authorship and/or a database (each, a "Work").
20 |
21 | Certain owners wish to permanently relinquish those rights to a Work for
22 | the purpose of contributing to a commons of creative, cultural and
23 | scientific works ("Commons") that the public can reliably and without fear
24 | of later claims of infringement build upon, modify, incorporate in other
25 | works, reuse and redistribute as freely as possible in any form whatsoever
26 | and for any purposes, including without limitation commercial purposes.
27 | These owners may contribute to the Commons to promote the ideal of a free
28 | culture and the further production of creative, cultural and scientific
29 | works, or to gain reputation or greater distribution for their Work in
30 | part through the use and efforts of others.
31 |
32 | For these and/or other purposes and motivations, and without any
33 | expectation of additional consideration or compensation, the person
34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she
35 | is an owner of Copyright and Related Rights in the Work, voluntarily
36 | elects to apply CC0 to the Work and publicly distribute the Work under its
37 | terms, with knowledge of his or her Copyright and Related Rights in the
38 | Work and the meaning and intended legal effect of CC0 on those rights.
39 |
40 | 1. Copyright and Related Rights. A Work made available under CC0 may be
41 | protected by copyright and related or neighboring rights ("Copyright and
42 | Related Rights"). Copyright and Related Rights include, but are not
43 | limited to, the following:
44 |
45 | i. the right to reproduce, adapt, distribute, perform, display,
46 | communicate, and translate a Work;
47 | ii. moral rights retained by the original author(s) and/or performer(s);
48 | iii. publicity and privacy rights pertaining to a person's image or
49 | likeness depicted in a Work;
50 | iv. rights protecting against unfair competition in regards to a Work,
51 | subject to the limitations in paragraph 4(a), below;
52 | v. rights protecting the extraction, dissemination, use and reuse of data
53 | in a Work;
54 | vi. database rights (such as those arising under Directive 96/9/EC of the
55 | European Parliament and of the Council of 11 March 1996 on the legal
56 | protection of databases, and under any national implementation
57 | thereof, including any amended or successor version of such
58 | directive); and
59 | vii. other similar, equivalent or corresponding rights throughout the
60 | world based on applicable law or treaty, and any national
61 | implementations thereof.
62 |
63 | 2. Waiver. To the greatest extent permitted by, but not in contravention
64 | of, applicable law, Affirmer hereby overtly, fully, permanently,
65 | irrevocably and unconditionally waives, abandons, and surrenders all of
66 | Affirmer's Copyright and Related Rights and associated claims and causes
67 | of action, whether now known or unknown (including existing as well as
68 | future claims and causes of action), in the Work (i) in all territories
69 | worldwide, (ii) for the maximum duration provided by applicable law or
70 | treaty (including future time extensions), (iii) in any current or future
71 | medium and for any number of copies, and (iv) for any purpose whatsoever,
72 | including without limitation commercial, advertising or promotional
73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
74 | member of the public at large and to the detriment of Affirmer's heirs and
75 | successors, fully intending that such Waiver shall not be subject to
76 | revocation, rescission, cancellation, termination, or any other legal or
77 | equitable action to disrupt the quiet enjoyment of the Work by the public
78 | as contemplated by Affirmer's express Statement of Purpose.
79 |
80 | 3. Public License Fallback. Should any part of the Waiver for any reason
81 | be judged legally invalid or ineffective under applicable law, then the
82 | Waiver shall be preserved to the maximum extent permitted taking into
83 | account Affirmer's express Statement of Purpose. In addition, to the
84 | extent the Waiver is so judged Affirmer hereby grants to each affected
85 | person a royalty-free, non transferable, non sublicensable, non exclusive,
86 | irrevocable and unconditional license to exercise Affirmer's Copyright and
87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the
88 | maximum duration provided by applicable law or treaty (including future
89 | time extensions), (iii) in any current or future medium and for any number
90 | of copies, and (iv) for any purpose whatsoever, including without
91 | limitation commercial, advertising or promotional purposes (the
92 | "License"). The License shall be deemed effective as of the date CC0 was
93 | applied by Affirmer to the Work. Should any part of the License for any
94 | reason be judged legally invalid or ineffective under applicable law, such
95 | partial invalidity or ineffectiveness shall not invalidate the remainder
96 | of the License, and in such case Affirmer hereby affirms that he or she
97 | will not (i) exercise any of his or her remaining Copyright and Related
98 | Rights in the Work or (ii) assert any associated claims and causes of
99 | action with respect to the Work, in either case contrary to Affirmer's
100 | express Statement of Purpose.
101 |
102 | 4. Limitations and Disclaimers.
103 |
104 | a. No trademark or patent rights held by Affirmer are waived, abandoned,
105 | surrendered, licensed or otherwise affected by this document.
106 | b. Affirmer offers the Work as-is and makes no representations or
107 | warranties of any kind concerning the Work, express, implied,
108 | statutory or otherwise, including without limitation warranties of
109 | title, merchantability, fitness for a particular purpose, non
110 | infringement, or the absence of latent or other defects, accuracy, or
111 | the present or absence of errors, whether or not discoverable, all to
112 | the greatest extent permissible under applicable law.
113 | c. Affirmer disclaims responsibility for clearing rights of other persons
114 | that may apply to the Work or any use thereof, including without
115 | limitation any person's Copyright and Related Rights in the Work.
116 | Further, Affirmer disclaims responsibility for obtaining any necessary
117 | consents, permissions or other rights required for any use of the
118 | Work.
119 | d. Affirmer understands and acknowledges that Creative Commons is not a
120 | party to this document and has no duty or obligation with respect to
121 | this CC0 or use of the Work.
122 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Books
2 |
3 | This repository contains a collection of books which may be used
4 | for chess engine development.
5 |
6 | ## Overview
7 |
8 | The following table gives a brief overview of the available books.
9 |
10 |
11 |
12 | | book | total | white | black | min_depth | max_depth |
13 | | :--- | ---: | ---: | ---: | ---: | ---: |
14 | | `2moves_v1.epd` | 40457 | 40457 | 0 | 4 | 4 |
15 | | `2moves_v2.pgn` | 12092 | 12092 | 0 | 4 | 4 |
16 | | `3moves_FRC.epd` | 126113 | 126113 | 0 | 6 | 6 |
17 | | `4mvs_+90_+99.epd` | 635 | 635 | 0 | 8 | 8 |
18 | | `6mvs_+90_+99.epd` | 2933 | 2933 | 0 | 12 | 12 |
19 | | `8moves_v3.pgn` | 34700 | 34700 | 0 | 16 | 16 |
20 | | `8mvs_+90_+99.epd` | 8533 | 8533 | 0 | 16 | 16 |
21 | | `8mvs_big_+80_+109.epd` | 25857 | 25857 | 0 | 16 | 16 |
22 | | `bjbraams_chessdb_198350_lines.pgn` | 198350 | 154148 | 44202 | 1 | 16 |
23 | | `closedpos.epd` | 165735 | 165735 | 0 | 8 | 8 |
24 | | `DFRC_4852_v1.epd` | 294466 | 160639 | 133827 | 0 | 3 |
25 | | `DFRC_openings.epd` | 921600 | 921600 | 0 | 0 | 0 |
26 | | `Drawkiller_balanced_big.epd` | 15962 | 15962 | 0 | 28 | 28 |
27 | | `endgames.epd` | 157846 | 74355 | 83491 | 23 | 652 |
28 | | `FRC_openings.epd` | 960 | 960 | 0 | 0 | 0 |
29 | | `hybrid_book_beta.epd` | 28054 | 28054 | 0 | None | None |
30 | | `noob_2moves.epd` | 7314 | 7314 | 0 | 4 | 4 |
31 | | `noob_3moves.epd` | 150932 | 150932 | 0 | 6 | 6 |
32 | | `noob_4moves.epd` | 1837365 | 1837365 | 0 | 8 | 8 |
33 | | `noob_5moves.epd` | 455287 | 455287 | 0 | 10 | 10 |
34 | | `popularpos_lichess.epd` | 200000 | 99953 | 100047 | None | None |
35 | | `popularpos_lichess_v2.epd` | 200000 | 100440 | 99560 | None | None |
36 | | `popularpos_lichess_v3.epd` | 200000 | 102952 | 97048 | None | None |
37 | | `stalemates_200d30_v1.epd` | 10796 | 7978 | 2818 | 12 | 479 |
38 | | `startpos.epd` | 1 | 1 | 0 | 0 | 0 |
39 | | `UHO_4060_v1.epd` | 246759 | 246759 | 0 | 16 | 16 |
40 | | `UHO_4060_v2.epd` | 242201 | 242201 | 0 | None | None |
41 | | `UHO_4060_v3.epd` | 242201 | 242201 | 0 | 16 | 16 |
42 | | `UHO_4060_v4.epd` | 241670 | 241670 | 0 | 16 | 16 |
43 | | `UHO_Lichess_4852_v1.epd` | 2632036 | 1457270 | 1174766 | 2 | 16 |
44 | | `UHO_MEGA_2022_+110_+149.pgn` | 321412 | 321412 | 0 | 16 | 16 |
45 | | `UHO_XXL_+0.80_+1.09.pgn` | 261028 | 261028 | 0 | 16 | 16 |
46 | | `UHO_XXL_+0.90_+1.19.pgn` | 223070 | 223070 | 0 | 16 | 16 |
47 | | `UHO_XXL_+1.00_+1.29.pgn` | 186098 | 186098 | 0 | 16 | 16 |
48 | | `UHO_XXL_2022_+100_+129.pgn` | 284035 | 284035 | 0 | 16 | 16 |
49 | | `UHO_XXL_2022_+110_+139.pgn` | 253847 | 253847 | 0 | 16 | 16 |
50 | | `UHO_XXL_2022_+120_+149.pgn` | 226629 | 226629 | 0 | 16 | 16 |
51 |
52 | *(Data sourced from [books.json](books.json).)*
53 |
54 |
--------------------------------------------------------------------------------
/UHO_4060_v1.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/UHO_4060_v1.epd.zip
--------------------------------------------------------------------------------
/UHO_4060_v2.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/UHO_4060_v2.epd.zip
--------------------------------------------------------------------------------
/UHO_4060_v3.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/UHO_4060_v3.epd.zip
--------------------------------------------------------------------------------
/UHO_4060_v4.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/UHO_4060_v4.epd.zip
--------------------------------------------------------------------------------
/UHO_Lichess_4852_v1.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/UHO_Lichess_4852_v1.epd.zip
--------------------------------------------------------------------------------
/UHO_MEGA_2022_+110_+149.pgn.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/UHO_MEGA_2022_+110_+149.pgn.zip
--------------------------------------------------------------------------------
/UHO_XXL_+0.80_+1.09.pgn.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/UHO_XXL_+0.80_+1.09.pgn.zip
--------------------------------------------------------------------------------
/UHO_XXL_+0.90_+1.19.pgn.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/UHO_XXL_+0.90_+1.19.pgn.zip
--------------------------------------------------------------------------------
/UHO_XXL_+1.00_+1.29.pgn.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/UHO_XXL_+1.00_+1.29.pgn.zip
--------------------------------------------------------------------------------
/UHO_XXL_2022_+100_+129.pgn.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/UHO_XXL_2022_+100_+129.pgn.zip
--------------------------------------------------------------------------------
/UHO_XXL_2022_+110_+139.pgn.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/UHO_XXL_2022_+110_+139.pgn.zip
--------------------------------------------------------------------------------
/UHO_XXL_2022_+120_+149.pgn.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/UHO_XXL_2022_+120_+149.pgn.zip
--------------------------------------------------------------------------------
/bjbraams_chessdb_198350_lines.pgn.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/bjbraams_chessdb_198350_lines.pgn.zip
--------------------------------------------------------------------------------
/books.json:
--------------------------------------------------------------------------------
1 | {
2 | "2moves_v1.epd": {
3 | "total": 40457,
4 | "white": 40457,
5 | "black": 0,
6 | "min_depth": 4,
7 | "max_depth": 4,
8 | "sri": "3KqrVhD252BCXrqwqVmFeYnLRp+ckuubLFo+9OFLic3iTuzrfV563rNMUB+vovpz"
9 | },
10 | "2moves_v2.pgn": {
11 | "total": 12092,
12 | "white": 12092,
13 | "black": 0,
14 | "min_depth": 4,
15 | "max_depth": 4,
16 | "sri": "uV7ni0IjOAJnufjffVXYdeRvWX8k6KHH9qdj1f4tq8qGu/yLiTkajlHNRNt/oqAm"
17 | },
18 | "3moves_FRC.epd": {
19 | "total": 126113,
20 | "white": 126113,
21 | "black": 0,
22 | "min_depth": 6,
23 | "max_depth": 6,
24 | "sri": "B2Xtc8K9x1JhiforTh/j2dXiChZ9prXlwfsUgXwVkBZxEKb18EipzUBDItGVPFYv"
25 | },
26 | "4mvs_+90_+99.epd": {
27 | "total": 635,
28 | "white": 635,
29 | "black": 0,
30 | "min_depth": 8,
31 | "max_depth": 8,
32 | "sri": "OrJ/nVsQciFTB0ozXshiXDDZ56WE5zKdr0cMsrSwhdT23MbiEqFNQ2xRm+v894Kp"
33 | },
34 | "6mvs_+90_+99.epd": {
35 | "total": 2933,
36 | "white": 2933,
37 | "black": 0,
38 | "min_depth": 12,
39 | "max_depth": 12,
40 | "sri": "fh8G9o6r6OJVONNxYBT1ZnGQevIhsV0LjdJPaa63pAtANYDPKbnd/K0ED2TVE6tt"
41 | },
42 | "8moves_v3.pgn": {
43 | "total": 34700,
44 | "white": 34700,
45 | "black": 0,
46 | "min_depth": 16,
47 | "max_depth": 16,
48 | "sri": "drf0LyW+HCqpwYvn3pE5+KHnG3WQofGC18vtRV1kjnQvrRu8rB+RUFN0NsGDAq1/"
49 | },
50 | "8mvs_+90_+99.epd": {
51 | "total": 8533,
52 | "white": 8533,
53 | "black": 0,
54 | "min_depth": 16,
55 | "max_depth": 16,
56 | "sri": "JAMC9KuG50fdNK2R+YV7SNKk+bpCyWA39NhLy+BGUo7GYXsGpJFF6Lr1dtSf+h15"
57 | },
58 | "8mvs_big_+80_+109.epd": {
59 | "total": 25857,
60 | "white": 25857,
61 | "black": 0,
62 | "min_depth": 16,
63 | "max_depth": 16,
64 | "sri": "isz6ubFj5Mo2PLlLLg+xtehW3+SF7/o6unHIHCzWHXx/vGgbFBOgtsa99+okvTzq"
65 | },
66 | "bjbraams_chessdb_198350_lines.pgn": {
67 | "total": 198350,
68 | "white": 154148,
69 | "black": 44202,
70 | "min_depth": 1,
71 | "max_depth": 16,
72 | "sri": "wU418kvxond2TCIPX9SPOPxtgowC3tA4Hi/y6zf+Injy4icrH24rzorG9Be6Usl4"
73 | },
74 | "closedpos.epd": {
75 | "total": 165735,
76 | "white": 165735,
77 | "black": 0,
78 | "min_depth": 8,
79 | "max_depth": 8,
80 | "sri": "Bgre8o2ye1/Qyf9YWsxRoen3wWYNZYtK7jcpfB2pmE7e1HFZXsoY6OCWbM+pKg83"
81 | },
82 | "DFRC_4852_v1.epd": {
83 | "total": 294466,
84 | "white": 160639,
85 | "black": 133827,
86 | "min_depth": 0,
87 | "max_depth": 3,
88 | "sri": "lVSTriuS/Pq2z5mz9YAkgluicHPzQh/B61AJKpmUS/9spQkcJ3MgfJXqtopdDfh1"
89 | },
90 | "DFRC_openings.epd": {
91 | "total": 921600,
92 | "white": 921600,
93 | "black": 0,
94 | "min_depth": 0,
95 | "max_depth": 0,
96 | "sri": "tVLdpACDZRpO04KeF4+HX0r3NiD8KP2bB1+FOlfj16/UZAKh4QxraFHBGqc74WAy"
97 | },
98 | "Drawkiller_balanced_big.epd": {
99 | "total": 15962,
100 | "white": 15962,
101 | "black": 0,
102 | "min_depth": 28,
103 | "max_depth": 28,
104 | "sri": "vgltOu0cfBCRBUt5E+Buk9P7E/n2LlEnwIOp8dG/q1DkJzgKH/mivWg1klt/ZmA7"
105 | },
106 | "endgames.epd": {
107 | "total": 157846,
108 | "white": 74355,
109 | "black": 83491,
110 | "min_depth": 23,
111 | "max_depth": 652,
112 | "sri": "nxIaD6KHWtRWCjwK1WS4FffBMilSTT3psxwNSNtW/zSMMlI1n/m6dximaniQGGe4"
113 | },
114 | "FRC_openings.epd": {
115 | "total": 960,
116 | "white": 960,
117 | "black": 0,
118 | "min_depth": 0,
119 | "max_depth": 0,
120 | "sri": "JVruRrMKePsACyfEBbKEKWnGcZjIXSfvE6MuQ58PFmGPK9sdtzWl6ZzADd5AkoLY"
121 | },
122 | "hybrid_book_beta.epd": {
123 | "total": 28054,
124 | "white": 28054,
125 | "black": 0,
126 | "min_depth": null,
127 | "max_depth": null,
128 | "sri": "BZKpMZvausaf1O0LXbcobG9RWdMXK0F/QQhRwiDpvZFgD3IuuqNRknZqC2FvgRsI"
129 | },
130 | "noob_2moves.epd": {
131 | "total": 7314,
132 | "white": 7314,
133 | "black": 0,
134 | "min_depth": 4,
135 | "max_depth": 4,
136 | "sri": "kmGmXQJVWl7dDWjxwaox1CJu9tWbszGuz5LkCYQKdC/CG7GEW1TEoYthgLCRX6bZ"
137 | },
138 | "noob_3moves.epd": {
139 | "total": 150932,
140 | "white": 150932,
141 | "black": 0,
142 | "min_depth": 6,
143 | "max_depth": 6,
144 | "sri": "FvfPX09TMPXct8CAIehuAZn16lLNP5Hn/tChtjz0sQ3bOh03OHi/r2LEosksvHKX"
145 | },
146 | "noob_4moves.epd": {
147 | "total": 1837365,
148 | "white": 1837365,
149 | "black": 0,
150 | "min_depth": 8,
151 | "max_depth": 8,
152 | "sri": "Ex11x6K37BVlHFyf25PapaGJYW7dC3RKfsE2mhKfg3YAEjGTcLCvpJwM0MRxuDgz"
153 | },
154 | "noob_5moves.epd": {
155 | "total": 455287,
156 | "white": 455287,
157 | "black": 0,
158 | "min_depth": 10,
159 | "max_depth": 10,
160 | "sri": "KkoVTUopFPmfODxE82lulQcA6Hs7yhLx/+Kd4oC3sn1gsxvVjKFfLeyWA186UAVN"
161 | },
162 | "popularpos_lichess.epd": {
163 | "total": 200000,
164 | "white": 99953,
165 | "black": 100047,
166 | "min_depth": null,
167 | "max_depth": null,
168 | "sri": "uPe5JnGDXHymQQnbv+1EHhD70JbioCJ/Sr5hdd5qp7JuMC5MOO+Ljd0ZzbVOzPHu"
169 | },
170 | "popularpos_lichess_v2.epd": {
171 | "total": 200000,
172 | "white": 100440,
173 | "black": 99560,
174 | "min_depth": null,
175 | "max_depth": null,
176 | "sri": "A/+NrdKvHD6rDeqlrTKq8JhTFYHYu2m9thvKkxppgCeAhdUeqL+mD71J71hWsqwl"
177 | },
178 | "popularpos_lichess_v3.epd": {
179 | "total": 200000,
180 | "white": 102952,
181 | "black": 97048,
182 | "min_depth": null,
183 | "max_depth": null,
184 | "sri": "GYBs7goZ8XzTWrGXHi1OpztbMKhBowWJuGhwoDqqVSj2DkwlljZMHOB80vzVBCNV"
185 | },
186 | "stalemates_200d30_v1.epd": {
187 | "total": 10796,
188 | "white": 7978,
189 | "black": 2818,
190 | "min_depth": 12,
191 | "max_depth": 479,
192 | "sri": "FRdKMTDCSEBRDY8Jyq9Wk8nQbFBFuLwnLFyoNqkfSxRLMFPdffXmOCPct7D9o6v3"
193 | },
194 | "startpos.epd": {
195 | "total": 1,
196 | "white": 1,
197 | "black": 0,
198 | "min_depth": 0,
199 | "max_depth": 0,
200 | "sri": "B0D/PN334ez5R9K8mGspR5ZjfXb0sWoEObBnkCI7sczqZbaOHQ5aooqk97zeHM0a"
201 | },
202 | "UHO_4060_v1.epd": {
203 | "total": 246759,
204 | "white": 246759,
205 | "black": 0,
206 | "min_depth": 16,
207 | "max_depth": 16,
208 | "sri": "nzjDniDroiL1rP002Iikz2Gk+7I8eRpSO22IeuInzn/1Q2LJlQz+30tseklGrJ6R"
209 | },
210 | "UHO_4060_v2.epd": {
211 | "total": 242201,
212 | "white": 242201,
213 | "black": 0,
214 | "min_depth": null,
215 | "max_depth": null,
216 | "sri": "SvrM+Qsc/tfh4HVnygjcg4ZvEUeIMPvDL1LonUelndE20PKn3Ea7m+ubnAQLMV4e"
217 | },
218 | "UHO_4060_v3.epd": {
219 | "total": 242201,
220 | "white": 242201,
221 | "black": 0,
222 | "min_depth": 16,
223 | "max_depth": 16,
224 | "sri": "ECbixK+Z71w0UNM69Eta9E8drT3tXtLPip4VuXxA6CZs5tYpAIT7J4j6a5Tvq2IZ"
225 | },
226 | "UHO_4060_v4.epd": {
227 | "total": 241670,
228 | "white": 241670,
229 | "black": 0,
230 | "min_depth": 16,
231 | "max_depth": 16,
232 | "sri": "MwywsnSV4YzSj5Q9DI2dUcPcRFMf4LtaOnj4igKRxcGxiSN2HdQPvq/M48kuqz+U"
233 | },
234 | "UHO_Lichess_4852_v1.epd": {
235 | "total": 2632036,
236 | "white": 1457270,
237 | "black": 1174766,
238 | "min_depth": 2,
239 | "max_depth": 16,
240 | "sri": "QHAU1P3LurcJr7UTRI7HZCVFsoYBWC3OTsBqZY/FfQA6VQo3MmECWtByB4gVACW5"
241 | },
242 | "UHO_MEGA_2022_+110_+149.pgn": {
243 | "total": 321412,
244 | "white": 321412,
245 | "black": 0,
246 | "min_depth": 16,
247 | "max_depth": 16,
248 | "sri": "dVMubbSulaPBZv9vmhh1a80fsCA9MLcN51XGqWFNW00Z+agLbYHhDQURBuUfhh9H"
249 | },
250 | "UHO_XXL_+0.80_+1.09.pgn": {
251 | "total": 261028,
252 | "white": 261028,
253 | "black": 0,
254 | "min_depth": 16,
255 | "max_depth": 16,
256 | "sri": "E9QyYfzbn/s03ueDeKq+poqBpLwwYY6g79R5JXtFj1FxUsYB5j1qNg3KTgqCdgqs"
257 | },
258 | "UHO_XXL_+0.90_+1.19.pgn": {
259 | "total": 223070,
260 | "white": 223070,
261 | "black": 0,
262 | "min_depth": 16,
263 | "max_depth": 16,
264 | "sri": "xnpY+GaWf/8UBpguZRTL6yimA4gixGGSlT/bT6Sg+Su/BD0Zz+SSYO9dAvfH59qc"
265 | },
266 | "UHO_XXL_+1.00_+1.29.pgn": {
267 | "total": 186098,
268 | "white": 186098,
269 | "black": 0,
270 | "min_depth": 16,
271 | "max_depth": 16,
272 | "sri": "hL7QVZcnVWTYtPEy3/ZV4Mtt5lHQfPO3NjPqSV1S8/wcS5p2zLFZ4c0sBK7RDmXJ"
273 | },
274 | "UHO_XXL_2022_+100_+129.pgn": {
275 | "total": 284035,
276 | "white": 284035,
277 | "black": 0,
278 | "min_depth": 16,
279 | "max_depth": 16,
280 | "sri": "Zm7JkVvV0w2fThQ1KqEHtW9A1Gep3H2Cy2lp4bYmBrQlg3b8Z1dNp5luI4rI4SdN"
281 | },
282 | "UHO_XXL_2022_+110_+139.pgn": {
283 | "total": 253847,
284 | "white": 253847,
285 | "black": 0,
286 | "min_depth": 16,
287 | "max_depth": 16,
288 | "sri": "ukD2bRPycwOniwdivzAGOx50DB4jEJsFSqHydxt0iXVZ7rfeLanHjEi4hpayqkLh"
289 | },
290 | "UHO_XXL_2022_+120_+149.pgn": {
291 | "total": 226629,
292 | "white": 226629,
293 | "black": 0,
294 | "min_depth": 16,
295 | "max_depth": 16,
296 | "sri": "Xpqvh2yrr5ynVHcrPn4PSl/WMVRE8G5UnRrcP1l6jsMtUUoPdo9xEPtzmOHiI6ga"
297 | }
298 | }
299 |
--------------------------------------------------------------------------------
/closedpos.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/closedpos.epd.zip
--------------------------------------------------------------------------------
/endgames.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/endgames.epd.zip
--------------------------------------------------------------------------------
/epd2pgn.py:
--------------------------------------------------------------------------------
1 | import chess, sys
2 |
3 |
4 | def epd_to_pgn(bookname):
5 | epds = set()
6 | duplicates = []
7 | pgnname = bookname.replace(".epd", ".pgn")
8 | with open(bookname) as epd, open(pgnname, "w") as pgn:
9 | for count, line in enumerate(epd):
10 | assert ";" not in line, "Expect FENs w/ or w/o move counters"
11 | fields = line.split()
12 | epd = " ".join(fields[:4])
13 | epd = chess.Board(epd).epd() # remove superfluous ep square
14 | if epd in epds:
15 | duplicates.append(count + 1)
16 | else:
17 | epds.add(epd)
18 | pgn.write('[FEN "' + line.strip() + '"]\n')
19 | pgn.write('[Result "*"]\n')
20 | pgn.write("\n")
21 | pgn.write("*\n\n")
22 |
23 | if duplicates:
24 | dstr = ",".join([str(g) for g in duplicates])
25 | print(f"Warning: The following FENs are a duplicate: {dstr}.")
26 |
27 | print(f"Wrote the converted book to {pgnname}.")
28 |
29 |
30 | if __name__ == "__main__":
31 | if len(sys.argv) == 2 and sys.argv[1].endswith(".epd"):
32 | epd_to_pgn(sys.argv[1])
33 | else:
34 | print(f"Usage: python {sys.argv[0]} ")
35 | print("\nConverts an .epd into a .pgn book, keeping the order intact.")
36 |
--------------------------------------------------------------------------------
/hybrid_book_beta.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/hybrid_book_beta.epd.zip
--------------------------------------------------------------------------------
/noob_2moves.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/noob_2moves.epd.zip
--------------------------------------------------------------------------------
/noob_3moves.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/noob_3moves.epd.zip
--------------------------------------------------------------------------------
/noob_4moves.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/noob_4moves.epd.zip
--------------------------------------------------------------------------------
/noob_5moves.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/noob_5moves.epd.zip
--------------------------------------------------------------------------------
/pgn2epd.py:
--------------------------------------------------------------------------------
1 | import chess, chess.pgn, sys
2 |
3 |
4 | def pgn_to_epd(bookname):
5 | epds = set()
6 | fens = []
7 | duplicates = []
8 | count = 0
9 | pgn = open(bookname)
10 | while True:
11 | game = chess.pgn.read_game(pgn)
12 | if game is None:
13 | break
14 | count += 1
15 | board = game.board()
16 | for move in game.mainline_moves():
17 | board.push(move)
18 | epd = board.epd() # ignore move counters when checking for duplicates
19 | if epd in epds:
20 | duplicates.append(count)
21 | else:
22 | epds.add(epd)
23 | fens.append(board.fen())
24 |
25 | if duplicates:
26 | dstr = ",".join([str(g) for g in duplicates])
27 | print(f"Warning: The following games lead to a duplicated exit: {dstr}.")
28 |
29 | epdname = bookname.replace(".pgn", ".epd")
30 | with open(epdname, "w") as f:
31 | for fen in fens:
32 | f.write(fen + "\n")
33 | print(f"Wrote the converted book to {epdname}.")
34 |
35 |
36 | if __name__ == "__main__":
37 | if len(sys.argv) == 2 and sys.argv[1].endswith(".pgn"):
38 | pgn_to_epd(sys.argv[1])
39 | else:
40 | print(f"Usage: python {sys.argv[0]} ")
41 | print("\nConverts a .pgn into an .epd book, keeping the order intact.")
42 |
--------------------------------------------------------------------------------
/popularpos_lichess.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/popularpos_lichess.epd.zip
--------------------------------------------------------------------------------
/popularpos_lichess_v2.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/popularpos_lichess_v2.epd.zip
--------------------------------------------------------------------------------
/popularpos_lichess_v3.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/popularpos_lichess_v3.epd.zip
--------------------------------------------------------------------------------
/stalemates_200d30_v1.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/stalemates_200d30_v1.epd.zip
--------------------------------------------------------------------------------
/startpos.epd.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/official-stockfish/books/bfd4ca203e6e2aa838d8208adc85def8e944b304/startpos.epd.zip
--------------------------------------------------------------------------------
/update_json.py:
--------------------------------------------------------------------------------
1 | import base64, chess, chess.pgn, hashlib, io, json, os, zipfile
2 |
3 | json_file = "books.json"
4 |
5 | """ Run 'python update_json.py' to update the meta data stored in books.json.
6 | Remove books.json if all the information should be recomputed from scratch.
7 | """
8 |
9 |
10 | def get_stats_and_sri(compressedbook, old_stats):
11 | content_bytes = None
12 | if compressedbook.endswith(".zip"):
13 | book, _, _ = compressedbook.rpartition(".zip")
14 | with zipfile.ZipFile(compressedbook) as zip_file:
15 | content_bytes = zip_file.read(book)
16 | if content_bytes is None:
17 | return book, {}
18 |
19 | sri = base64.b64encode(hashlib.sha384(content_bytes).digest()).decode("utf8")
20 |
21 | if book in old_stats and "sri" in old_stats[book] and old_stats[book]["sri"] == sri:
22 | return book, None # book is unchanged, no need to compute stats
23 |
24 | content = content_bytes.decode("utf-8", errors="ignore")
25 | white = black = 0
26 | min_depth = 2**16
27 | max_depth = -1
28 | if book.endswith(".epd"):
29 | lines = content.splitlines()
30 | total = len(lines)
31 |
32 | for line in lines:
33 | fields = line.split()
34 | if len(fields) > 1:
35 | if fields[1] == "w":
36 | white += 1
37 | elif fields[1] == "b":
38 | black += 1
39 | else:
40 | print("Error: Invalid FEN {line}")
41 | return book, {}
42 | if len(fields) > 5 and fields[5].isdigit():
43 | move = int(fields[5])
44 | ply = (move - 1) * 2 if fields[1] == "w" else (move - 1) * 2 + 1
45 | min_depth = min(min_depth, ply)
46 | max_depth = max(max_depth, ply)
47 | elif book.endswith(".pgn"):
48 | pgn_stream = io.StringIO(content)
49 | while True:
50 | game = chess.pgn.read_game(pgn_stream)
51 | if game is None:
52 | break
53 | ply = game.ply() + len(list(game.mainline_moves()))
54 | min_depth = min(min_depth, ply)
55 | max_depth = max(max_depth, ply)
56 | if ply % 2:
57 | black += 1
58 | else:
59 | white += 1
60 |
61 | if min_depth > max_depth:
62 | min_depth = max_depth = None
63 |
64 | return book, {
65 | "total": white + black,
66 | "white": white,
67 | "black": black,
68 | "min_depth": min_depth,
69 | "max_depth": max_depth,
70 | "sri": sri,
71 | }
72 |
73 |
74 | old_stats = {}
75 | if os.path.isfile(json_file):
76 | with open(json_file) as f:
77 | old_stats = json.load(f)
78 | print(f"Read in stats for {len(old_stats)} books from {json_file}.")
79 |
80 | new_stats = {}
81 | for filename in sorted(os.listdir(), key=str.lower):
82 | if (
83 | filename.endswith(".epd.zip") or filename.endswith(".pgn.zip")
84 | ) and os.path.isfile(filename):
85 | print(f"Processing {filename}", end="", flush=True)
86 | book, stats = get_stats_and_sri(filename, old_stats)
87 | if stats is not None:
88 | new_stats[book] = stats
89 | if "total" in stats:
90 | print(
91 | f", found {stats['total']} lines (w/b = {stats['white']}/{stats['black']})."
92 | )
93 | else:
94 | print("")
95 | else:
96 | new_stats[book] = old_stats[book]
97 | print(", book unchanged. Use old stats.")
98 |
99 |
100 | with open(json_file, "w") as f:
101 | json.dump(new_stats, f, indent=4)
102 | f.write("\n") # add missing newline character
103 |
104 | print(f"\nSaved results to {json_file}.")
105 |
--------------------------------------------------------------------------------
/update_readme.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 | json_file = "books.json"
4 | readme_file = "README.md"
5 |
6 | with open(json_file) as f:
7 | data = json.load(f)
8 |
9 | headers = ["book", "total", "white", "black", "min_depth", "max_depth"]
10 | header_md = "| " + " | ".join(headers) + " |"
11 | separator_md = "| :--- | " + " | ".join(["---:"] * (len(headers) - 1)) + " |"
12 |
13 | rows_md = []
14 | for book in data:
15 | row_values = ["`" + book + "`"]
16 | row_values += [str(data[book][h]) for h in headers if h != "book"]
17 | rows_md.append("| " + " | ".join(row_values) + " |")
18 |
19 | table_md = "\n".join([header_md, separator_md] + rows_md)
20 |
21 | with open(readme_file) as f:
22 | readme = f.read()
23 |
24 | start_marker = ""
25 | end_marker = ""
26 | source_line = f"*(Data sourced from [{json_file}]({json_file}).)*"
27 |
28 | if start_marker in readme and end_marker in readme:
29 | before_table = readme.split(start_marker)[0]
30 | after_table = readme.split(end_marker)[1]
31 | new_readme = f"{before_table}{start_marker}\n{table_md}\n\n{source_line}\n{end_marker}{after_table}"
32 | else:
33 | print(
34 | f"Warning: Markers {start_marker} and {end_marker} not found in {readme_file}."
35 | )
36 | exit(1)
37 |
38 | if new_readme != readme:
39 | with open(readme_file, "w") as f:
40 | f.write(new_readme)
41 | print(f"Successfully updated table in {readme_file}.")
42 | else:
43 | print(f"No changes needed.")
44 |
--------------------------------------------------------------------------------