├── .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 | --------------------------------------------------------------------------------