├── .gitignore ├── Demo.rar ├── Demov1.00.rar ├── LICENSE ├── README.md ├── src ├── benchmark.cpp ├── bitboard.cpp ├── bitboard.h ├── bitcount.h ├── boardtype.h ├── book.cpp ├── book.h ├── endgame.cpp ├── endgame.h ├── evaluate.cpp ├── evaluate.h ├── main.cpp ├── material.cpp ├── material.h ├── misc.cpp ├── misc.h ├── movegen.cpp ├── movegen.h ├── movepick.cpp ├── movepick.h ├── notation.cpp ├── notation.h ├── pawns.cpp ├── pawns.h ├── platform.h ├── position.cpp ├── position.h ├── psqtab.h ├── rkiss.h ├── search.cpp ├── search.h ├── thread.cpp ├── thread.h ├── timeman.cpp ├── timeman.h ├── tt.cpp ├── tt.h ├── types.h ├── uci.cpp ├── ucioption.cpp └── ucioption.h └── vs2008 ├── Challenger.sln └── Challenger.vcproj /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | 6 | # Compiled Dynamic libraries 7 | *.so 8 | *.dylib 9 | 10 | # Compiled Static libraries 11 | *.lai 12 | *.la 13 | *.a 14 | -------------------------------------------------------------------------------- /Demo.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grefen/challenger/902e706b33a786796920ffe4c92612f5d3e34bf0/Demo.rar -------------------------------------------------------------------------------- /Demov1.00.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grefen/challenger/902e706b33a786796920ffe4c92612f5d3e34bf0/Demov1.00.rar -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | UCI Chinese chess engine 294 | Copyright (C) 2013 grefen 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | challenger 2 | ========== 3 | 4 | UCI Chinese chess engine 5 | 6 | 7 | Demov1.00.rar is a GUI for engine 8 | Challengerv1.00.exe is a engine; 9 | 10 | the engine strongth is more powerfull than me. 11 | the strongest open source chinese chess 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/benchmark.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grefen/challenger/902e706b33a786796920ffe4c92612f5d3e34bf0/src/benchmark.cpp -------------------------------------------------------------------------------- /src/bitboard.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grefen/challenger/902e706b33a786796920ffe4c92612f5d3e34bf0/src/bitboard.cpp -------------------------------------------------------------------------------- /src/bitboard.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grefen/challenger/902e706b33a786796920ffe4c92612f5d3e34bf0/src/bitboard.h -------------------------------------------------------------------------------- /src/bitcount.h: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chinese chess playing engine based on Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | 12 | Challenger is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #ifndef BITCOUNT_H_INCLUDED 22 | #define BITCOUNT_H_INCLUDED 23 | 24 | #include 25 | #include "types.h" 26 | 27 | enum BitCountType { 28 | CNT_90, 29 | }; 30 | 31 | 32 | 33 | /// popcount() counts the number of nonzero bits in a bitboard 34 | template inline int popcount(Bitboard); 35 | 36 | inline int popcount32(uint32_t b) 37 | { 38 | uint32_t v = uint32_t(b); 39 | v -= (v >> 1) & 0x55555555; // 0-2 in 2 bits 40 | v = ((v >> 2) & 0x33333333) + (v & 0x33333333); // 0-4 in 4 bits 41 | v = ((v >> 4) + v) & 0x0F0F0F0F; 42 | return (v * 0x01010101) >> 24; 43 | } 44 | 45 | template<> 46 | inline int popcount(Bitboard b) 47 | { 48 | return popcount32(b.low) + popcount32(b.mid) + popcount32(b.hight); 49 | } 50 | 51 | inline void test_bitcount() 52 | { 53 | Bitboard board(0x03,0x1,0xf); 54 | 55 | printf("%d",popcount(board)); 56 | } 57 | 58 | #endif // #ifndef BITCOUNT_H_INCLUDED 59 | -------------------------------------------------------------------------------- /src/boardtype.h: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chinese chess playing engine based on Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef BOARDTYPE_H_INCLUDED 21 | #define BOARDTYPE_H_INCLUDED 22 | 23 | #include "platform.h" 24 | #include "stdio.h" 25 | #include 26 | 27 | 28 | const uint32_t BIT_MASK = 0x03FFFFFF; 29 | 30 | // 96 bit board, 3 uint32 31 | struct bitboardtype 32 | { 33 | uint32_t low, mid, hight; 34 | 35 | bitboardtype():low(0),mid(0),hight(0) {}; 36 | bitboardtype(uint32_t a, uint32_t b, uint32_t c):low(a),mid(b),hight(c&BIT_MASK){}; 37 | bitboardtype(const bitboardtype& board){ low = board.low; mid = board.mid; hight = board.hight&BIT_MASK;}; 38 | 39 | bitboardtype& operator=(const bitboardtype& board) 40 | { 41 | low = board.low; 42 | mid = board.mid; 43 | hight = board.hight&BIT_MASK; 44 | return *this; 45 | } 46 | 47 | operator bool() const 48 | { 49 | return (low || mid || (hight&BIT_MASK)); 50 | } 51 | 52 | int operator ==(const bitboardtype &board) const 53 | { 54 | return low == board.low && mid == board.mid && hight == board.hight; 55 | } 56 | 57 | int operator !=(const bitboardtype &board) const 58 | { 59 | return low != board.low || mid != board.mid && hight != board.hight; 60 | } 61 | 62 | bitboardtype operator ~() const 63 | { 64 | return bitboardtype(~low, ~mid, ~hight); 65 | } 66 | 67 | bitboardtype operator &(const bitboardtype &board) const 68 | { 69 | return bitboardtype(low & board.low, mid & board.mid, hight & board.hight); 70 | } 71 | 72 | bitboardtype operator |(const bitboardtype &board) const 73 | { 74 | return bitboardtype(low | board.low, mid | board.mid, hight | board.hight); 75 | } 76 | 77 | bitboardtype operator ^(const bitboardtype &board) const 78 | { 79 | return bitboardtype(low ^ board.low, mid ^ board.mid, hight ^ board.hight); 80 | } 81 | 82 | bitboardtype &operator &=(const bitboardtype &board) 83 | { 84 | low &= board.low; 85 | mid &= board.mid; 86 | hight &= board.hight&BIT_MASK; 87 | return *this; 88 | } 89 | 90 | bitboardtype &operator |=(const bitboardtype &board) 91 | { 92 | low |= board.low; 93 | mid |= board.mid; 94 | hight |= board.hight; 95 | hight &= BIT_MASK; 96 | return *this; 97 | } 98 | 99 | bitboardtype &operator ^=(const bitboardtype &board) 100 | { 101 | low ^= board.low; 102 | mid ^= board.mid; 103 | hight ^= board.hight; 104 | hight &= BIT_MASK;//if not, will affect shift 105 | return *this; 106 | } 107 | 108 | // Shift Operations 109 | bitboardtype operator <<(int bit) 110 | { 111 | if (bit < 0) 112 | return *this >> -bit; 113 | else if (bit == 0) 114 | return *this; 115 | else if (bit < 32) 116 | return bitboardtype(low << bit, mid << bit | low >> (32 - bit), hight << bit | mid >> (32 - bit)); 117 | else if (bit == 32) 118 | return bitboardtype(0, low, mid); 119 | else if (bit < 64) 120 | return bitboardtype(0, low << (bit - 32), mid << (bit - 32) | low >> (64 - bit)); 121 | else if (bit == 64) 122 | return bitboardtype(0, 0, low); 123 | else if (bit < 96) 124 | return bitboardtype(0, 0, low << (bit - 64)); 125 | else 126 | return bitboardtype(0, 0, 0); 127 | } 128 | 129 | bitboardtype operator >>(int bit) 130 | { 131 | hight &= BIT_MASK; 132 | if (bit < 0) 133 | return *this << -bit; 134 | else if (bit == 0) 135 | return *this; 136 | else if (bit < 32) 137 | return bitboardtype(low >> bit | mid << (32 - bit), mid >> bit | hight << (32 - bit), hight >> bit); 138 | else if (bit == 32) 139 | return bitboardtype(mid, hight, 0); 140 | else if (bit < 64) 141 | return bitboardtype(mid >> (bit - 32) | hight << (64 - bit), hight >> (bit - 32), 0); 142 | else if (bit == 64) 143 | return bitboardtype(hight, 0, 0); 144 | else if (bit < 96) 145 | return bitboardtype(hight >> (bit - 64), 0, 0); 146 | else 147 | return bitboardtype(0, 0, 0); 148 | } 149 | 150 | bitboardtype &operator <<=(int bit) 151 | { 152 | if (bit < 0) 153 | { 154 | *this >>= -bit; 155 | } 156 | else if (bit == 0) 157 | { 158 | } 159 | else if (bit < 32) 160 | { 161 | hight <<= bit; 162 | hight |= mid >> (32 - bit); 163 | mid <<= bit; 164 | mid |= low >> (32 - bit); 165 | low <<= bit; 166 | } 167 | else if (bit == 32) 168 | { 169 | hight = mid; 170 | mid = low; 171 | low = 0; 172 | } 173 | else if (bit < 64) 174 | { 175 | hight = mid << (bit - 32); 176 | hight |= low >> (64 - bit); 177 | mid = low << (bit - 32); 178 | low = 0; 179 | } 180 | else if (bit == 64) 181 | { 182 | hight = low; 183 | mid = 0; 184 | low = 0; 185 | } 186 | else if (bit < 96) 187 | { 188 | hight = low << (bit - 64); 189 | mid = 0; 190 | low = 0; 191 | } 192 | else 193 | { 194 | hight = 0; 195 | mid = 0; 196 | low = 0; 197 | } 198 | 199 | hight &= BIT_MASK; 200 | return *this; 201 | } 202 | 203 | bitboardtype &operator >>=(int bit) 204 | { 205 | hight &= BIT_MASK; 206 | if (bit < 0) 207 | { 208 | *this <<= -bit; 209 | } 210 | else if (bit == 0) 211 | { 212 | } 213 | else if (bit < 32) 214 | { 215 | low >>= bit; 216 | low |= mid << (32 - bit); 217 | mid >>= bit; 218 | mid |= hight << (32 - bit); 219 | hight >>= bit; 220 | } 221 | else if (bit == 32) 222 | { 223 | low = mid; 224 | mid = hight; 225 | hight = 0; 226 | } 227 | else if (bit < 64) 228 | { 229 | low = mid >> (bit - 32); 230 | low |= hight << (64 - bit); 231 | mid = hight >> (bit - 32); 232 | hight = 0; 233 | } 234 | else if (bit == 64) 235 | { 236 | low = hight; 237 | mid = 0; 238 | hight = 0; 239 | } 240 | else if (bit < 96) 241 | { 242 | low = hight >> (bit - 64); 243 | mid = 0; 244 | hight = 0; 245 | } 246 | else 247 | { 248 | low = 0; 249 | mid = 0; 250 | hight = 0; 251 | } 252 | return *this; 253 | } 254 | 255 | // b - 1 256 | bitboardtype operator-(uint32_t n) 257 | { 258 | if(low >= n) 259 | { 260 | return bitboardtype(low - n, mid, hight); 261 | } 262 | else if(mid > 0) 263 | { 264 | return bitboardtype(0xffffffff,mid - 1, hight); 265 | } 266 | else if(hight > 0) 267 | { 268 | return bitboardtype(0xffffffff, 0xffffffff, hight - 1); 269 | } 270 | return bitboardtype(0, 0, 0); 271 | } 272 | 273 | // debug 274 | void print() 275 | { 276 | int shift[10] = {0,9,18,27,36,45,54,63,72,81}; 277 | 278 | printf("\n"); 279 | 280 | bitboardtype one(0x1,0,0); 281 | for(int i = 0 ; i< 10; ++i) 282 | { 283 | bitboardtype t = (*this)>>shift[9-i]; 284 | for(int j = 0; j < 9; ++j) 285 | { 286 | printf("%d",(t&(one<>shift[8-i]; 303 | for(int j = 0; j < 10; ++j) 304 | { 305 | printf("%d",(t&(one<>shift[9-i]; 322 | for(int j = 0; j < 9; ++j) 323 | { 324 | printf("%d",(t&(one<>90; 331 | for(int i = 0; i < 6; ++i) 332 | { 333 | printf("%d",(t&(one<>1; b.printall(); 375 | 376 | //b <<= 1; b.printall(); 377 | //b >>= 1; b.printall(); 378 | 379 | //b = b.operator-(1); b.printall(); 380 | 381 | //bitboardtype b(0x1,0,0); 382 | for(int i = 0 ; i < 6; i++) 383 | { 384 | //bitboardtype t = b<>i; 386 | //t.printall(); 387 | } 388 | } 389 | 390 | 391 | } 392 | #endif -------------------------------------------------------------------------------- /src/book.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | /* 21 | The code in this file is based on the opening book code in PolyGlot 22 | by Fabien Letouzey. PolyGlot is available under the GNU General 23 | Public License, and can be downloaded from http://wbec-ridderkerk.nl 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | #include "book.h" 31 | #include "misc.h" 32 | #include "movegen.h" 33 | 34 | using namespace std; 35 | 36 | namespace { 37 | 38 | // A Polyglot book is a series of "entries" of 16 bytes. All integers are 39 | // stored in big-endian format, with highest byte first (regardless of size). 40 | // The entries are ordered according to the key in ascending order. 41 | struct Entry { 42 | uint64_t key; 43 | uint16_t move; 44 | uint16_t count; 45 | uint32_t learn; 46 | }; 47 | 48 | // Random numbers from PolyGlot, used to compute book hash keys 49 | const union { 50 | Key PolyGlotRandoms[1351];//13*60+1//15*90 + 1 51 | struct { 52 | Key psq[14][90]; // [piece][square] 53 | 54 | Key turn; 55 | } Zobrist; 56 | } PG = {{ 57 | 0x5D82CA6A2C19BCB3ULL, 0xA0F7F3FBFEF39367ULL, 0x6E125B00A0CD5A0FULL, 58 | 0x1A1211C285AD06CAULL, 0x8E716BAA5250A383ULL, 0x968C5F3F59EA14EFULL, 59 | 0xA8A7E1C2D3C62243ULL, 0xDD5DA4A13FFC75D2ULL, 0xABCD17B317EBB2C4ULL, 60 | 0x424B38B414F844C7ULL, 0xCD99BD64E66A10C6ULL, 0x3B729A6E28A0210BULL, 61 | 0xA6CCC0A7F1EEBF7FULL, 0x6F839E2A1BFFFC2BULL, 0xDEEAEBD8AAF454F8ULL, 62 | 0x4ED3CAFE4BEB8389ULL, 0x6C6D8ED70CD2D066ULL, 0x8FD8AE140D2CC250ULL, 63 | 0x308FBDFBD2AFB7E7ULL, 0x33576218DD56C075ULL, 0x5171280162E17EBAULL, 64 | 0x4E947438630609A1ULL, 0xEBD616652CB8D83DULL, 0xB4758490436DAADEULL, 65 | 0xA2F063C373134A59ULL, 0x8D8CDFBC7089118CULL, 0x568B80169B698384ULL, 66 | 0xC327B8BE1FC3DA79ULL, 0x3E375B382AB4EDABULL, 0x4D428E815637210FULL, 67 | 0x388132074DBE86C4ULL, 0x194E987F7A70DF2DULL, 0xDAFE23A05E92561FULL, 68 | 0xDA7D12494C665560ULL, 0x7542E1EEBE8CCFAEULL, 0x7059230D036CFC82ULL, 69 | 0xE6D25C349158E5EBULL, 0xD33728D4E801D5DFULL, 0xCBFC1EA9651BE951ULL, 70 | 0x7BB52643E7253216ULL, 0x7E54E0FFBDCE5106ULL, 0x42BBC867E8ADC8C4ULL, 71 | 0x4C2A98D5A853ACF7ULL, 0x96C9ED0EEA342C99ULL, 0x1D138D434AD619FFULL, 72 | 0xB61EA560CD203BA8ULL, 0x7509E0169AD81006ULL, 0x243B39FAD286B40BULL, 73 | 0x31F5B2AADDAF575EULL, 0xC0AD8AB9897986E9ULL, 0x2BC5BCB08C3169E5ULL, 74 | 0x61B6C583605C81FBULL, 0xEE9D826F99294102ULL, 0x3F28B559C86F0275ULL, 75 | 0x02D3812BC94FDE08ULL, 0x51E706751871C8FEULL, 0x2EF1BAEB93BAE27AULL, 76 | 0xD3E075CFD449BB1EULL, 0xA23F7E2075FC0663ULL, 0x87E7FBECA8338670ULL, 77 | 0x76294E6BD7BD1704ULL, 0x6F3744792F5FF73EULL, 0x7CE1998CBF4D202BULL, 78 | 0xDEC84ECB89205640ULL, 0xE3D4D3FD47C5301CULL, 0xD32EBF8566811589ULL, 79 | 0x3E262A8FD5D9AB0BULL, 0x33243FAAEE0EBAF4ULL, 0x5617B0BE86CB43BFULL, 80 | 0xBF48BE23BF14387AULL, 0xC39064ABAA92D1D1ULL, 0xA3DEF306E12DFBBFULL, 81 | 0x82C35E0ACD76BF5AULL, 0x17BF62F08FAE6AE7ULL, 0x0C387A540CC1F50AULL, 82 | 0x218F3C999D6597F0ULL, 0xDD41A0F54F05FA22ULL, 0x20DF74AB28E31128ULL, 83 | 0xCBB346498F03DDCDULL, 0xE51A6EDCC0923AD5ULL, 0x6FBE08D4AE0A1563ULL, 84 | 0x108190CFFC6F9D39ULL, 0x8E2CD05D1B486946ULL, 0xDBF9E17010FD02E7ULL, 85 | 0xA6031D2BD4E58206ULL, 0xB14210DEA726746DULL, 0x1B09EBE5B4CE852AULL, 86 | 0x2F49FFF15935B41FULL, 0x457D4418B2F78026ULL, 0x27028B6CBEF5814CULL, 87 | 0x80214F58611CAAE7ULL, 0x1135F6434E2902AEULL, 0xB70C655FF69348FEULL, 88 | 0xA2E3F59F36FCF339ULL, 0x9B8337AD27184981ULL, 0x8AA140A505E6A3FBULL, 89 | 0x2CAE82EF9465001FULL, 0x42C53661A515D15FULL, 0xF5C376BB0ABA165EULL, 90 | 0xC9594CF8F2392E7BULL, 0x8328692BC6DD9746ULL, 0x6E4C5DCCFAA81A39ULL, 91 | 0xBAFA39EC06204CE6ULL, 0xF2F28DE00E07F8D1ULL, 0xBDE1F9B7A6330ED0ULL, 92 | 0x694D4A5390DDECA7ULL, 0xA463340CD911F56EULL, 0x36BEE5B851ACF98FULL, 93 | 0x81B6C35577E44FC5ULL, 0x25A01BBF739E3C4BULL, 0xE9CCCBD3300B5E07ULL, 94 | 0xCEEB14D716F492E3ULL, 0xDC042D484A1234B2ULL, 0x3AD76828F74C908EULL, 95 | 0x8B4534023AD91EBDULL, 0x50422076C938252FULL, 0xA929FC40CBD94D58ULL, 96 | 0xCD630ECDC5C3B218ULL, 0xC52C2B418FC4C11DULL, 0x1BD7BE722F6A1861ULL, 97 | 0x58B850414270712BULL, 0xF803AD36F40E730AULL, 0xA9C11BB5F1863145ULL, 98 | 0x3388EB57B6677C69ULL, 0xD33C53CB30F1C1DAULL, 0x95BACDC94B45709FULL, 99 | 0xD21074367CD740D5ULL, 0x770CA513C7A4B558ULL, 0x0C651A1F22AF3373ULL, 100 | 0xFF12042F0FED0E7AULL, 0x0318CEF63DE0C67FULL, 0x71E9453C13B78A37ULL, 101 | 0xDDDC9BB377445C67ULL, 0xC436545C13992318ULL, 0x974D3F50530C44C8ULL, 102 | 0xD47A10BB6C182714ULL, 0x3390F011B15DD250ULL, 0xC042FFD27E087455ULL, 103 | 0xC4004F434933B5BDULL, 0xF10E5CACE7EFCF6BULL, 0x0533D44CF58022D8ULL, 104 | 0xC5DE186CE0A2C04AULL, 0xA6E4C2F1EEDF1CCEULL, 0x651133694A59DD35ULL, 105 | 0xB6C3CEF926AAF2E0ULL, 0x504B679B9800F058ULL, 0xCC9577FE4BE77AE4ULL, 106 | 0x21283B78703B623EULL, 0x6F5D0CAF94A1D6C8ULL, 0x2029B24B5B16F67BULL, 107 | 0xCD77EE5BC39BC2D1ULL, 0x504756D5C7E5FDC0ULL, 0xC5B829C492A5EA56ULL, 108 | 0x3E39160A72C61709ULL, 0xACD2F3ED8C7BB30CULL, 0x3F1F716FCA036A2EULL, 109 | 0xB8893848367CE5BFULL, 0x74B9E561376D337DULL, 0x22F33A25664EE05DULL, 110 | 0x6954257C0413AFADULL, 0x9CF4A0052E21DEC5ULL, 0x390A9635000D6CD4ULL, 111 | 0xF31A03B87BD0064CULL, 0xBA298FC9B6C2BFE6ULL, 0xD8CB9D0DD8C8BE1FULL, 112 | 0x884E5B00A85D2449ULL, 0xE2EC5230B3079489ULL, 0xCDE281A2135B7B18ULL, 113 | 0x81EE6675FCC2E715ULL, 0xAB2885084203D2F5ULL, 0xFF04919BEE40AB8BULL, 114 | 0x82670F42E4ACFE41ULL, 0xF9EDD063AA3FB369ULL, 0xC8CDEF1A7BE618E9ULL, 115 | 0xA8DBD192BFC98B5BULL, 0x8995BC144F86DD61ULL, 0xC4234AC269FB05C0ULL, 116 | 0xADD7C4DA989C68F9ULL, 0xAEA5E6383D96055CULL, 0x3337175264B94B39ULL, 117 | 0x7A042CDC9E504226ULL, 0x73FBA8185B7E3925ULL, 0x27000FDD046EF600ULL, 118 | 0x7F51B6A279E17BFCULL, 0x4E4557C787B76A5EULL, 0x0D834EB3268D5E26ULL, 119 | 0xC9DEA83640A90E38ULL, 0x0D17E5F0C4C93C78ULL, 0x8342E2B899B2CDB8ULL, 120 | 0x83D605BB47557798ULL, 0x7CB8116EC8ADA475ULL, 0xAA241C70CF12993CULL, 121 | 0x2B795712666B1E4BULL, 0x5DC9B4C93D76E4C9ULL, 0xBA822D56F73EB32CULL, 122 | 0x94FF300897984482ULL, 0x497FA4BD32C16CB4ULL, 0xBCB13B2FDA17EB01ULL, 123 | 0x6BC9C2B9413C1619ULL, 0x12117662B0BF333FULL, 0x83AAED30AA9F3B53ULL, 124 | 0x9D83B2DB437E0081ULL, 0xC41966424624E36BULL, 0x57CA72404EB4F105ULL, 125 | 0x00F1AC92ACD5D2D8ULL, 0x5802DE97953BFBBAULL, 0xD5B0443199CFE196ULL, 126 | 0xF5F0B2973DA3AEE5ULL, 0xD0AF811D366DEC0AULL, 0x17B99CC7BEC69F23ULL, 127 | 0x7B2A9685DDDC526EULL, 0xC40429A9D73D4BB2ULL, 0x347BF5D70AF7FF28ULL, 128 | 0x20651B1992F31AADULL, 0x8448B109716CD3F4ULL, 0x6BC1DCD8CE593451ULL, 129 | 0xC151C4AA88FA8F4DULL, 0xBB520847AF34B73AULL, 0x7B61F4AC696A7350ULL, 130 | 0xE22FD72D8A1DFF86ULL, 0x080A4D49D4C44881ULL, 0x2D57F2198D4E3D32ULL, 131 | 0x54545A2F1CE65168ULL, 0xBEE398ED55401431ULL, 0x8E9D324AF93A6466ULL, 132 | 0xB1905EC59F072044ULL, 0xDA401C8DA18153B4ULL, 0xCF563F98A4D10219ULL, 133 | 0x1DDE517FF61E6DC9ULL, 0x721C93D5835CC5B0ULL, 0x3DBECBF43DDB0CA6ULL, 134 | 0x781876ADD402773AULL, 0x0A9487E2285FFC1EULL, 0x01200D8106C008CCULL, 135 | 0xCC9C5845414D3503ULL, 0x228589B19E337377ULL, 0x6DAA66CF2CFE4507ULL, 136 | 0xF1EBD1B6281D5995ULL, 0x7E86EEBD75ABD873ULL, 0xFABEE62C26AB4165ULL, 137 | 0xE3DA53529C926F86ULL, 0x319CF420C08AC92AULL, 0x78C122F61653DCD6ULL, 138 | 0xD6E1F60FFE91D63EULL, 0xF403996E5E21718CULL, 0x3C9D8623154DEF66ULL, 139 | 0x6246AB82A37BA36EULL, 0x8F245F8AC6F3181BULL, 0x476F8209CD22B1C9ULL, 140 | 0x24CDA63D091D1FB4ULL, 0x314B87A6407B7C47ULL, 0xFD4F624D7CCE50D8ULL, 141 | 0x77152EF27558F188ULL, 0x093945CA4F61C0FBULL, 0x3CAF7670D5ED1619ULL, 142 | 0xEFD9BF9FC09F3681ULL, 0xD09873AD2D13AC96ULL, 0xBD81F4E43E02CDCEULL, 143 | 0x8F89F63059B9696BULL, 0x62949CC50B9E3929ULL, 0x902C18D15595E338ULL, 144 | 0x14AC1AA6E89B07DFULL, 0x01A56ACE73C3720FULL, 0x435461C626D76AEDULL, 145 | 0x6AC3A252AC7477C1ULL, 0x6D6AA50D224728A3ULL, 0x6CC3D235BE4D343EULL, 146 | 0x73FB14BD66722CD8ULL, 0xFADA63F8BCF4BAE3ULL, 0xC4E113B20745D197ULL, 147 | 0x2DDBD645F2D8A45DULL, 0x66078CFC76973C9EULL, 0x4B88DFFB9C0426DFULL, 148 | 0xAF9E50537DDC4663ULL, 0x257AF35834F4F4CCULL, 0x3ADBC1DEF03D13BFULL, 149 | 0x8EC4A3EE8E66A815ULL, 0xA0D14DFABCDD9F91ULL, 0x9CA5F2173F647B03ULL, 150 | 0xCFC73A8349434DFEULL, 0x8B595C36BDA98837ULL, 0x8163522A1573EFD3ULL, 151 | 0x6411D4C7C4C4E285ULL, 0x436224AE7C384C4BULL, 0xDD2BA267C9BD822EULL, 152 | 0x34A3341415E9A7DFULL, 0xFF5F1DC90C8E2042ULL, 0x96A26583ABF0F210ULL, 153 | 0x1B4BB6B1FC8F8ABAULL, 0xD5A6543CEBDCC629ULL, 0xF7E1C2E766319353ULL, 154 | 0x9D3C89ABD26D9771ULL, 0x0A8FE41381B17881ULL, 0x50DF029FDB1926AEULL, 155 | 0x833E808B936D11B8ULL, 0x9A773388ADE18890ULL, 0x11ADC35BF018B6EEULL, 156 | 0x052C84692E1630F9ULL, 0x52259E49B8D53DE7ULL, 0x973080BCEEAC3E2CULL, 157 | 0xFC4460CE8C90F283ULL, 0x3DEFF1E4E28219CCULL, 0x40278025484E580DULL, 158 | 0x7BF59C7D9B4B271CULL, 0x3AF91A454B80AC9CULL, 0x868F42FD8EA386B8ULL, 159 | 0x8DDD78A59AE4F152ULL, 0x03952E6A7525276BULL, 0x813729446A970F50ULL, 160 | 0xB1839B5D831501C4ULL, 0x7A0823BB59E00B53ULL, 0x067DAF0A9AA4D12AULL, 161 | 0x5A7B0BB2A2AFF85BULL, 0x3A4BDC98D1B38CF9ULL, 0x39856B0241770338ULL, 162 | 0x6B739D3F05CAE042ULL, 0x845CCC3951AA0E03ULL, 0x5B9DED653490284BULL, 163 | 0xEFFE72E182D542ADULL, 0xFFA72FA94CCCF9B9ULL, 0x2BC99DE58AA23092ULL, 164 | 0xDD8329C4618728CAULL, 0x6A683872B26B029FULL, 0x2DF8865ACACBBE4DULL, 165 | 0x15376DACDA2F0E81ULL, 0xD42D704592FC32B5ULL, 0x58FA4413070D3399ULL, 166 | 0xB8C966145088CEADULL, 0xF668E74FA89E204DULL, 0x285ABAE848BBABE9ULL, 167 | 0x2ADBCF8214392ED1ULL, 0x77F7C84D28329DC1ULL, 0xFA2405903D4B352CULL, 168 | 0xA8AB3D31B7A9FAB0ULL, 0xA5535BFA41A91573ULL, 0x526AB53ECF3245C3ULL, 169 | 0x5860F72591C7FFE2ULL, 0xF037CF2FFD87B278ULL, 0xCBD7A816A2BC2BC8ULL, 170 | 0xE1D47F38AF50AD7BULL, 0xB373CDF32A493C2AULL, 0x6F30E922DABEA8A0ULL, 171 | 0x62300FF2B414BFE8ULL, 0x6336411D3D35EEAFULL, 0xE15E767952EAFF63ULL, 172 | 0x41596A60ED40C100ULL, 0x85FA09037AA9173EULL, 0x666DB06C94505F25ULL, 173 | 0xC019C5D9CC58B557ULL, 0xCE1685F52A6CD919ULL, 0x4230F2C5694EE781ULL, 174 | 0x2841082C5F3FA5B2ULL, 0x83F484CB8B58EA14ULL, 0xFC4DCC481F3367AEULL, 175 | 0x06920C8FE1D1F022ULL, 0xABA9705D0D53F518ULL, 0x1F73D14BC7B2D94FULL, 176 | 0x6006D68AC875E18CULL, 0x15538E2882949F20ULL, 0xE7A9D34A64F07716ULL, 177 | 0x6F057A3D676715B4ULL, 0xBC4B79F8443DEB67ULL, 0xB7C4D38A8E286D44ULL, 178 | 0x3422668CE3AC9E41ULL, 0x539446E33F9A2489ULL, 0xDA936278DAE94047ULL, 179 | 0xD2993BDE5B9EFE02ULL, 0xD9843A58058CD05EULL, 0x6224E0B9DF6BBAE5ULL, 180 | 0xD4C9935872C556F7ULL, 0x7109963FD7967FE7ULL, 0x40B8F3A9718DD495ULL, 181 | 0x1BB4DB2814CCAE67ULL, 0x2F7B37B07BF78DCAULL, 0x0BA052BCE41C531DULL, 182 | 0x55BB031322F81B81ULL, 0x413277827C6C895DULL, 0x3D3A0BDD3DBD7A6BULL, 183 | 0xBFD6ADCD72CD7E38ULL, 0xB837FE068FF7466DULL, 0x58A5F58D0B3381F7ULL, 184 | 0x6DDC0369F63CF094ULL, 0xC553019D39FEA9D8ULL, 0x6F0C43641723CB28ULL, 185 | 0x7DC436965E127E9FULL, 0x98D0B57C9D1633E7ULL, 0xAB0BB22502751D21ULL, 186 | 0xD4FAA0ADF2C33E63ULL, 0x71467A9DD43ECA0FULL, 0xCC6DA6AE21EE0895ULL, 187 | 0xFF508A0B91B2491CULL, 0xDA445AB7D24FE053ULL, 0xC018539B031D2D50ULL, 188 | 0xCC70894B0BBB3668ULL, 0xBBD791657371A8C2ULL, 0x0339202D3DD26F3DULL, 189 | 0x9E46DA68E356FF9CULL, 0xBC8F4C48B2DC4C5BULL, 0xF26BD0B18AE35BEDULL, 190 | 0xAF2CC40EC43BF203ULL, 0x0D776996B28E0B01ULL, 0xA3CC91D7955A8F75ULL, 191 | 0xE4BD8F5314E4906EULL, 0x52367550A29B2B21ULL, 0x47E4F0D7A11ECB9FULL, 192 | 0x085CED0D396813BFULL, 0xF9880B92D2B3A1E2ULL, 0xFA7E577F587E3205ULL, 193 | 0x182E5981458D944EULL, 0xC23E809D53515C0EULL, 0xD332BD14CC488D2FULL, 194 | 0xC508551E69624903ULL, 0x047BE5EF37163BA3ULL, 0x0D74B167E79C52E4ULL, 195 | 0xAB99F16BFED0A5F9ULL, 0x1AF161057FAD49FFULL, 0x963E3E9BB0F149E7ULL, 196 | 0xF030E3A10BAFCF29ULL, 0xBD65C2FF1AD7C38DULL, 0x1685A3505F7BD27EULL, 197 | 0xD8EF4D779DD108E4ULL, 0xEA16509AB4A20DC2ULL, 0x4016DA2975718765ULL, 198 | 0x11CB2708ED8E5151ULL, 0x2929E999E499E13DULL, 0xC4B76C6D372A5D9FULL, 199 | 0xCC57FD9513711DD3ULL, 0x7A896B5A2978596AULL, 0x0D5520975BCA2D51ULL, 200 | 0xA787CFA1172A875BULL, 0x4D54C002DDB0EB9EULL, 0x1B0A2B7B6AFB1C3CULL, 201 | 0x1E310151A0215CABULL, 0x949A8C6E316BAE86ULL, 0x2689386CA9BC877CULL, 202 | 0x3FE7416AB10C6D41ULL, 0xF1C25798145B2103ULL, 0x62E3966BFD77A38DULL, 203 | 0xD284C6EF30BB1F9AULL, 0x408202E5171F6D90ULL, 0xC7CC502EA7CDAA6BULL, 204 | 0x27C2C3BEBE070EE2ULL, 0x4E74C86E3D2BFD4FULL, 0x2FF999B0E3C00ACCULL, 205 | 0xACD0324F38753836ULL, 0x9E45BA3EE7502CE8ULL, 0xC0D3EF3C4918E4B5ULL, 206 | 0x4C2BC25F84C9500AULL, 0x0C60D645945FA0E3ULL, 0x4B7D333D34584BCEULL, 207 | 0x50847113DC4DF626ULL, 0x7EDBA55C7DB5A85AULL, 0xF08AC6DD32AA79E2ULL, 208 | 0x0FD07CB89770FCA4ULL, 0x1556026BF7988B0BULL, 0x53D158FB41D58AFDULL, 209 | 0x3E6FC942816BCEC1ULL, 0xE463BB0B0AFBB623ULL, 0xC58AF9FE16449BB3ULL, 210 | 0x050B020AABE94AB7ULL, 0x415A089418F75988ULL, 0x0C791EDD7BCF328AULL, 211 | 0x5507A5965AB0E95CULL, 0x679B31FA63CB4AC9ULL, 0xBF361DFFD19E79B9ULL, 212 | 0x086C1B02316D7734ULL, 0x79403C039766780AULL, 0xA91055C834DE8D97ULL, 213 | 0x0B6683231E6D0087ULL, 0x17673477DF6F6320ULL, 0x52DFD153C6F4F180ULL, 214 | 0x0A0245CF88CA639CULL, 0xD5A148E61E77F456ULL, 0x878E7D009E8E5975ULL, 215 | 0xD8AB40ACBF1DC502ULL, 0x1F1ACE9DDEC15226ULL, 0xE573A526F83E6774ULL, 216 | 0xCF9F0A31AAFFA79BULL, 0x1CAB005309EC91BCULL, 0xC52ED6F7EC24BA6EULL, 217 | 0xF3C18763135FD806ULL, 0x2811F8917E885AF2ULL, 0x6518FCCA566B34CCULL, 218 | 0xDB0EF166B295E69FULL, 0x83FE270F693A93A9ULL, 0x5771EADFFA304DBAULL, 219 | 0x8A1AEF1F6E7429D0ULL, 0x1A1656B4ACE774B9ULL, 0x551E8B39AD57BB86ULL, 220 | 0xF6A2FC48D8F6087BULL, 0xCA678CD5CA85C609ULL, 0x2FFEE5A912B938B1ULL, 221 | 0xD504B08F3B70DEB5ULL, 0xB0BBF75434C5FA9AULL, 0xECEAFBC1D0C87FF6ULL, 222 | 0x2032900113DEC7BBULL, 0x0B0FC2AFD52B7481ULL, 0x94D5A531738AE0FCULL, 223 | 0xB2F02E18506110F1ULL, 0x25B836919BE51145ULL, 0xA92FF476E01D6A59ULL, 224 | 0x502BD4BEA885F5C7ULL, 0x92DF42C2B7D8C223ULL, 0xB084F872A050C529ULL, 225 | 0x82F47A63B7C7A82CULL, 0xB466F0EF9E7DD33CULL, 0xBE6FDE623DFFA1B4ULL, 226 | 0x83C804F4DDB41969ULL, 0x20BA69D998830162ULL, 0x22BF46EE6FC7A7D6ULL, 227 | 0x813FA1F5C6B0EC32ULL, 0x6FEF49E943CC6CA2ULL, 0x7F3F9C1A50E9B15CULL, 228 | 0x424D73A79C95FC33ULL, 0xFE569330A71EE1D4ULL, 0x9CD515AD3483BD59ULL, 229 | 0xB71920218FCEC3FDULL, 0x8425444D1568CCD8ULL, 0x583D1F364F55C365ULL, 230 | 0x217538882ABDCF3AULL, 0x1775CA48D9542B6DULL, 0x468B4005393CC777ULL, 231 | 0x72521E3DDE9ABF46ULL, 0x494B5406EC795304ULL, 0xA8E9EF50301DAAAEULL, 232 | 0x641AF6DF8C39771EULL, 0x92960BEFD661DC51ULL, 0x07A2A036FDA72DF5ULL, 233 | 0x719A2E57B28EB0FCULL, 0xDE11F44DACD41EBFULL, 0xC7B36774D31D24BBULL, 234 | 0x16053F804CE7B077ULL, 0x7DAB584A43844024ULL, 0x4E92BAD920BE5935ULL, 235 | 0x381ACFF270BCEB32ULL, 0xC7959C74E7B2ADD2ULL, 0xC6729EBF7698582EULL, 236 | 0xEF67296241CCEF3DULL, 0x45B3C1DB103B6E04ULL, 0x70959A9738662BBFULL, 237 | 0x5665B97727C8291AULL, 0xEA57D9725D6E63DBULL, 0xC53950F87EA9E017ULL, 238 | 0x8FC507019C38AEFEULL, 0x6C36C3326773BC72ULL, 0x8E8503466CDC842DULL, 239 | 0xC9E89C692CEE1723ULL, 0x591F640996C1BFB0ULL, 0xE52B4BBE6CE84FE3ULL, 240 | 0x4FC28BBDB217236FULL, 0xF967AEAC0A4DCC62ULL, 0xA5C165C6CA848699ULL, 241 | 0x7398BDE560CC0E4FULL, 0x359A88B828116D97ULL, 0xF5214B32399A950BULL, 242 | 0x429881B851042899ULL, 0x580C1CFD5C0A7A17ULL, 0xA6F279BA4F3C60E5ULL, 243 | 0xA2DA8F67F751BFF0ULL, 0x6B6BC9544983CCC3ULL, 0x61BBB8474D81E8C7ULL, 244 | 0xAD3C72EE0F5833DDULL, 0x35BE82C817D900C9ULL, 0xC6D29B5E0115F8ECULL, 245 | 0x4ED778194A57F87BULL, 0x8E62CB98A6C05C74ULL, 0x7D3331C19655A8BFULL, 246 | 0xEFC3B26F22DECFF5ULL, 0xCF96A427AD400E08ULL, 0xBEAC4BF5C50C711FULL, 247 | 0xCA3748263BEEC78AULL, 0x7B25B57007257DADULL, 0x70C1B894B14ECBDEULL, 248 | 0xDF25487BA944BD4AULL, 0x729894D4CAF4EC45ULL, 0xD5097C694EC89480ULL, 249 | 0x5AB654A2421890D4ULL, 0x478C17DE788FACE2ULL, 0x70F100E8B24932DCULL, 250 | 0x154342A779EC1860ULL, 0xC735EEC6250B3583ULL, 0x8B515BA004347C1CULL, 251 | 0x5D277F258C01D57BULL, 0x45001B997893B3C6ULL, 0xC4AD64853517160DULL, 252 | 0x214863538D7FA052ULL, 0x94093661CF15CAD9ULL, 0x75C8F0C99CF247A8ULL, 253 | 0x17A015AE5A1DE432ULL, 0xDD45875443D76FA5ULL, 0x823C0B79A0502FC7ULL, 254 | 0x86437C240228239CULL, 0x88ABFDAEEC13E26FULL, 0xD307BC78C70082CCULL, 255 | 0xAEE7DA615047A394ULL, 0xB929F1B7B34D4FFDULL, 0xF110E2E5A62C9528ULL, 256 | 0xCFA3ECB0DE58C955ULL, 0xC28AB04C66101DFAULL, 0xD80DF8A3A34E2076ULL, 257 | 0x9A9B31501CE1080BULL, 0x18AD11E289F01653ULL, 0x019DE1BA32F5F222ULL, 258 | 0xBD3CAE1FC19E494AULL, 0xEA689BEE30021016ULL, 0x920915BB5D4892B5ULL, 259 | 0x4A3080D061CC2FEBULL, 0xBE1F720FAAFD1861ULL, 0xBDD8FB2400C7524DULL, 260 | 0x385B0253CD6039D8ULL, 0x05A0A95739C519A9ULL, 0x2BB94254527C6399ULL, 261 | 0xEDECF2C4E3BFACB7ULL, 0x59AFFBE6F456E90DULL, 0x9CAE6471AD41ABADULL, 262 | 0xAA9F7E5F501DACEAULL, 0x169A1E5EF4D3BF40ULL, 0x509A5E745AE7EBBFULL, 263 | 0x7BF6A874BD0EBC5FULL, 0xDB39800FE3A1DB52ULL, 0x3672D0A12DAFDF3DULL, 264 | 0xF4C02681A9DF67EBULL, 0x6AE5E3F6951EE2CEULL, 0xA7FF2E7E56D79DBAULL, 265 | 0x4263FCBA59703FF6ULL, 0x7BAA6313CEB2A36BULL, 0x938E8D602F5DE404ULL, 266 | 0x8041670E13481381ULL, 0x1F3126C9E2A63E12ULL, 0x1E4248DB8D8FB161ULL, 267 | 0xD33EDB99DCA9564BULL, 0x4133162F55CFE571ULL, 0x8044DF8A70B8E0D4ULL, 268 | 0x8D3F856E39651E9AULL, 0x16D098AA92089FB3ULL, 0x5FC4BB642245CC95ULL, 269 | 0x6C6593379C925826ULL, 0x20B87718FA569EA8ULL, 0x86A68CF4F8183EFDULL, 270 | 0x0FDB16EABB409D81ULL, 0x10CDF17A1DF5D326ULL, 0xE38BDCCD9E966C5BULL, 271 | 0x7C6107D78E5A6D9CULL, 0xEF6E5C1F91F0A0BEULL, 0x154FA478336DFB12ULL, 272 | 0xFE3311D5172DB5D9ULL, 0x3328D5AE6A6306CEULL, 0x5812E0245DDCCDDBULL, 273 | 0x8F8B2EFA3463FAF5ULL, 0xA976ED94FC5407ECULL, 0xCBE9540649CE45DFULL, 274 | 0x6AC3E2CB4815E792ULL, 0xCFCFC84EF73B4B66ULL, 0xC9FAFB5768F0C757ULL, 275 | 0x81A0A36F689E3132ULL, 0x63008FED346D900CULL, 0x572C90E936CE0BCFULL, 276 | 0xE0A0FFCE1BDAC21BULL, 0x1AC6AC5FC69C554DULL, 0x85DA499EE69C8ACDULL, 277 | 0x1F914F0AA865E969ULL, 0xC9C2F1CD63A67710ULL, 0xD7245381E8695069ULL, 278 | 0x6329C3A550AC7155ULL, 0x1FC25512B0A01CADULL, 0xD611D872B34DB42EULL, 279 | 0x115781A62CD7EE27ULL, 0xA69473CEAF03156FULL, 0xE4CB69140A7FE983ULL, 280 | 0xD3E07A9DB53872F6ULL, 0xA03FD9831172125BULL, 0xF55A9F75C4F947C5ULL, 281 | 0x22048533D5056D75ULL, 0x3A754C78A46C73D9ULL, 0x3522A637F7615162ULL, 282 | 0xB71CFF981E65BDE1ULL, 0x25078B9C5E94D615ULL, 0x5DA495198EFE3788ULL, 283 | 0xD7C387E359360A7AULL, 0xBD9D75E37A6232ADULL, 0x80EAB13B84244E8DULL, 284 | 0xB0AC26D0999C95A3ULL, 0x39D9E1D98A32328CULL, 0xAC763E36EDE6D193ULL, 285 | 0xA66F44CF36DB3665ULL, 0x8748A05883A85B04ULL, 0x48DF12A6C89A732FULL, 286 | 0x181DA563192A0D21ULL, 0xB9A5E990FCF45BABULL, 0xDB71016D34A7BA2EULL, 287 | 0xF53DDC189BAC1A50ULL, 0x589E249B0A88CDF6ULL, 0x5A36972D73D7D8C8ULL, 288 | 0x5ED8C53703F795A1ULL, 0x30BC6163B5461E07ULL, 0x16960C4C1F02C7FFULL, 289 | 0x4CE3C590686BD538ULL, 0x044B1EEEDF17F715ULL, 0x5009AE644E650549ULL, 290 | 0x3284FD2D5874707EULL, 0x4D7518F17263B177ULL, 0xE7964A962EBC3A79ULL, 291 | 0x26A79E8EF958FFECULL, 0xF919DC2C020CAD6BULL, 0xCAAFDEF6DAB7DFA2ULL, 292 | 0x638B19F5DCC099F0ULL, 0x34D0A854ACF35EF9ULL, 0xC3EC696700A83B34ULL, 293 | 0x838C14AFCA632397ULL, 0x5A39789FB62D70A3ULL, 0x43E92F9F3204AF8FULL, 294 | 0x4A1A852F47ED7F35ULL, 0xB760F61927B1BB04ULL, 0x368C7C002C6BFF36ULL, 295 | 0x478C7758B9652124ULL, 0xA74A56429CC877FBULL, 0xCE836A1A353DCA4AULL, 296 | 0x1FB0033BEE6D6C65ULL, 0xBEF3D73B36D1E59AULL, 0x8CD192A42A1FE1DAULL, 297 | 0x4894281AB43E6DDAULL, 0xDF2B7AE4D4CA5217ULL, 0xD135B5B9F20DEE26ULL, 298 | 0x58C002A801947B67ULL, 0x12D51A51211304E3ULL, 0xDC2EE29C8E17960BULL, 299 | 0x092260B38FCD938DULL, 0x6944DDC43B6DEFB2ULL, 0x5A222E8D946BD9C8ULL, 300 | 0x8BFEBE9B8E3A38D2ULL, 0xC4B355BD47565D3FULL, 0x83B9C03B1450F00BULL, 301 | 0xAC604855CCC52F2FULL, 0x24B47E2898F496B8ULL, 0x4C5FEC57263D108AULL, 302 | 0x946B5842771FC6B5ULL, 0x93AD95A2A25D01D2ULL, 0x20E88ED52D01A6CCULL, 303 | 0x11000BC3D0AD55A4ULL, 0xD4BD5C0FBF4F48AFULL, 0xED203C5F35AEFE8EULL, 304 | 0xD38204545FEED2AEULL, 0xFA3A46F757E8236BULL, 0xD9D91754B5811996ULL, 305 | 0x3FDC4F8F5F70FD3BULL, 0x81A6236135E93729ULL, 0xF798CCEEDB21E2CAULL, 306 | 0x351C673D4B4A6F22ULL, 0x14F8FF4D47DDC74CULL, 0x35AEAD7BB3ED5DE5ULL, 307 | 0xB528A87EFC38DA9FULL, 0x9D45C550FB1B9B90ULL, 0xE775E80C8549CC5FULL, 308 | 0xBC00E901C2C4256DULL, 0x05FCD11447AD5236ULL, 0xA6EE7B4DC21E6AD2ULL, 309 | 0x8E0E519A8D9F6C23ULL, 0x92A5257E91CE7E72ULL, 0x8BEB73570D5BA8CAULL, 310 | 0x5AC1721713028CC2ULL, 0xA6BE37501FCE663EULL, 0x57FC8603E8773970ULL, 311 | 0x55D27C8D72024085ULL, 0x117EC7770F555F4AULL, 0x9DEB2E95B9ACB5DBULL, 312 | 0xDE2046231AEFC0ECULL, 0x42BB07741267A1D9ULL, 0x89C7CBF6B7E4C177ULL, 313 | 0xCF59A1C50C39DCF1ULL, 0x833FEABA027ED531ULL, 0xC1488C13F577613CULL, 314 | 0x3A45E0D7D0AC2A01ULL, 0x3A7ECE948037341DULL, 0xD637A50FDBD7C52AULL, 315 | 0x97CF8079A95A4BD4ULL, 0x8C44BBA75E5A9025ULL, 0x75FB5F44E11E505EULL, 316 | 0xD5C16494D655B2ACULL, 0x2CE0028E7B712ADDULL, 0x5E1F39AA2994B08FULL, 317 | 0x5A55641C0124C76EULL, 0xE45B46AD94EDA45EULL, 0x4AC403E6C3DA55B6ULL, 318 | 0x4FF5EFAE52782500ULL, 0xA0A89BBEFE10EC4BULL, 0xBF6D796EBB02FF59ULL, 319 | 0xCE83C4296F160FC7ULL, 0x224FEFFBB829778DULL, 0x724DA6DA361902FBULL, 320 | 0xB1746B472CD84008ULL, 0xE83BA3B078D3913DULL, 0x5DAD6F66F63C004DULL, 321 | 0x5AAD764A492B5D46ULL, 0xB10D73F767B2CE84ULL, 0xA7DEB18A445406E1ULL, 322 | 0x0ED7E519193E7AD0ULL, 0x6886221E761A21C1ULL, 0x0AA326E363CCBAF0ULL, 323 | 0xFFE76ACCBF2D5B32ULL, 0xE5EF01FC2A4B5A99ULL, 0x8F793DD2914EA0EAULL, 324 | 0x3938F5BDA16CBF9FULL, 0x651E87BACE401CD9ULL, 0x536BA6D5B7B8656FULL, 325 | 0xD396B37AFEE9F048ULL, 0x83FD5C26F60CFADEULL, 0xC7434F0F8A4B864EULL, 326 | 0x0E1AA73C154FB86AULL, 0xD8D20DD86BBED531ULL, 0xAACA45D8BA54505AULL, 327 | 0xB002DF369C50BCBEULL, 0x73D231C5FAD1B46BULL, 0xAA4C6C5989543E31ULL, 328 | 0x9D38DD178E5F5599ULL, 0xBC759593F096E130ULL, 0xAE37035428D9C7A9ULL, 329 | 0x44DC5F79EC641E5CULL, 0x600DAC33E9FD7A34ULL, 0x812EF3F78812D420ULL, 330 | 0x2456CB3C9362D148ULL, 0x0D56E07F2F53CF67ULL, 0xA5A3404A86CE3875ULL, 331 | 0xF5F2CB7F0250ADA9ULL, 0xACBBD8EB87511449ULL, 0xDF551A64A9CE28CDULL, 332 | 0xA7FDB602FEE4AE2BULL, 0x2293B4795151A4F1ULL, 0xD05CA25E6DC12045ULL, 333 | 0x47087FD52F0602AFULL, 0xE8ACBABA9CD62CEDULL, 0x3539193DEB19A4BDULL, 334 | 0xFB96057185741BD2ULL, 0x03ABC8901CFC7E02ULL, 0xE38DDEE6DC21BE4FULL, 335 | 0x536D194C39B9CDE7ULL, 0x1788F1A17D2D5A59ULL, 0x9E6726F8A3E5823BULL, 336 | 0x820870B153B60E55ULL, 0x4630DC5F0013AC73ULL, 0x40736DF7C04116A2ULL, 337 | 0xB6906C4DB67F610FULL, 0xD21F95613CA0EAF4ULL, 0x3AE20ED47D19E3DCULL, 338 | 0x65E2421213AD1AECULL, 0x1BBC4E5613C4EDE1ULL, 0xB24F90D5C0E95205ULL, 339 | 0x0C7FCEA7F2051756ULL, 0x30F892B02C49ABB7ULL, 0x0F453072D940623BULL, 340 | 0xB2077D82AE6CA2D8ULL, 0x911C2BB99E2C0641ULL, 0x68E315A26EFD5C36ULL, 341 | 0x6A3B0EA0FF318B95ULL, 0xA3B972D2D6FDF7A4ULL, 0x599D2C5A69F9ACBCULL, 342 | 0x5C9E1DA2F6FA9BCCULL, 0x3DECD74E01414940ULL, 0x224BA4706B6E4B4CULL, 343 | 0x79B29C72AE77D94BULL, 0xF563875C8695F507ULL, 0x4A6CFA80663A3A11ULL, 344 | 0x9933C03766310656ULL, 0xC809D91E38D6D687ULL, 0x68DC9FBA2B39E42CULL, 345 | 0x0897A7BE56B1C09EULL, 0x491A2A0EF97D86EAULL, 0x5FEAA2AD34720A8AULL, 346 | 0xA2EB09D4481B0CF9ULL, 0x7D934D8A1A091D39ULL, 0xE2846BC41049330DULL, 347 | 0x39FBB678CE3E2038ULL, 0x27C0D33D57F45B13ULL, 0xBFF887C50C90C6A5ULL, 348 | 0x730B873DA2C01B49ULL, 0xD9842207CA1245BEULL, 0x8308C92883AD48A8ULL, 349 | 0x92A58F45A4744924ULL, 0x2DB3B9BFB6BB756DULL, 0xA71FCA60B492C634ULL, 350 | 0x7681064A422D9BC4ULL, 0x78ED3A45DC3A2283ULL, 0x00ACC385C8A51A78ULL, 351 | 0x8A05F9E270C08F5BULL, 0x798951DFBBAAD71DULL, 0xC9E31A6AC26B7158ULL, 352 | 0x0339A47DFB718DAFULL, 0x3BD54AFABB5A476DULL, 0x0EE4F85BB4611AC6ULL, 353 | 0x398CFDA3BD42E866ULL, 0x50AEB36E95076C39ULL, 0xFED0CE62C80F766CULL, 354 | 0x03DD4CE0C73A9F1EULL, 0xEDF029E1E6820997ULL, 0x7BED7BD01E541ABFULL, 355 | 0x1E9224361A96AA8EULL, 0x6AE76AC7AF2F9510ULL, 0x3D95717B07EA4022ULL, 356 | 0x1C5CDD81D810F165ULL, 0x9170D4DDEDC4A027ULL, 0x5BF0CBE80BB3C76AULL, 357 | 0x0E38295E540E8F3EULL, 0x6B38CF852BA03FE0ULL, 0xB21EB841DE31B8C0ULL, 358 | 0xA554C79B8071361FULL, 0x5241F4BF8A2D6C87ULL, 0x6516BF6C72D1FCC1ULL, 359 | 0xA5F98F59C0FF2CAEULL, 0xAF38ADB2F62FF308ULL, 0x4F3713E5C2799227ULL, 360 | 0xD56783B879556C78ULL, 0x88BC1AAC1B6612ECULL, 0xE536B758C19BE96AULL, 361 | 0x42EEA3D4B280224FULL, 0xED8AA4826EB8A36FULL, 0x8EC960BD39D6B2A6ULL, 362 | 0x4EDD4D07F1B096C6ULL, 0x921F134BD424E60CULL, 0xC662C2C23035133DULL, 363 | 0x48EBCF01572A6510ULL, 0xE44491B969894CD7ULL, 0x86DD7EBC4502511CULL, 364 | 0x56C9A56698914AA1ULL, 0xFD8B353773E85782ULL, 0x29B648F4C88DB1C9ULL, 365 | 0xECFC42A8D6494EEAULL, 0x6715EB34A9C24A5AULL, 0xDD869217BDCBF2A1ULL, 366 | 0x6F86683604A0EDF6ULL, 0xA9EB8976C38C4A9EULL, 0x773F62680646A328ULL, 367 | 0xA849B4175CA54C9DULL, 0x97E1C617737A8ACCULL, 0x20F9740C2EC882EBULL, 368 | 0x110A6CF8C7D03437ULL, 0x5E53CC9D4312E29DULL, 0x3F886FACB2B12269ULL, 369 | 0xE8123240047DA329ULL, 0xB09D603AE2463254ULL, 0x67CB65714007D6B2ULL, 370 | 0x7DC093E942865707ULL, 0xBBA9ECF8D4D1A3BDULL, 0x7FFF2FA7A7EE4233ULL, 371 | 0xEB02FDDD8FE3B10CULL, 0x38A204368385FD8FULL, 0xEDEC504C3305B626ULL, 372 | 0x9B00D12355A32F86ULL, 0x96B498EC38CCFD8EULL, 0xB7CB8F074CC08EFEULL, 373 | 0xCE01D278B1E1D9E5ULL, 0x37FBDFDBD43AAC36ULL, 0xACE911C8F334A824ULL, 374 | 0x0D934F66C1061983ULL, 0x20FAEC63A955CE89ULL, 0x39E1BD6E83CAC75DULL, 375 | 0x69496D012AAB2BEEULL, 0x79CCCCBCF11E90BDULL, 0x6772973494F1BAC4ULL, 376 | 0x505B1B6188ED8532ULL, 0x512A8A12229037CEULL, 0xF4B1F12A5B142892ULL, 377 | 0x5A1047041D26F18DULL, 0x9213DF13FEB41FB0ULL, 0x41A694844C7751E5ULL, 378 | 0x44D5DDA1C61E7400ULL, 0x5C24192620047EE6ULL, 0x51311D4C29D0A878ULL, 379 | 0xA02E020FFCDBF703ULL, 0xEA03DD8BDA4AEA3CULL, 0x63E1938395D9E8F5ULL, 380 | 0xB897ED785B400670ULL, 0xA2D241EB5F0F697CULL, 0xB5A3B7899FA0154FULL, 381 | 0x7CC33E1FEDF67830ULL, 0xF629BE34BC4661A5ULL, 0x3651A6657758F5B8ULL, 382 | 0xD5A1063610CD8535ULL, 0x13E3DDAADB03B419ULL, 0x70BDF28471A42D79ULL, 383 | 0x59324534AC34A130ULL, 0x2B3AFD293868D2ADULL, 0x86D09A512BCB7BB6ULL, 384 | 0x3F1694A93E617E64ULL, 0x8212538FD52FC719ULL, 0x22E7134A4257A928ULL, 385 | 0x6C501A521CC71839ULL, 0x87B5D48371E7E3AFULL, 0x9C1296BD90357CD4ULL, 386 | 0x7BD2793C60E532D2ULL, 0x52DFD310771B4DCAULL, 0xA32DB0ACFF200017ULL, 387 | 0x70564E225C51DAD4ULL, 0x2BBA3F2A01C3B91EULL, 0xB8FFCE87EB61086AULL, 388 | 0xB8E92C0BAEC2286DULL, 0xD0CBE6AA01A006ACULL, 0x5DE330ED581B40F8ULL, 389 | 0x00DD3D6457179CFDULL, 0x47ADEAC71ECB8795ULL, 0x565DA36CEF95685BULL, 390 | 0x19C558F9C691337FULL, 0x1E60EF4DA45B0032ULL, 0x5F41EC3618FB84A7ULL, 391 | 0xD8937A2271F91167ULL, 0xA98C5B9D29DE98A3ULL, 0x54BBA6A82FF161BEULL, 392 | 0xEFCD408A453F0952ULL, 0x0BFB43C32CED4EDFULL, 0xB2FDAEBA3E9AFCCAULL, 393 | 0xE34765BDF779A171ULL, 0x57C5AF9407A2B16CULL, 0x2A46B1614D4A751EULL, 394 | 0xE1B2FC7551C9ABDFULL, 0xE6228F6525BD066DULL, 0x6B06E19660C9A424ULL, 395 | 0x4CBFEB46732A145FULL, 0xCF3E76181B3B366BULL, 0x151B2E9E4A462A74ULL, 396 | 0xCCAAB247F4BDE9DDULL, 0xD847135774C745B7ULL, 0x916B572CA83F60CBULL, 397 | 0xCD321AC0AB1B27DBULL, 0xE5BAFFB74FC3578BULL, 0xFC71E078565EA590ULL, 398 | 0x61E095EE094D89C0ULL, 0x5D9ACCBB11849775ULL, 0xAD28E9724246FB6DULL, 399 | 0x94F6357C5BF54F6EULL, 0xBB96FA909D744BBEULL, 0x7A01F6036E697475ULL, 400 | 0xBD0F6CB9EFE7DF48ULL, 0x1FD40A6B152EDC9CULL, 0xD5A51CC7C8CC4F03ULL, 401 | 0x4617ADC790FCBDA7ULL, 0x9C97884E671DFB2DULL, 0x3B727C091687614EULL, 402 | 0x3DCD8604253391EEULL, 0x8ADBF245D5707441ULL, 0xAFD2C1F869662217ULL, 403 | 0xB84073B30FB2808BULL, 0x61D7034EB5C254C1ULL, 0x0FCE70C7A3A42D72ULL, 404 | 0x30F9A91E76FE79B0ULL, 0xDD5A61DA47EC0B14ULL, 0x67E60432CE71DDAFULL, 405 | 0x02275E35584D2484ULL, 0x62B786C05BC0400BULL, 0x484FC52E48ED8221ULL, 406 | 0x2588ECB564678A5BULL, 0x7751C308E219596DULL, 0x5010B816944FC1B7ULL, 407 | 0xD7076F1B18BC5511ULL, 0x951AE876CE794EAFULL, 0xFABA3A0D8CD1F0BCULL, 408 | 0x9B7F3D26C3328482ULL, 0x499FD84044E6997AULL, 0x0E6901074251D6B6ULL, 409 | 0xCA0D846AE9A11286ULL, 0x0E3B173194B8DF44ULL, 0x8C061B1BB3620F8EULL, 410 | 0xBDDBDC0429CEDD38ULL, 0xCDA5B1C1E8DDE415ULL, 0xA1BAF7F068C3E168ULL, 411 | 0xF6222898B1C6E9A5ULL, 0x98B71068CDB4C3FFULL, 0xB644C87A637049FFULL, 412 | 0x5AC79AD3834ED3CAULL, 0x7B1FA4B70D5A6D77ULL, 0x0B46FEB8DE8C286FULL, 413 | 0x4C74269C4C41DBD9ULL, 0x2B08B55A0B275896ULL, 0x72C6D76BE7229AEFULL, 414 | 0x44DEBCB61F1B3F7EULL, 0x2C01E709AEFFE4F6ULL, 0x102F789F7A09D4FEULL, 415 | 0x811DAF9DB29A5514ULL, 0xE3F6CCED425D6DA8ULL, 0x4F82AB402E9A4EDDULL, 416 | 0x726A6190BBB2C2CAULL, 0x0A3A2F4FDF412715ULL, 0xC626E2723095A9FEULL, 417 | 0x88A421B60ED80C04ULL, 0x1996F5093358FEC3ULL, 0x2A558E5216700356ULL, 418 | 0x2512E46A78FFE668ULL, 0x4EEE109968C28007ULL, 0x910838B85330BD04ULL, 419 | 0x16443048A33E554BULL, 0xF4C42266C44BDD83ULL, 0x20D48AFF0FC03A8DULL, 420 | 0x87E949929D7EF8D4ULL, 0xEAE2696938C614F5ULL, 0x25C08F5E4009A731ULL, 421 | 0x820011837BFC2E30ULL, 0xFEA6F3B3DDDCE3B4ULL, 0x1D7707DD51D9B7C1ULL, 422 | 0xFE87161255818FC2ULL, 0x1FE4BA0010B09053ULL, 0x6D00964A5831F0C3ULL, 423 | 0xA17811FF960269CFULL, 0x1088DDDDFEAA611FULL, 0xE356101AEE60CAA2ULL, 424 | 0x226D78E7DD83F908ULL, 0xB9DBAB4E00B4FAABULL, 0x0F9CB49457646AA5ULL, 425 | 0x6A39DEAF9873056FULL, 0xEB130F7FD2FD4475ULL, 0xD7F0AD224BA3E09BULL, 426 | 0x6F399F6E97BDCF17ULL, 0x457C8440000A4FBEULL, 0xB094C5EFAEC5AAEAULL, 427 | 0x4AD8482C7A6E87C8ULL, 0xEF5C92378D24F291ULL, 0x74DC7E0021F04FF4ULL, 428 | 0xE4D304899AB5A15AULL, 0x4B4E35DE262CF307ULL, 0xB4B39EE4324BF4DCULL, 429 | 0x8894E75B43C7492BULL, 0x913F092AD7B8DDC1ULL, 0x87A19099D878AF1CULL, 430 | 0x271ABC47D0689ED6ULL, 0x7D3E4500125CF30BULL, 0x51224E33DF4CC37AULL, 431 | 0x4B71694A0DAAD435ULL, 0x163A9C9DD10B1381ULL, 0x1D3AA0291C899293ULL, 432 | 0xEB2319909C2CBC62ULL, 0x1F41CC385B381F85ULL, 0xF7D01F64876F8446ULL, 433 | 0xE282CEC966DD2343ULL, 0xC7CDF5582C6C6A0CULL, 0x3B128E3D33DA2702ULL, 434 | 0x49492FB8255C9D06ULL, 0x6746E5A17F58B3E3ULL, 0x523F4209F26E3071ULL, 435 | 0x6947A4084C916579ULL, 0x1C6A7F7A88288D3AULL, 0x68A8D531820AFB90ULL, 436 | 0x386D98BBC8E1CB6EULL, 0x9B820593DE89F3F4ULL, 0x28FE1B7F155B520DULL, 437 | 0x831681511359630DULL, 0xA2E6AF2AECCDC4F1ULL, 0x8BB5C57749F730C3ULL, 438 | 0x5AADAB203DDDD939ULL, 0xE590C219A6634C88ULL, 0x6EC55DF66B34C4F0ULL, 439 | 0x9A470566A1F5900DULL, 0x224967589BAC6C32ULL, 0x9D13EC3DC98F9E15ULL, 440 | 0x798B274F77F170E9ULL, 0x59573E4D7757DE29ULL, 0xAF2BC573237027DEULL, 441 | 0x4B37860B81296505ULL, 0xADF97E687817F463ULL, 0xC63A07F0DACAB254ULL, 442 | 0x12434BA6A170C3CAULL, 0xF4F11EC116239925ULL, 0xDA9C22A1861793A7ULL, 443 | 0x3C3B4AC1E19996CDULL, 0x01EE88826E6F8AC3ULL, 0x1849CEEE1708023DULL, 444 | 0x18ADBBC7D9A67CB1ULL, 0x1C74C832DB477134ULL, 0xB6D6ABBF8EB5D94EULL, 445 | 0x290D4B419A6B54DFULL, 0x5B5C144C84ED14F6ULL, 0xA27CFBC45060CFFFULL, 446 | 0x1456D9430A202E70ULL, 0x9E9FF002C1BC210BULL, 0x4292482C780487EEULL, 447 | 0x9BA90E9669989270ULL, 0x66A4093303873F83ULL, 0x3B86307995565F94ULL, 448 | 0x9029F365110BE290ULL, 0xF7A3D17371517570ULL, 0xAAAB9DD113995B8BULL, 449 | 0xFC3980E5BDA88774ULL, 0x82C1394DB4FF52E5ULL, 0xA960E3635DA84837ULL, 450 | 0x55F03B9E4CC8CC2AULL, 0xF4292618CC4BB5CAULL, 0xC13ACD31C0C6CE3EULL, 451 | 0x59A93D2A96264AE3ULL, 0x3A526A0CF9EE947AULL, 0xF7706250E86A7F8BULL, 452 | 0x4F01006FCF6E149FULL, 0xC7E837B59DAB20FCULL, 0xDE1AD3ADC8B5F0EBULL, 453 | 0xB51953811BE8B8EFULL, 0x2F18D38EB36C4327ULL, 0xDE24FDA3BB65A309ULL, 454 | 0xFD5905DAFDE9ED84ULL, 0xDA92FA9A170257A6ULL, 0x53B6B0CABCC30DB4ULL, 455 | 0x7DCA2542FDE6A808ULL, 0x677C76065EA5AD3EULL, 0x29A384756296EBC6ULL, 456 | 0x233244D5D0DF2D14ULL, 0x2395ED923F2B6A20ULL, 0x3B050E665C75A86DULL, 457 | 0xC433A8733B4EF6D6ULL, 0xC4C08489C7FBA97DULL, 0x6E555857D3509BB6ULL, 458 | 0x2BB0539B35A44660ULL, 0xB4B99EF00D5470B4ULL, 0x9B37C43C00B7A271ULL, 459 | 0x00B7FDBEDFF45A94ULL, 0xCAAA63D9668BB548ULL, 0x41D6DFB8FCE05348ULL, 460 | 0x2A126BCFA027630EULL, 0x9DC19819A21C11A2ULL, 0x4250DBC6DAA05E4FULL, 461 | 0x87E0FB60A8341B3DULL, 0xB99D0C8FC8C348E1ULL, 0xBD7EE5E5E5841A26ULL, 462 | 0xAEA477104AD3A4CCULL, 0x993703486C37DDBFULL, 0x2F282B758B463BBAULL, 463 | 0x40346D38B9A38263ULL, 0x949BB1ECFE187855ULL, 0xAD9FB8648E3E0BD6ULL, 464 | 0x2207BB529BDCBC89ULL, 0x21D0B668550D6F5FULL, 0x7F12439F846A4CF8ULL, 465 | 0x8302845F65665E3FULL, 0x1F35D285B6297771ULL, 0x76A0B0E4FE697660ULL, 466 | 0xFA93F1E7D7141084ULL, 0xAB9D37D76D182DE5ULL, 0x9E5736B1AB409B7CULL, 467 | 0x3B5A8B8410108CA9ULL, 0xA61D37F811D5FDF3ULL, 0xEAFC7FF4AADA78C7ULL, 468 | 0x6C30B4D34D691A1EULL, 0xF00F8A27E8EA1788ULL, 0xEFAAB7C3FD1FE5AAULL, 469 | 0x770249D0A77EFD3BULL, 0x810D87BB30D13B09ULL, 0xEECE7E8165CBC62DULL, 470 | 0xBB2FA83357036A61ULL, 0xF23473046FE64A73ULL, 0x3D52457616E627F5ULL, 471 | 0xC8445FCB404E9669ULL, 0xC682E47C42E5F5B2ULL, 0xB17A3785450AA2B1ULL, 472 | 0x01A85E6FD2D0B8F5ULL, 0x0D645419E85F9034ULL, 0xB14A51E390598DE2ULL, 473 | 0x7F141B1F9E7CE0BEULL, 0x27ABE9C2B67D1F6EULL, 0xB483DB1DF63212F8ULL, 474 | 0x29052E2C89474DF2ULL, 0x27D493AD112A1057ULL, 0xA39AC5CB0BA56D11ULL, 475 | 0x09DFD822010934DCULL, 0x43871AFA5527AA79ULL, 0xECE72F10C169DD25ULL, 476 | 0x748B4FB2D1543DF1ULL, 0xF9C5D7FA50020EEEULL, 0x4052BA90D27F5FB3ULL, 477 | 0xDC6E3391BDCE3658ULL, 0xE91BF6C642620791ULL, 0x5764A7DC2CE3856AULL, 478 | 0x63DAD70F5FC20DBDULL, 0x1EC14495655C4949ULL, 0xCA105D0795A465F5ULL, 479 | 0x1F0987744B6C851EULL, 0xC19BCDF7725F5E42ULL, 0xACD9F6B3A7C739EFULL, 480 | 0x0C0EFD427DA37A5FULL, 0x551AEBE6E6B24211ULL, 0x870DEC3C1B531487ULL, 481 | 0xE570A6082158F34CULL, 0x9403BC029846FA86ULL, 0x779AB3CCDAA0B866ULL, 482 | 0x8F3F87FB32415720ULL, 0x68C1095B29B1521BULL, 0x219EF1A8FA5ACA58ULL, 483 | 0x319ED20E6B3DC9E3ULL, 0x44003B56001545BEULL, 0x9D604433C05F3A75ULL, 484 | 0x8304AC77D422C622ULL, 0x994D272D22189952ULL, 0xAD60CB2F2B4A238FULL, 485 | 0xB7B2A4157E4A623EULL, 0xFC0F3F922C37B57FULL, 0xE5DF3C0B746F9802ULL, 486 | 0xACCFA469493B6A31ULL, 0x57B8D485125180C0ULL, 0x41B6D355F01C2E6EULL, 487 | 0x7F5177876F94A360ULL, 0xE9154801A2EBCBA6ULL, 0x2DAD297A821C5E61ULL, 488 | 0x51E13E84DC1FCDD5ULL, 0x2F7B655ADAB2B4A1ULL, 0xBBFAB747E579548EULL, 489 | 0x01C87B08CFF50D3CULL, 0x9886C7F2C74EF095ULL, 0x18AE9DEF50AB83F9ULL, 490 | 0x73C82DEB1089DADDULL, 0xBB8DB619FD613A36ULL, 0xF6CFF4CF283AD42FULL, 491 | 0x9A903AC7548D3039ULL, 0xC4A53EB07A9E4273ULL, 0x4A05D20A56E64F62ULL, 492 | 0x0301D35AEC98DE1BULL, 0x9975C2EEF1AF238BULL, 0x6CC3C8C7A4523C63ULL, 493 | 0x8F7C74603C54A732ULL, 0xDDB8C2A6445B1D85ULL, 0x2FEA3EFB8693E85BULL, 494 | 0xDE8BD8ED2632FC8BULL, 0x1756A452AF3AD798ULL, 0x7170D576542A5C97ULL, 495 | 0x89E3B1536ED4D2D3ULL, 0xF21AE4E8B7656A70ULL, 0xECF5A2D368FE6261ULL, 496 | 0x224DE1BFED2D174EULL, 0xA33E07AE10C62D4AULL, 0x06102E5F6AF9FA3BULL, 497 | 0xA8566927E4908AD6ULL, 0x94EE734291472250ULL, 0x74E4D2E9B023016CULL, 498 | 0xFFEDE299ED558029ULL, 0x73405527C1E93E3DULL, 0x9CA4DB038D7EEB11ULL, 499 | 0x512FEAA28F347E29ULL, 0xF57F6CD07B9B247CULL, 0x276F9733A9813BC9ULL, 500 | 0xAD050BB855AC034BULL, 0xF77C5A4F06F2E497ULL, 0x04953DB42F94833CULL, 501 | 0x2148FD8674194B77ULL, 0xA684CF39FF1D5A41ULL, 0x4131C3246A36063CULL, 502 | 0x21DCAA82FB3D54F4ULL, 0xCA5AEED84CCC09AEULL, 0x54FB4DB07456C270ULL, 503 | 0xD12DBBFACBF6BB59ULL, 0xF96AF2F3E1D02B54ULL, 0x70DDF5FFD453E2C7ULL, 504 | 0x7380F75287996FAEULL, 0x4C4E7FB35319FCABULL, 0x64D6DC20E1A84ACBULL, 505 | 0x161DB07C22BF2658ULL, 0x1D3584C0610AB3D8ULL, 0xD98F9CFA6E2DADD2ULL, 506 | 0x366FD8DBEAEB262FULL, 0x8FFA6F0DAEEEF7FBULL, 0xE4AF5DCA9E19758DULL, 507 | 0xB60F5777A07FD280ULL 508 | }}; 509 | 510 | // polyglot_key() returns the PolyGlot hash key of the given position 511 | Key polyglot_key(const Position& pos) { 512 | 513 | Key key = 0; 514 | Bitboard b = pos.pieces(); 515 | 516 | while (b) 517 | { 518 | Square s = pop_lsb(&b); 519 | Piece p = pos.piece_on(s); 520 | 521 | // PolyGlot pieces are: BP = 0, WP = 1, BN = 2, ... BK = 10, WK = 11 522 | //BPAWN,WPAWN,BBISHOP,WBISHOP, BADVISOR, WADVISOR, BKNIGHT,WKNIGHT, BCANNON,WCANNON, BROOK,WROOK, BKING,WKING 523 | key ^= PG.Zobrist.psq[2 * (type_of(p) - 1) + (color_of(p) == WHITE)][s]; 524 | } 525 | 526 | if (pos.side_to_move() == WHITE) 527 | key ^= PG.Zobrist.turn; 528 | 529 | return key; 530 | } 531 | 532 | } // namespace 533 | 534 | PolyglotBook::PolyglotBook() : rkiss(Time::now() % 10000) {} 535 | 536 | PolyglotBook::~PolyglotBook() { if (is_open()) close(); } 537 | 538 | 539 | /// operator>>() reads sizeof(T) chars from the file's binary byte stream and 540 | /// converts them in a number of type T. A Polyglot book stores numbers in 541 | /// big-endian format. 542 | 543 | template PolyglotBook& PolyglotBook::operator>>(T& n) { 544 | 545 | n = 0; 546 | for (size_t i = 0; i < sizeof(T); ++i) 547 | n = T((n << 8) + ifstream::get()); 548 | 549 | return *this; 550 | } 551 | 552 | template<> PolyglotBook& PolyglotBook::operator>>(Entry& e) { 553 | return *this >> e.key >> e.move >> e.count >> e.learn; 554 | } 555 | 556 | 557 | /// open() tries to open a book file with the given name after closing any 558 | /// exsisting one. 559 | 560 | bool PolyglotBook::open(const char* fName) { 561 | 562 | if (is_open()) // Cannot close an already closed file 563 | close(); 564 | 565 | ifstream::open(fName, ifstream::in | ifstream::binary); 566 | 567 | fileName = is_open() ? fName : ""; 568 | ifstream::clear(); // Reset any error flag to allow retry ifstream::open() 569 | return !fileName.empty(); 570 | } 571 | 572 | 573 | /// probe() tries to find a book move for the given position. If no move is 574 | /// found returns MOVE_NONE. If pickBest is true returns always the highest 575 | /// rated move, otherwise randomly chooses one, based on the move score. 576 | 577 | Move PolyglotBook::probe(const Position& pos, const string& fName, bool pickBest) { 578 | 579 | if (fileName != fName && !open(fName.c_str())) 580 | return MOVE_NONE; 581 | 582 | Entry e; 583 | uint16_t best = 0; 584 | unsigned sum = 0; 585 | Move move = MOVE_NONE; 586 | Key key = polyglot_key(pos); 587 | 588 | seekg(find_first(key) * sizeof(Entry), ios_base::beg); 589 | 590 | while (*this >> e, e.key == key && good()) 591 | { 592 | best = max(best, e.count); 593 | sum += e.count; 594 | 595 | // Choose book move according to its score. If a move has a very 596 | // high score it has higher probability to be choosen than a move 597 | // with lower score. Note that first entry is always chosen. 598 | if ( (sum && rkiss.rand() % sum < e.count) 599 | || (pickBest && e.count == best)) 600 | move = Move(e.move); 601 | } 602 | 603 | if (!move) 604 | return MOVE_NONE; 605 | 606 | // Add 'special move' flags and verify it is legal 607 | for (MoveList it(pos); *it; ++it) 608 | if (move == (*it ^ type_of(*it))) 609 | return *it; 610 | 611 | return MOVE_NONE; 612 | } 613 | 614 | 615 | /// find_first() takes a book key as input, and does a binary search through 616 | /// the book file for the given key. Returns the index of the leftmost book 617 | /// entry with the same key as the input. 618 | 619 | size_t PolyglotBook::find_first(Key key) { 620 | 621 | seekg(0, ios::end); // Move pointer to end, so tellg() gets file's size 622 | 623 | size_t low = 0, mid, high = (size_t)tellg() / sizeof(Entry) - 1; 624 | Entry e; 625 | 626 | assert(low <= high); 627 | 628 | while (low < high && good()) 629 | { 630 | mid = (low + high) / 2; 631 | 632 | assert(mid >= low && mid < high); 633 | 634 | seekg(mid * sizeof(Entry), ios_base::beg); 635 | *this >> e; 636 | 637 | if (key <= e.key) 638 | high = mid; 639 | else 640 | low = mid + 1; 641 | } 642 | 643 | assert(low == high); 644 | 645 | return low; 646 | } 647 | -------------------------------------------------------------------------------- /src/book.h: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef BOOK_H_INCLUDED 21 | #define BOOK_H_INCLUDED 22 | 23 | #include 24 | #include 25 | 26 | #include "position.h" 27 | #include "rkiss.h" 28 | 29 | class PolyglotBook : private std::ifstream { 30 | public: 31 | PolyglotBook(); 32 | ~PolyglotBook(); 33 | Move probe(const Position& pos, const std::string& fName, bool pickBest); 34 | 35 | private: 36 | template PolyglotBook& operator>>(T& n); 37 | 38 | bool open(const char* fName); 39 | size_t find_first(Key key); 40 | 41 | RKISS rkiss; 42 | std::string fileName; 43 | }; 44 | 45 | #endif // #ifndef BOOK_H_INCLUDED 46 | -------------------------------------------------------------------------------- /src/endgame.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grefen/challenger/902e706b33a786796920ffe4c92612f5d3e34bf0/src/endgame.cpp -------------------------------------------------------------------------------- /src/endgame.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grefen/challenger/902e706b33a786796920ffe4c92612f5d3e34bf0/src/endgame.h -------------------------------------------------------------------------------- /src/evaluate.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grefen/challenger/902e706b33a786796920ffe4c92612f5d3e34bf0/src/evaluate.cpp -------------------------------------------------------------------------------- /src/evaluate.h: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef EVALUATE_H_INCLUDED 21 | #define EVALUATE_H_INCLUDED 22 | 23 | #include "types.h" 24 | 25 | class Position; 26 | 27 | namespace Eval { 28 | 29 | extern void init(); 30 | extern void init_variables(); 31 | extern Value evaluate(const Position& pos, Value& margin); 32 | extern std::string trace(const Position& pos); 33 | 34 | } 35 | 36 | #endif // #ifndef EVALUATE_H_INCLUDED 37 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "bitboard.h" 5 | #include "evaluate.h" 6 | #include "position.h" 7 | #include "search.h" 8 | #include "thread.h" 9 | #include "tt.h" 10 | #include "ucioption.h" 11 | 12 | int main(int argc, char* argv[]) { 13 | 14 | std::cout << engine_info() << std::endl; 15 | 16 | UCI::init(Options); 17 | Bitboards::init(); 18 | Position::init(); 19 | 20 | Search::init(); 21 | Eval::init(); 22 | Threads.init(); 23 | TT.set_size(Options["Hash"]); 24 | 25 | //test_bitboard(); 26 | //test_position(); 27 | 28 | std::string args; 29 | 30 | for (int i = 1; i < argc; ++i) 31 | args += std::string(argv[i]) + " "; 32 | 33 | UCI::loop(args); 34 | 35 | Threads.exit(); 36 | } -------------------------------------------------------------------------------- /src/material.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grefen/challenger/902e706b33a786796920ffe4c92612f5d3e34bf0/src/material.cpp -------------------------------------------------------------------------------- /src/material.h: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef MATERIAL_H_INCLUDED 21 | #define MATERIAL_H_INCLUDED 22 | 23 | #include "endgame.h" 24 | #include "misc.h" 25 | #include "position.h" 26 | #include "types.h" 27 | 28 | namespace Material { 29 | 30 | /// Material::Entry contains various information about a material configuration. 31 | /// It contains a material balance evaluation, a function pointer to a special 32 | /// endgame evaluation function (which in most cases is NULL, meaning that the 33 | /// standard evaluation function will be used), and "scale factors". 34 | /// 35 | /// The scale factors are used to scale the evaluation score up or down. 36 | /// For instance, in KRB vs KR endgames, the score is scaled down by a factor 37 | /// of 4, which will result in scores of absolute value less than one pawn. 38 | 39 | struct Entry { 40 | 41 | Score material_value() const { return make_score(value, value); } 42 | Score space_weight() const { return spaceWeight; } 43 | Phase game_phase() const { return gamePhase; } 44 | bool specialized_eval_exists() const { return evaluationFunction != NULL; } 45 | Value evaluate(const Position& p) const { return (*evaluationFunction)(p); } 46 | ScaleFactor scale_factor(const Position& pos, Color c) const; 47 | 48 | Key key; 49 | int16_t value; 50 | uint8_t factor[COLOR_NB]; 51 | EndgameBase* evaluationFunction; 52 | EndgameBase* scalingFunction[COLOR_NB]; 53 | Score spaceWeight; 54 | Phase gamePhase; 55 | }; 56 | 57 | typedef HashTable Table; 58 | 59 | Entry* probe(const Position& pos, Table& entries, Endgames& endgames); 60 | Phase game_phase(const Position& pos); 61 | 62 | /// Material::scale_factor takes a position and a color as input, and 63 | /// returns a scale factor for the given color. We have to provide the 64 | /// position in addition to the color, because the scale factor need not 65 | /// to be a constant: It can also be a function which should be applied to 66 | /// the position. For instance, in KBP vs K endgames, a scaling function 67 | /// which checks for draws with rook pawns and wrong-colored bishops. 68 | 69 | inline ScaleFactor Entry::scale_factor(const Position& pos, Color c) const { 70 | 71 | return !scalingFunction[c] || (*scalingFunction[c])(pos) == SCALE_FACTOR_NONE 72 | ? ScaleFactor(factor[c]) : (*scalingFunction[c])(pos); 73 | } 74 | 75 | extern void init(); 76 | } 77 | 78 | #endif // #ifndef MATERIAL_H_INCLUDED 79 | -------------------------------------------------------------------------------- /src/misc.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "misc.h" 25 | #include "thread.h" 26 | 27 | using namespace std; 28 | 29 | /// Version number. If Version is left empty, then compile date, in the 30 | /// format DD-MM-YY, is shown in engine_info. 31 | static const string Version = ""; 32 | 33 | 34 | /// engine_info() returns the full name of the current Challenger version. This 35 | /// will be either "Challenger DD-MM-YY" (where DD-MM-YY is the date when 36 | /// the program was compiled) or "Challenger ", depending on whether 37 | /// Version is empty. 38 | 39 | const string engine_info(bool to_uci) { 40 | 41 | const string months("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"); 42 | string month, day, year; 43 | stringstream s, date(__DATE__); // From compiler, format is "Sep 21 2008" 44 | 45 | s << "Challenger " << Version << setfill('0'); 46 | 47 | if (Version.empty()) 48 | { 49 | date >> month >> day >> year; 50 | s << setw(2) << day << setw(2) << (1 + months.find(month) / 4) << year.substr(2); 51 | } 52 | 53 | s << (Is64Bit ? " 64" : "") 54 | << (HasPopCnt ? " SSE4.2" : "") 55 | << (to_uci ? "\nid author ": " by ") 56 | << "grefen"; 57 | 58 | return s.str(); 59 | } 60 | 61 | 62 | /// Debug functions used mainly to collect run-time statistics 63 | 64 | static uint64_t hits[2], means[2]; 65 | 66 | void dbg_hit_on(bool b) { hits[0]++; if (b) hits[1]++; } 67 | void dbg_hit_on_c(bool c, bool b) { if (c) dbg_hit_on(b); } 68 | void dbg_mean_of(int v) { means[0]++; means[1] += v; } 69 | 70 | void dbg_print() { 71 | 72 | if (hits[0]) 73 | cerr << "Total " << hits[0] << " Hits " << hits[1] 74 | << " hit rate (%) " << 100 * hits[1] / hits[0] << endl; 75 | 76 | if (means[0]) 77 | cerr << "Total " << means[0] << " Mean " 78 | << (float)means[1] / means[0] << endl; 79 | } 80 | 81 | 82 | /// Our fancy logging facility. The trick here is to replace cin.rdbuf() and 83 | /// cout.rdbuf() with two Tie objects that tie cin and cout to a file stream. We 84 | /// can toggle the logging of std::cout and std:cin at runtime while preserving 85 | /// usual i/o functionality and without changing a single line of code! 86 | /// Idea from http://groups.google.com/group/comp.lang.c++/msg/1d941c0f26ea0d81 87 | 88 | struct Tie: public streambuf { // MSVC requires splitted streambuf for cin and cout 89 | 90 | Tie(streambuf* b, ofstream* f) : buf(b), file(f) {} 91 | 92 | int sync() { return file->rdbuf()->pubsync(), buf->pubsync(); } 93 | int overflow(int c) { return log(buf->sputc((char)c), "<< "); } 94 | int underflow() { return buf->sgetc(); } 95 | int uflow() { return log(buf->sbumpc(), ">> "); } 96 | 97 | streambuf* buf; 98 | ofstream* file; 99 | 100 | int log(int c, const char* prefix) { 101 | 102 | static int last = '\n'; 103 | 104 | if (last == '\n') 105 | file->rdbuf()->sputn(prefix, 3); 106 | 107 | return last = file->rdbuf()->sputc((char)c); 108 | } 109 | }; 110 | 111 | class Logger { 112 | 113 | Logger() : in(cin.rdbuf(), &file), out(cout.rdbuf(), &file) {} 114 | ~Logger() { start(false); } 115 | 116 | ofstream file; 117 | Tie in, out; 118 | 119 | public: 120 | static void start(bool b) { 121 | 122 | static Logger l; 123 | 124 | if (b && !l.file.is_open()) 125 | { 126 | l.file.open("io_log.txt", ifstream::out | ifstream::app); 127 | cin.rdbuf(&l.in); 128 | cout.rdbuf(&l.out); 129 | } 130 | else if (!b && l.file.is_open()) 131 | { 132 | cout.rdbuf(l.out.buf); 133 | cin.rdbuf(l.in.buf); 134 | l.file.close(); 135 | } 136 | } 137 | }; 138 | 139 | 140 | /// Used to serialize access to std::cout to avoid multiple threads to write at 141 | /// the same time. 142 | 143 | std::ostream& operator<<(std::ostream& os, SyncCout sc) { 144 | 145 | static Mutex m; 146 | 147 | if (sc == io_lock) 148 | m.lock(); 149 | 150 | if (sc == io_unlock) 151 | m.unlock(); 152 | 153 | return os; 154 | } 155 | 156 | 157 | /// Trampoline helper to avoid moving Logger to misc.h 158 | void start_logger(bool b) { Logger::start(b); } 159 | 160 | 161 | /// timed_wait() waits for msec milliseconds. It is mainly an helper to wrap 162 | /// conversion from milliseconds to struct timespec, as used by pthreads. 163 | 164 | void timed_wait(WaitCondition& sleepCond, Lock& sleepLock, int msec) { 165 | 166 | #ifdef _WIN32 167 | int tm = msec; 168 | #else 169 | timespec ts, *tm = &ts; 170 | uint64_t ms = Time::now() + msec; 171 | 172 | ts.tv_sec = ms / 1000; 173 | ts.tv_nsec = (ms % 1000) * 1000000LL; 174 | #endif 175 | 176 | cond_timedwait(sleepCond, sleepLock, tm); 177 | } 178 | 179 | 180 | /// prefetch() preloads the given address in L1/L2 cache. This is a non 181 | /// blocking function and do not stalls the CPU waiting for data to be 182 | /// loaded from memory, that can be quite slow. 183 | #ifdef NO_PREFETCH 184 | 185 | void prefetch(char*) {} 186 | 187 | #else 188 | 189 | void prefetch(char* addr) { 190 | 191 | # if defined(__INTEL_COMPILER) 192 | // This hack prevents prefetches to be optimized away by 193 | // Intel compiler. Both MSVC and gcc seems not affected. 194 | __asm__ (""); 195 | # endif 196 | 197 | # if defined(__INTEL_COMPILER) || defined(_MSC_VER) 198 | _mm_prefetch(addr, _MM_HINT_T0); 199 | # else 200 | __builtin_prefetch(addr); 201 | # endif 202 | } 203 | 204 | #endif 205 | -------------------------------------------------------------------------------- /src/misc.h: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef MISC_H_INCLUDED 21 | #define MISC_H_INCLUDED 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include "types.h" 28 | 29 | extern const std::string engine_info(bool to_uci = false); 30 | extern void timed_wait(WaitCondition&, Lock&, int); 31 | extern void prefetch(char* addr); 32 | extern void start_logger(bool b); 33 | 34 | extern void dbg_hit_on(bool b); 35 | extern void dbg_hit_on_c(bool c, bool b); 36 | extern void dbg_mean_of(int v); 37 | extern void dbg_print(); 38 | 39 | 40 | struct Log : public std::ofstream { 41 | Log(const std::string& f = "log.txt") : std::ofstream(f.c_str(), std::ios::out | std::ios::app) {} 42 | ~Log() { if (is_open()) close(); } 43 | }; 44 | 45 | 46 | namespace Time { 47 | typedef int64_t point; 48 | inline point now() { return system_time_to_msec(); } 49 | } 50 | 51 | 52 | template 53 | struct HashTable { 54 | HashTable() : e(Size, Entry()) {} 55 | Entry* operator[](Key k) { return &e[(uint32_t)k & (Size - 1)]; } 56 | 57 | private: 58 | std::vector e; 59 | }; 60 | 61 | 62 | enum SyncCout { io_lock, io_unlock }; 63 | std::ostream& operator<<(std::ostream&, SyncCout); 64 | 65 | #define sync_cout std::cout << io_lock 66 | #define sync_endl std::endl << io_unlock 67 | 68 | #endif // #ifndef MISC_H_INCLUDED 69 | -------------------------------------------------------------------------------- /src/movegen.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grefen/challenger/902e706b33a786796920ffe4c92612f5d3e34bf0/src/movegen.cpp -------------------------------------------------------------------------------- /src/movegen.h: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef MOVEGEN_H_INCLUDED 21 | #define MOVEGEN_H_INCLUDED 22 | 23 | #include "types.h" 24 | 25 | enum GenType { 26 | CAPTURES, 27 | QUIETS, 28 | QUIET_CHECKS, 29 | EVASIONS, 30 | NON_EVASIONS, 31 | LEGAL 32 | }; 33 | 34 | class Position; 35 | 36 | template 37 | ExtMove* generate(const Position& pos, ExtMove* mlist); 38 | 39 | /// The MoveList struct is a simple wrapper around generate(), sometimes comes 40 | /// handy to use this class instead of the low level generate() function. 41 | template 42 | struct MoveList { 43 | 44 | explicit MoveList(const Position& pos) : cur(mlist), last(generate(pos, mlist)) { last->move = MOVE_NONE; } 45 | void operator++() { cur++; } 46 | Move operator*() const { return cur->move; } 47 | size_t size() const { return last - mlist; } 48 | bool contains(Move m) const { 49 | for (const ExtMove* it(mlist); it != last; ++it) if (it->move == m) return true; 50 | return false; 51 | } 52 | 53 | private: 54 | ExtMove mlist[MAX_MOVES]; 55 | ExtMove *cur, *last; 56 | }; 57 | extern bool move_is_legal(const Position& pos, Move move); 58 | extern bool move_is_check(const Position& pos, Move move); 59 | 60 | extern void test_move_gen(Position& pos); 61 | #endif // #ifndef MOVEGEN_H_INCLUDED 62 | -------------------------------------------------------------------------------- /src/movepick.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | 12 | Challenger is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | */ 20 | 21 | #include 22 | 23 | #include "movepick.h" 24 | #include "thread.h" 25 | 26 | namespace { 27 | 28 | enum Stages { 29 | MAIN_SEARCH, CAPTURES_S1, KILLERS_S1, QUIETS_1_S1, QUIETS_2_S1, BAD_CAPTURES_S1, 30 | EVASION, EVASIONS_S2, 31 | QSEARCH_0, CAPTURES_S3, QUIET_CHECKS_S3, 32 | QSEARCH_1, CAPTURES_S4, 33 | PROBCUT, CAPTURES_S5, 34 | RECAPTURE, CAPTURES_S6, 35 | STOP 36 | }; 37 | 38 | // Our insertion sort, guaranteed to be stable, as is needed 39 | void insertion_sort(ExtMove* begin, ExtMove* end) 40 | { 41 | ExtMove tmp, *p, *q; 42 | 43 | for (p = begin + 1; p < end; ++p) 44 | { 45 | tmp = *p; 46 | for (q = p; q != begin && *(q-1) < tmp; --q) 47 | *q = *(q-1); 48 | *q = tmp; 49 | } 50 | } 51 | 52 | // Unary predicate used by std::partition to split positive scores from remaining 53 | // ones so to sort separately the two sets, and with the second sort delayed. 54 | inline bool has_positive_score(const ExtMove& ms) { return ms.score > 0; } 55 | 56 | // Picks and moves to the front the best move in the range [begin, end), 57 | // it is faster than sorting all the moves in advance when moves are few, as 58 | // normally are the possible captures. 59 | inline ExtMove* pick_best(ExtMove* begin, ExtMove* end) 60 | { 61 | std::swap(*begin, *std::max_element(begin, end)); 62 | return begin; 63 | } 64 | } 65 | 66 | 67 | /// Constructors of the MovePicker class. As arguments we pass information 68 | /// to help it to return the presumably good moves first, to decide which 69 | /// moves to return (in the quiescence search, for instance, we only want to 70 | /// search captures, promotions and some checks) and about how important good 71 | /// move ordering is at the current node. 72 | 73 | MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const HistoryStats& h, 74 | Move* cm, Search::Stack* s) : pos(p), history(h), depth(d) { 75 | 76 | assert(d > DEPTH_ZERO); 77 | 78 | cur = end = moves; 79 | endBadCaptures = moves + MAX_MOVES - 1; 80 | countermoves = cm; 81 | ss = s; 82 | 83 | if (p.checkers()) 84 | stage = EVASION; 85 | 86 | else 87 | stage = MAIN_SEARCH; 88 | 89 | ttMove = (ttm && pos.is_pseudo_legal(ttm) ? ttm : MOVE_NONE); 90 | end += (ttMove != MOVE_NONE); 91 | } 92 | 93 | MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const HistoryStats& h, 94 | Square sq) : pos(p), history(h), cur(moves), end(moves) { 95 | 96 | assert(d <= DEPTH_ZERO); 97 | 98 | if (p.checkers()) 99 | stage = EVASION; 100 | 101 | else if (d > DEPTH_QS_NO_CHECKS) 102 | stage = QSEARCH_0; 103 | 104 | else if (d > DEPTH_QS_RECAPTURES) 105 | { 106 | stage = QSEARCH_1; 107 | 108 | // Skip TT move if is not a capture , this avoids qsearch 109 | // tree explosion due to a possible perpetual check or similar rare cases 110 | // when TT table is full. 111 | if (ttm && !pos.is_capture(ttm)) 112 | ttm = MOVE_NONE; 113 | } 114 | else 115 | { 116 | stage = RECAPTURE; 117 | recaptureSquare = sq; 118 | ttm = MOVE_NONE; 119 | } 120 | 121 | ttMove = (ttm && pos.is_pseudo_legal(ttm) ? ttm : MOVE_NONE); 122 | end += (ttMove != MOVE_NONE); 123 | } 124 | 125 | MovePicker::MovePicker(const Position& p, Move ttm, const HistoryStats& h, PieceType pt) 126 | : pos(p), history(h), cur(moves), end(moves) { 127 | 128 | assert(!pos.checkers()); 129 | 130 | stage = PROBCUT; 131 | 132 | // In ProbCut we generate only captures better than parent's captured piece 133 | captureThreshold = PieceValue[MG][pt]; 134 | ttMove = (ttm && pos.is_pseudo_legal(ttm) ? ttm : MOVE_NONE); 135 | 136 | if (ttMove && (!pos.is_capture(ttMove) || pos.see(ttMove) <= captureThreshold)) 137 | ttMove = MOVE_NONE; 138 | 139 | end += (ttMove != MOVE_NONE); 140 | } 141 | 142 | 143 | /// score() assign a numerical move ordering score to each move in a move list. 144 | /// The moves with highest scores will be picked first. 145 | template<> 146 | void MovePicker::score() { 147 | // Winning and equal captures in the main search are ordered by MVV/LVA. 148 | // Suprisingly, this appears to perform slightly better than SEE based 149 | // move ordering. The reason is probably that in a position with a winning 150 | // capture, capturing a more valuable (but sufficiently defended) piece 151 | // first usually doesn't hurt. The opponent will have to recapture, and 152 | // the hanging piece will still be hanging (except in the unusual cases 153 | // where it is possible to recapture with the hanging piece). Exchanging 154 | // big pieces before capturing a hanging piece probably helps to reduce 155 | // the subtree size. 156 | // In main search we want to push captures with negative SEE values to 157 | // badCaptures[] array, but instead of doing it now we delay till when 158 | // the move has been picked up in pick_move_from_list(), this way we save 159 | // some SEE calls in case we get a cutoff (idea from Pablo Vazquez). 160 | Move m; 161 | 162 | for (ExtMove* it = moves; it != end; ++it) 163 | { 164 | m = it->move; 165 | it->score = PieceValue[MG][pos.piece_on(to_sq(m))] 166 | - type_of(pos.piece_moved(m)); 167 | } 168 | } 169 | 170 | template<> 171 | void MovePicker::score() { 172 | 173 | Move m; 174 | 175 | for (ExtMove* it = moves; it != end; ++it) 176 | { 177 | m = it->move; 178 | it->score = history[pos.piece_moved(m)][to_sq(m)]; 179 | } 180 | } 181 | 182 | template<> 183 | void MovePicker::score() { 184 | // Try good captures ordered by MVV/LVA, then non-captures if destination square 185 | // is not under attack, ordered by history value, then bad-captures and quiet 186 | // moves with a negative SEE. This last group is ordered by the SEE score. 187 | Move m; 188 | int seeScore; 189 | 190 | for (ExtMove* it = moves; it != end; ++it) 191 | { 192 | m = it->move; 193 | if ((seeScore = pos.see_sign(m)) < 0) 194 | it->score = seeScore - HistoryStats::Max; // At the bottom 195 | 196 | else if (pos.is_capture(m)) 197 | it->score = PieceValue[MG][pos.piece_on(to_sq(m))] 198 | - type_of(pos.piece_moved(m)) + HistoryStats::Max; 199 | else 200 | it->score = history[pos.piece_moved(m)][to_sq(m)]; 201 | } 202 | } 203 | 204 | 205 | /// generate_next() generates, scores and sorts the next bunch of moves, when 206 | /// there are no more moves to try for the current phase. 207 | 208 | void MovePicker::generate_next() { 209 | 210 | cur = moves; 211 | 212 | switch (++stage) { 213 | 214 | case CAPTURES_S1: case CAPTURES_S3: case CAPTURES_S4: case CAPTURES_S5: case CAPTURES_S6: 215 | end = generate(pos, moves); 216 | score(); 217 | return; 218 | 219 | case KILLERS_S1: 220 | cur = killers; 221 | end = cur + 2; 222 | 223 | killers[0].move = ss->killers[0]; 224 | killers[1].move = ss->killers[1]; 225 | killers[2].move = killers[3].move = MOVE_NONE; 226 | 227 | // Be sure countermoves are different from killers 228 | for (int i = 0; i < 2; ++i) 229 | if (countermoves[i] != cur->move && countermoves[i] != (cur+1)->move) 230 | (end++)->move = countermoves[i]; 231 | 232 | if (countermoves[1] && countermoves[1] == countermoves[0]) // Due to SMP races 233 | killers[3].move = MOVE_NONE; 234 | 235 | return; 236 | 237 | case QUIETS_1_S1: 238 | endQuiets = end = generate(pos, moves); 239 | score(); 240 | end = std::partition(cur, end, has_positive_score); 241 | insertion_sort(cur, end); 242 | return; 243 | 244 | case QUIETS_2_S1: 245 | cur = end; 246 | end = endQuiets; 247 | if (depth >= 3 * ONE_PLY) 248 | insertion_sort(cur, end); 249 | return; 250 | 251 | case BAD_CAPTURES_S1: 252 | // Just pick them in reverse order to get MVV/LVA ordering 253 | cur = moves + MAX_MOVES - 1; 254 | end = endBadCaptures; 255 | return; 256 | 257 | case EVASIONS_S2: 258 | end = generate(pos, moves); 259 | if (end > moves + 1) 260 | score(); 261 | return; 262 | 263 | case QUIET_CHECKS_S3: 264 | end = generate(pos, moves); 265 | return; 266 | 267 | case EVASION: case QSEARCH_0: case QSEARCH_1: case PROBCUT: case RECAPTURE: 268 | stage = STOP; 269 | case STOP: 270 | end = cur + 1; // Avoid another next_phase() call 271 | return; 272 | 273 | default: 274 | assert(false); 275 | } 276 | } 277 | 278 | 279 | /// next_move() is the most important method of the MovePicker class. It returns 280 | /// a new pseudo legal move every time is called, until there are no more moves 281 | /// left. It picks the move with the biggest score from a list of generated moves 282 | /// taking care not returning the ttMove if has already been searched previously. 283 | template<> 284 | Move MovePicker::next_move() { 285 | 286 | Move move; 287 | 288 | while (true) 289 | { 290 | while (cur == end) 291 | generate_next(); 292 | 293 | switch (stage) { 294 | 295 | case MAIN_SEARCH: case EVASION: case QSEARCH_0: case QSEARCH_1: case PROBCUT: 296 | cur++; 297 | return ttMove; 298 | 299 | case CAPTURES_S1: 300 | move = pick_best(cur++, end)->move; 301 | if (move != ttMove) 302 | { 303 | if (pos.see_sign(move) >= 0) 304 | return move; 305 | 306 | // Losing capture, move it to the tail of the array 307 | (endBadCaptures--)->move = move; 308 | } 309 | break; 310 | 311 | case KILLERS_S1: 312 | move = (cur++)->move; 313 | if ( move != MOVE_NONE 314 | && pos.is_pseudo_legal(move) 315 | && move != ttMove 316 | && !pos.is_capture(move)) 317 | return move; 318 | break; 319 | 320 | case QUIETS_1_S1: case QUIETS_2_S1: 321 | move = (cur++)->move; 322 | if ( move != ttMove 323 | && move != killers[0].move 324 | && move != killers[1].move 325 | && move != killers[2].move 326 | && move != killers[3].move) 327 | return move; 328 | break; 329 | 330 | case BAD_CAPTURES_S1: 331 | return (cur--)->move; 332 | 333 | case EVASIONS_S2: case CAPTURES_S3: case CAPTURES_S4: 334 | move = pick_best(cur++, end)->move; 335 | if (move != ttMove) 336 | return move; 337 | break; 338 | 339 | case CAPTURES_S5: 340 | move = pick_best(cur++, end)->move; 341 | if (move != ttMove && pos.see(move) > captureThreshold) 342 | return move; 343 | break; 344 | 345 | case CAPTURES_S6: 346 | move = pick_best(cur++, end)->move; 347 | if (to_sq(move) == recaptureSquare) 348 | return move; 349 | break; 350 | 351 | case QUIET_CHECKS_S3: 352 | move = (cur++)->move; 353 | if (move != ttMove) 354 | return move; 355 | break; 356 | 357 | case STOP: 358 | return MOVE_NONE; 359 | 360 | default: 361 | assert(false); 362 | } 363 | } 364 | } 365 | 366 | 367 | /// Version of next_move() to use at split point nodes where the move is grabbed 368 | /// from the split point's shared MovePicker object. This function is not thread 369 | /// safe so must be lock protected by the caller. 370 | template<> 371 | Move MovePicker::next_move() { return ss->splitPoint->movePicker->next_move(); } 372 | -------------------------------------------------------------------------------- /src/movepick.h: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef MOVEPICK_H_INCLUDED 21 | #define MOVEPICK_H_INCLUDED 22 | 23 | #include // For std::max 24 | #include // For std::memset 25 | 26 | #include "movegen.h" 27 | #include "position.h" 28 | #include "search.h" 29 | #include "types.h" 30 | 31 | 32 | /// The Stats struct stores moves statistics. According to the template parameter 33 | /// the class can store History, Gains and Countermoves. History records how often 34 | /// different moves have been successful or unsuccessful during the current search 35 | /// and is used for reduction and move ordering decisions. Gains records the move's 36 | /// best evaluation gain from one ply to the next and is used for pruning decisions. 37 | /// Countermoves store the move that refute a previous one. Entries are stored 38 | /// according only to moving piece and destination square, hence two moves with 39 | /// different origin but same destination and piece will be considered identical. 40 | template 41 | struct Stats { 42 | 43 | static const Value Max = Value(2000); 44 | 45 | const T* operator[](Piece p) const { return table[p]; } 46 | void clear() { std::memset(table, 0, sizeof(table)); } 47 | 48 | void update(Piece p, Square to, Move m) { 49 | 50 | assert(p < PIECE_NB); 51 | assert(to < SQUARE_NB); 52 | if (m == table[p][to].first) 53 | return; 54 | 55 | table[p][to].second = table[p][to].first; 56 | table[p][to].first = m; 57 | } 58 | 59 | void update(Piece p, Square to, Value v) { 60 | 61 | assert(p < PIECE_NB); 62 | assert(to < SQUARE_NB); 63 | if (Gain) 64 | table[p][to] = std::max(v, table[p][to] - 1); 65 | 66 | else if (abs(table[p][to] + v) < Max) 67 | table[p][to] += v; 68 | } 69 | 70 | private: 71 | T table[PIECE_NB][SQUARE_NB]; 72 | }; 73 | 74 | typedef Stats< true, Value> GainsStats; 75 | typedef Stats HistoryStats; 76 | typedef Stats > CountermovesStats; 77 | 78 | 79 | /// MovePicker class is used to pick one pseudo legal move at a time from the 80 | /// current position. The most important method is next_move(), which returns a 81 | /// new pseudo legal move each time it is called, until there are no moves left, 82 | /// when MOVE_NONE is returned. In order to improve the efficiency of the alpha 83 | /// beta algorithm, MovePicker attempts to return the moves which are most likely 84 | /// to get a cut-off first. 85 | 86 | class MovePicker { 87 | 88 | MovePicker& operator=(const MovePicker&); // Silence a warning under MSVC 89 | 90 | public: 91 | MovePicker(const Position&, Move, Depth, const HistoryStats&, Square); 92 | MovePicker(const Position&, Move, const HistoryStats&, PieceType); 93 | MovePicker(const Position&, Move, Depth, const HistoryStats&, Move*, Search::Stack*); 94 | 95 | template Move next_move(); 96 | 97 | private: 98 | template void score(); 99 | void generate_next(); 100 | 101 | const Position& pos; 102 | const HistoryStats& history; 103 | Search::Stack* ss; 104 | Move* countermoves; 105 | Depth depth; 106 | Move ttMove; 107 | ExtMove killers[4]; 108 | Square recaptureSquare; 109 | int captureThreshold, stage; 110 | ExtMove *cur, *end, *endQuiets, *endBadCaptures; 111 | ExtMove moves[MAX_MOVES]; 112 | }; 113 | 114 | #endif // #ifndef MOVEPICK_H_INCLUDED 115 | -------------------------------------------------------------------------------- /src/notation.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grefen/challenger/902e706b33a786796920ffe4c92612f5d3e34bf0/src/notation.cpp -------------------------------------------------------------------------------- /src/notation.h: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef NOTATION_H_INCLUDED 21 | #define NOTATION_H_INCLUDED 22 | 23 | #include 24 | 25 | #include "types.h" 26 | 27 | class Position; 28 | 29 | std::string score_to_uci(Value v, Value alpha = -VALUE_INFINITE, Value beta = VALUE_INFINITE); 30 | Move move_from_uci(const Position& pos, std::string& str); 31 | const std::string move_to_uci(Move m, bool chess960); 32 | const std::string move_to_san(Position& pos, Move m); 33 | std::string pretty_pv(Position& pos, int depth, Value score, int64_t msecs, Move pv[]); 34 | 35 | extern std::string move_to_chinese(const Position& pos, Move m); 36 | 37 | #endif // #ifndef NOTATION_H_INCLUDED 38 | -------------------------------------------------------------------------------- /src/pawns.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grefen/challenger/902e706b33a786796920ffe4c92612f5d3e34bf0/src/pawns.cpp -------------------------------------------------------------------------------- /src/pawns.h: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef PAWNS_H_INCLUDED 21 | #define PAWNS_H_INCLUDED 22 | 23 | #include "misc.h" 24 | #include "position.h" 25 | #include "types.h" 26 | 27 | namespace Pawns { 28 | 29 | /// Pawns::Entry contains various information about a pawn structure. Currently, 30 | /// it only includes a middle game and end game pawn structure evaluation, and a 31 | /// bitboard of passed pawns. We may want to add further information in the future. 32 | /// A lookup to the pawn hash table (performed by calling the probe function) 33 | /// returns a pointer to an Entry object. 34 | 35 | struct Entry { 36 | 37 | Score pawns_value() const { return value; } 38 | Bitboard pawn_attacks(Color c) const { return pawnAttacks[c]; } 39 | Bitboard passed_pawns(Color c) const { return passedPawns[c]; } 40 | int semiopen(Color c, File f) const { return semiopenFiles[c] & (1 << int(f)); } 41 | int semiopen_on_side(Color c, File f, bool left) const { 42 | 43 | return semiopenFiles[c] & (left ? ((1 << int(f)) - 1) : ~((1 << int(f+1)) - 1)); 44 | } 45 | 46 | 47 | Key key; 48 | Bitboard passedPawns[COLOR_NB]; 49 | Bitboard pawnAttacks[COLOR_NB]; 50 | Square kingSquares[COLOR_NB]; 51 | int minKPdistance[COLOR_NB]; 52 | Score value; 53 | int semiopenFiles[COLOR_NB]; 54 | Score kingSafety[COLOR_NB]; 55 | int pawnsOnSquares[COLOR_NB][COLOR_NB]; 56 | }; 57 | 58 | typedef HashTable Table; 59 | 60 | Entry* probe(const Position& pos, Table& entries); 61 | 62 | } 63 | 64 | #endif // #ifndef PAWNS_H_INCLUDED 65 | -------------------------------------------------------------------------------- /src/platform.h: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chinese chess playing engine based on Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef PLATFORM_H_INCLUDED 21 | #define PLATFORM_H_INCLUDED 22 | 23 | #ifdef _MSC_VER 24 | 25 | // Disable some silly and noisy warning from MSVC compiler 26 | #pragma warning(disable: 4127) // Conditional expression is constant 27 | #pragma warning(disable: 4146) // Unary minus operator applied to unsigned type 28 | #pragma warning(disable: 4800) // Forcing value to bool 'true' or 'false' 29 | #pragma warning(disable: 4996) // Function _ftime() may be unsafe 30 | 31 | // MSVC does not support 32 | typedef signed __int8 int8_t; 33 | typedef unsigned __int8 uint8_t; 34 | typedef signed __int16 int16_t; 35 | typedef unsigned __int16 uint16_t; 36 | typedef signed __int32 int32_t; 37 | typedef unsigned __int32 uint32_t; 38 | typedef signed __int64 int64_t; 39 | typedef unsigned __int64 uint64_t; 40 | 41 | #else 42 | # include 43 | #endif 44 | 45 | #ifndef _WIN32 // Linux - Unix 46 | 47 | # include 48 | 49 | inline int64_t system_time_to_msec() { 50 | timeval t; 51 | gettimeofday(&t, NULL); 52 | return t.tv_sec * 1000LL + t.tv_usec / 1000; 53 | } 54 | 55 | # include 56 | typedef pthread_mutex_t Lock; 57 | typedef pthread_cond_t WaitCondition; 58 | typedef pthread_t NativeHandle; 59 | typedef void*(*pt_start_fn)(void*); 60 | 61 | # define lock_init(x) pthread_mutex_init(&(x), NULL) 62 | # define lock_grab(x) pthread_mutex_lock(&(x)) 63 | # define lock_release(x) pthread_mutex_unlock(&(x)) 64 | # define lock_destroy(x) pthread_mutex_destroy(&(x)) 65 | # define cond_destroy(x) pthread_cond_destroy(&(x)) 66 | # define cond_init(x) pthread_cond_init(&(x), NULL) 67 | # define cond_signal(x) pthread_cond_signal(&(x)) 68 | # define cond_wait(x,y) pthread_cond_wait(&(x),&(y)) 69 | # define cond_timedwait(x,y,z) pthread_cond_timedwait(&(x),&(y),z) 70 | # define thread_create(x,f,t) pthread_create(&(x),NULL,(pt_start_fn)f,t) 71 | # define thread_join(x) pthread_join(x, NULL) 72 | 73 | #else // Windows and MinGW 74 | 75 | # include 76 | 77 | inline int64_t system_time_to_msec() { 78 | _timeb t; 79 | _ftime(&t); 80 | return t.time * 1000LL + t.millitm; 81 | } 82 | 83 | #ifndef NOMINMAX 84 | # define NOMINMAX // disable macros min() and max() 85 | #endif 86 | 87 | #define WIN32_LEAN_AND_MEAN 88 | #include 89 | #undef WIN32_LEAN_AND_MEAN 90 | #undef NOMINMAX 91 | 92 | // We use critical sections on Windows to support Windows XP and older versions, 93 | // unfortunatly cond_wait() is racy between lock_release() and WaitForSingleObject() 94 | // but apart from this they have the same speed performance of SRW locks. 95 | typedef CRITICAL_SECTION Lock; 96 | typedef HANDLE WaitCondition; 97 | typedef HANDLE NativeHandle; 98 | 99 | // On Windows 95 and 98 parameter lpThreadId my not be null 100 | inline DWORD* dwWin9xKludge() { static DWORD dw; return &dw; } 101 | 102 | # define lock_init(x) InitializeCriticalSection(&(x)) 103 | # define lock_grab(x) EnterCriticalSection(&(x)) 104 | # define lock_release(x) LeaveCriticalSection(&(x)) 105 | # define lock_destroy(x) DeleteCriticalSection(&(x)) 106 | # define cond_init(x) { x = CreateEvent(0, FALSE, FALSE, 0); } 107 | # define cond_destroy(x) CloseHandle(x) 108 | # define cond_signal(x) SetEvent(x) 109 | # define cond_wait(x,y) { lock_release(y); WaitForSingleObject(x, INFINITE); lock_grab(y); } 110 | # define cond_timedwait(x,y,z) { lock_release(y); WaitForSingleObject(x,z); lock_grab(y); } 111 | # define thread_create(x,f,t) (x = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)f,t,0,dwWin9xKludge())) 112 | # define thread_join(x) { WaitForSingleObject(x, INFINITE); CloseHandle(x); } 113 | 114 | #endif 115 | 116 | #endif // #ifndef PLATFORM_H_INCLUDED 117 | -------------------------------------------------------------------------------- /src/position.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grefen/challenger/902e706b33a786796920ffe4c92612f5d3e34bf0/src/position.cpp -------------------------------------------------------------------------------- /src/position.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grefen/challenger/902e706b33a786796920ffe4c92612f5d3e34bf0/src/position.h -------------------------------------------------------------------------------- /src/psqtab.h: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef PSQTAB_H_INCLUDED 21 | #define PSQTAB_H_INCLUDED 22 | 23 | #include "types.h" 24 | 25 | #define S(mg, eg) make_score(mg, eg) 26 | 27 | 28 | /// PSQT[PieceType][Square] contains Piece-Square scores. For each piece type on 29 | /// a given square a (midgame, endgame) score pair is assigned. PSQT is defined 30 | /// for white side, for black side the tables are symmetric. 31 | //PAWN, BISHOP, ADVISOR, KNIGHT, CANNON, ROOK, KING 32 | #if 1 33 | static Score PSQT[PIECE_TYPE_NB][SQUARE_NB] = { 34 | { }, 35 | { // Pawn 36 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 37 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 38 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 39 | S(0 , 8), S( 0, 0), S(-14,8), S( 0, 0), S(20,8), S( 0, 0), S(-14,8), S( 0, 0), S( 0, 8), 40 | S(0, 8), S( 0, 0), S( 0, 8), S( 0, 0), S(20,8), S( 0, 0), S( 0, 8), S( 0, 0), S( 0, 8), 41 | 42 | S( 4,8), S( 4,8), S( 9,8), S(14,8), S(20,8), S(14,8), S( 9,8), S( 4,8), S( 4,8), 43 | S( 4,8), S( 9,8), S(14,8), S(14,8), S(24,8), S(14,8), S(14,8), S( 9,8), S( 4,8), 44 | S( 4,8), S( 9,8), S(14,8), S(17,8), S(24,8), S(17,8), S(14,8), S( 9,8), S( 4,8), 45 | S(-20,8), S( 9,8), S(17,8), S(24,8), S(34,8), S(24,8), S(17,8), S( 9,8), S(-20,8), 46 | S(-30,-18), S(-16,-18), S( 0,-18), S( 0,-8), S( 0,-8), S( 0,-8), S( 0,-18), S(-16,-18 ), S(-30,-18) 47 | }, 48 | {//BISHOP 49 | S( 0, 0), S( 0, 0), S(12, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 12, 0), S( 0, 0), S( 0, 0), 50 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 51 | S(8, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(17, 4), S( 0, 0), S( 0, 0), S( 0, 0), S( 8,0), 52 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 53 | S( 0, 0), S( 0, 0), S(8, 0), S( 0, 0), S(0, 0), S( 0, 0), S(8, 0), S( 0, 0), S( 0, 0), 54 | 55 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 56 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 57 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 58 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 59 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0) 60 | }, 61 | 62 | {//ADVISOR 63 | S( 0, 0), S( 0, 0), S( 0, 0), S(8, 0), S(0, 0), S(8, 0), S( 0, 0), S( 0, 0), S( 0, 0), 64 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(17, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 65 | S( 0, 0), S( 0, 0), S( 0, 0), S(-8, 0), S(0, 0), S(-8, 0), S( 0, 0), S( 0, 0), S( 0, 0), 66 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 67 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 68 | 69 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 70 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 71 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 72 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 73 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0) 74 | }, 75 | 76 | {//KNIGHT 77 | S(-135,-104), S(-107,-79), S(-80,-55), S(-25,-17), S(-67,-42), S(-25,-17), S(-80,-55), S(-107,-79), S(-135,-104), 78 | S( -93, -79), S( -67,-55), S(-53, -55), S(-15,-17), S(-193,-104), S(-15,-17), S(-53, -55), S( -67,-55), S( -93, -79), 79 | S( -23, -55), S( -25,-30), S( 1, -6), S( 1, -6), S(-25,-17), S( 1, -6), S( 1, -6), S( -25,-30), S( -23, -55), 80 | S( -25, -42), S( 1,-17), S( 1,-17), S( 1,-17), S( 27, 5), S( 1,-17), S( 1,-17), S( 1,-17), S( -25, -42), 81 | S( -25, -42), S( 13, 5), S( 27, 5), S( 27, 5), S( 27, 5), S( 27, 5), S( 27, 5), S( 13, 5), S( -25, -42), 82 | 83 | S( -11, -42), S( 27, 5), S( 27, 5), S(27, 5), S(41,18), S( 27, 5), S( 27, 5), S( 27, 5), S( -11, -42), 84 | S( 13,-30), S(41, 18), S( 27, 5), S(41, 18), S( 27, 5), S( 41,18), S( 27, 5), S( 41, 18), S( 13, -30), 85 | S( 13,-30), S( 27, 5), S( 27, 5), S(45 ,18), S( 27, 5), S( 45,18), S( 27, 5), S( 27, 5), S( 13, -30), 86 | S( 13,-30), S( 27, 5), S( 45, 18), S( 27, 5), S( 27, 5), S( 27, 5), S( 45, 18), S( 27, 5), S( 13, -30), 87 | S( 13,-30), S( 13,-17), S( 13,-17), S( 13, 5), S( 13, 5), S( 13, 5), S( 13,-17), S( 13,-17), S( 13, -30) 88 | }, 89 | 90 | {//CANNON 91 | S(8,-8), S(8,-6), S(8,-6), S(8, 18), S(8, 16), S(8, 18), S(8,-6), S( 8,-6), S(8,-8), 92 | S(8,-6), S(8,-6), S(8,-6), S(8, 18), S(8, 16), S(8, 18), S(8,-6), S( 8,-6), S(8,-6), 93 | S(8,-6), S(8, -6),S(18, 16),S(18, 16),S(28, 18),S(18, 16), S(18, 6), S(8, -6), S(8,-6), 94 | S(8,-6), S(8, -6), S(8, -6), S(8, 18), S(18, 18), S(8, 18), S(8, -6), S(8, -6), S(8,-6), 95 | S(-8,-6), S(8, -6), S(-8, -6), S(-8, 18), S(18, 18), S(-8, 18), S(-8, -6), S(8, -6), S(-8,-6), 96 | 97 | S(8,-6), S(8, -6), S(8, -6), S(8, -6), S(28, 18), S(8, -6), S(8, -6), S( 8, -6), S(8,-6), 98 | S(8, -6), S(8, -6), S(8, -6), S(8, -6), S(28, 18), S(8, -6), S(8, -6), S( 8, -6), S(8, -6), 99 | S(8, 6), S(8, 6), S(8, -6), S(8,-18), S(8,-30), S(8,-18), S(8, -6), S(8, 6), S(8, 6), 100 | S(8, 6), S(8, 6), S(8, -6), S(8,-30), S(8,-30), S(8,-30), S(8, -6), S(8, 6), S(8, 6), 101 | S(8, 18), S(8, 18), S(8, 6), S(8,-30), S(8,-30), S(8,-30), S(8, 6), S(8, 18), S(8, 18) 102 | }, 103 | {//ROOK 104 | S(-12, 3), S(10, 3), S(6, 3), S(10, 3), S(2, 3), S(10, 3), S(6, 3), S(10, 3), S(-12, 3), 105 | S(6, 3), S(11, 3), S(6, 3), S(12, 3), S(2, 3), S(12, 3), S(6, 3), S(11, 3), S(6, 3), 106 | S(7, 3), S(12, 3), S(6, 3), S(12, 3), S(2, 3), S(12, 3), S(6, 3), S(12, 3), S(7, 3), 107 | S(7, 3), S(13, 3), S(6, 3), S(12, 3), S(2, 3), S(12, 3), S(6, 3), S(13, 3), S(7, 3), 108 | S(7, 3), S(17, 3), S(17, 3), S(17, 3), S(17, 3), S(17, 3), S(17, 3), S(17, 3), S(7, 3), 109 | 110 | S(7, 3), S(15, 3), S(15, 3), S(16, 3), S(16, 3), S(16, 3), S(15, 3), S(15, 3), S(7, 3), 111 | S(7, 3), S(17, 3), S(22, 3), S(22, 3), S(22, 3), S(22, 3), S(22, 3), S(17, 3), S(7, 3), 112 | S(7, 3), S(12, 3), S(10, 3), S(12, 3), S(12, 3), S(12, 3), S(12, 3), S(12, 3), S(7, 3), 113 | S(7, 3), S(15, 3), S(12, 3), S(12, 3), S(62, 3), S(12, 3), S(12, 3), S(15, 3), S(7, 3), 114 | S(7, 3), S(12, 3), S(12, 3), S(42, 3), S(52, 3), S(42, 3), S(12, 3), S(12, 3), S(7, 3) 115 | }, 116 | {//KING 117 | S( 0, 0), S( 0, 0), S( 0, 0), S(287,222), S(287,222), S(287,222), S( 0, 0), S( 0, 0), S( 0, 0), 118 | S( 0, 0), S( 0, 0), S( 0, 0), S(190,193), S(142,193), S(190,193), S( 0, 0), S( 0, 0), S( 0, 0), 119 | S( 0, 0), S( 0, 0), S( 0, 0), S(94, 18), S(21,18), S(94, 18), S( 0, 0), S( 0, 0), S( 0, 0), 120 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 121 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 122 | 123 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 124 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 125 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 126 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 127 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0) 128 | } 129 | }; 130 | #endif 131 | #if 0 132 | 133 | static Score PSQT[PIECE_TYPE_NB][SQUARE_NB] = { 134 | { }, 135 | { // Pawn 136 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 137 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 138 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 139 | S( 7, 0), S( 0, 0), S( 7, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 7, 0), S( 0, 0), S( 7, 0), 140 | S( 7, 0), S( 0, 0), S(13, 0), S( 0, 0), S(0, 0), S( 0, 0), S(13, 0), S( 0, 0), S( 7, 0), 141 | 142 | S(19, 0), S(27, 0), S(31, 0), S(44, 0), S(49, 0), S(44, 0), S(31, 0), S( 27, 0), S( 19, 0), 143 | S(29, 0), S(36, 0), S(39, 0), S(49, 0), S(51, 0), S(49, 0), S(39, 0), S( 36, 0), S( 29, 0), 144 | S(29, 0), S(39, 0), S(54, 0), S(64, 0), S(64, 0), S(64, 0), S(54, 0), S( 39, 0), S( 29, 0), 145 | S(29, 0), S(39, 0), S(59, 0), S(74, 0), S(79, 0), S(74, 0), S(59, 0), S( 39, 0), S( 29, 0), 146 | S( 9, 0), S( 9, 0), S( 9, 0), S(11, 0), S(13, 0), S(11, 0), S( 9, 0), S( 9, 0), S( 9, 0) 147 | }, 148 | {//BISHOP 149 | S( 0, 0), S( 0, 0), S( 25,0), S( 0, 0), S(0, 0), S( 0, 0), S(25, 0), S( 0, 0), S( 0, 0), 150 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 151 | S(23, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(28, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(23, 0), 152 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 153 | S( 0, 0), S( 0, 0), S(25, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 25,0), S( 0, 0), S( 0, 0), 154 | 155 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 156 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 157 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 158 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 159 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0) 160 | }, 161 | 162 | {//ADVISOR 163 | S( 0, 0), S( 0, 0), S( 0, 0), S(27, 0), S(0, 0), S(27, 0), S( 0, 0), S( 0, 0), S( 0, 0), 164 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(30, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 165 | S( 0, 0), S( 0, 0), S( 0, 0), S(27, 0), S(0, 0), S(27, 0), S( 0, 0), S( 0, 0), S( 0, 0), 166 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 167 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 168 | 169 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 170 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 171 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 172 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 173 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0) 174 | }, 175 | 176 | {//KNIGHT 177 | S(88, 0), S(85, 0), S(90, 0), S(88, 0), S(90, 0), S(88, 0), S(90, 0), S(85, 0), S(88, 0), 178 | S(85, 0), S(90, 0), S(92, 0), S(93, 0), S(78, 0), S(93, 0), S(92, 0), S(90, 0), S(85, 0), 179 | S(93, 0), S(92, 0), S(94, 0), S(95, 0), S(92, 0), S(95, 0), S(94, 0), S(92, 0), S(93, 0), 180 | S(92, 0), S(94, 0), S(98, 0), S(95, 0), S(98, 0), S(95, 0), S(98, 0), S(94, 0), S(92, 0), 181 | S(90, 0), S(98, 0), S(101,0), S(102,0), S(103, 0), S(102,0), S(101,0), S(98, 0), S(90, 0), 182 | 183 | S(90, 0), S(100, 0), S(99, 0), S(103, 0), S(104, 0),S(103, 0),S(99, 0), S(100, 0), S(90, 0), 184 | S(93, 0), S(108, 0), S(100, 0),S(107,0), S(100, 0),S(107,0), S(100, 0),S(108, 0), S(93, 0), 185 | S(92, 0), S(98, 0), S(99, 0), S(103, 0), S(99, 0), S(103, 0),S(99, 0), S(98, 0), S(92, 0), 186 | S(90, 0), S(96, 0), S(103, 0),S(97, 0), S(94, 0), S(97, 0), S(103, 0),S(96, 0), S(90, 0), 187 | S(90, 0), S(90, 0), S(90, 0), S(96, 0), S(90, 0), S(96, 0), S(90, 0), S(90, 0), S(90, 0) 188 | }, 189 | 190 | {//CANNON 191 | 192 | S(96, 0), S( 96, 0), S(97, 0), S(99, 0), S(99, 0), S(99, 0), S( 97, 0), S(96, 0), S(96, 0), 193 | S(96, 0), S( 97, 0), S(98, 0), S(98, 0), S(98, 0), S(98, 0), S( 98, 0), S(97, 0), S(96, 0), 194 | S(97, 0), S(96, 0), S(100, 0), S(99, 0), S(101, 0), S(99, 0), S(100, 0), S(96, 0), S(97, 0), 195 | S(96, 0), S(96, 0), S(96, 0), S(96, 0), S(96, 0), S(96, 0), S(96, 0), S(96, 0), S(96, 0), 196 | S(95, 0), S(96, 0), S(99, 0), S(96, 0), S(100, 0), S(96, 0), S(99, 0), S(96, 0), S(95, 0), 197 | 198 | S(96, 0), S(96, 0), S(96, 0), S(96, 0), S(100, 0),S(96, 0), S(96, 0), S(96, 0), S(96, 0), 199 | S(96, 0), S(99, 0), S(99, 0), S(98, 0), S(100, 0), S(98, 0), S(99, 0), S(99, 0), S(96, 0), 200 | S(97, 0), S(97, 0), S(96, 0), S(91, 0), S(92, 0), S(91, 0), S(96, 0), S(97, 0), S(97, 0), 201 | S(98, 0), S(98, 0), S(96, 0), S(92, 0), S(89, 0), S(92, 0), S(96, 0), S(98, 0), S(98, 0), 202 | S(100, 0), S(100, 0), S(96, 0), S(91, 0), S(90, 0), S(91, 0), S(96, 0), S(100, 0), S(100, 0) 203 | }, 204 | {//ROOK 205 | 206 | S(194, 0), S(206, 0), S(204, 0), S(212, 0), S(200, 0), S(212, 0), S(204, 0), S(206, 0), S(194, 0), 207 | S(200, 0), S(208, 0), S(206, 0), S(212, 0), S(200, 0), S(212, 0), S(206, 0), S(208, 0), S(200, 0), 208 | S(198, 0), S(208, 0), S(204, 0), S(212, 0), S(212, 0), S(212, 0), S(204, 0), S(208, 0), S(198, 0), 209 | S(204, 0), S(209, 0), S(204, 0), S(212, 0), S(214, 0), S(212, 0), S(204, 0), S(209, 0), S(204, 0), 210 | S(208, 0), S(212, 0), S(212, 0), S(214, 0), S(215, 0), S(214, 0), S(212, 0), S(212, 0), S(208, 0), 211 | 212 | 213 | S(208, 0), S(211, 0), S(211, 0), S(214, 0), S(215, 0), S(214, 0), S(211, 0), S(211, 0), S(208, 0), 214 | S(206, 0), S(213, 0), S(213, 0), S(216, 0), S(216, 0), S(216, 0), S(213, 0), S(213, 0), S(206, 0), 215 | S(206, 0), S(208, 0), S(207, 0), S(214, 0), S(216, 0), S(214, 0), S(207, 0), S(208, 0), S(206, 0), 216 | S(206, 0), S(212, 0), S(209, 0), S(216, 0), S(233, 0), S(216, 0), S(209, 0), S(212, 0), S(206, 0), 217 | S(206, 0), S(208, 0), S(207, 0), S(213, 0), S(214, 0), S(213, 0), S(207, 0), S(208, 0), S(206, 0) 218 | }, 219 | {//KING 220 | S( 0, 0), S( 0, 0), S( 0, 0), S(11, 0), S(15, 0), S(11, 0), S( 0, 0), S( 0, 0), S( 0, 0), 221 | S( 0, 0), S( 0, 0), S( 0, 0), S( 2, 0), S(2, 0), S( 2, 0), S( 0, 0), S( 0, 0), S( 0, 0), 222 | S( 0, 0), S( 0, 0), S( 0, 0), S( 1, 0), S(1, 0), S( 1, 0), S( 0, 0), S( 0, 0), S( 0, 0), 223 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 224 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 225 | 226 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 227 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 228 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 229 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), 230 | S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S(0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0) 231 | } 232 | }; 233 | #endif 234 | 235 | 236 | #undef S 237 | 238 | #endif // #ifndef PSQTAB_H_INCLUDED 239 | -------------------------------------------------------------------------------- /src/rkiss.h: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chinese chess playing engine based on Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | This file is based on original code by Heinz van Saanen and is 20 | available under the GNU General Public License as published by 21 | the Free Software Foundation, either version 3 of the License, or 22 | (at your option) any later version. 23 | */ 24 | 25 | #ifndef RKISS_H_INCLUDED 26 | #define RKISS_H_INCLUDED 27 | 28 | #include "types.h" 29 | 30 | /// RKISS is our pseudo random number generator (PRNG) used to compute hash keys. 31 | /// George Marsaglia invented the RNG-Kiss-family in the early 90's. This is a 32 | /// specific version that Heinz van Saanen derived from some public domain code 33 | /// by Bob Jenkins. Following the feature list, as tested by Heinz. 34 | /// 35 | /// - Quite platform independent 36 | /// - Passes ALL dieharder tests! Here *nix sys-rand() e.g. fails miserably:-) 37 | /// - ~12 times faster than my *nix sys-rand() 38 | /// - ~4 times faster than SSE2-version of Mersenne twister 39 | /// - Average cycle length: ~2^126 40 | /// - 64 bit seed 41 | /// - Return doubles with a full 53 bit mantissa 42 | /// - Thread safe 43 | 44 | class RKISS { 45 | 46 | struct S { uint64_t a, b, c, d; } s; // Keep variables always together 47 | 48 | uint64_t rotate(uint64_t x, uint64_t k) const { 49 | return (x << k) | (x >> (64 - k)); 50 | } 51 | 52 | uint64_t rand64() { 53 | 54 | const uint64_t 55 | e = s.a - rotate(s.b, 7); 56 | s.a = s.b ^ rotate(s.c, 13); 57 | s.b = s.c + rotate(s.d, 37); 58 | s.c = s.d + e; 59 | return s.d = e + s.a; 60 | } 61 | 62 | public: 63 | RKISS(int seed = 73) { 64 | 65 | s.a = 0xf1ea5eed; 66 | s.b = s.c = s.d = 0xd4e12c77; 67 | for (int i = 0; i < seed; ++i) // Scramble a few rounds 68 | rand64(); 69 | } 70 | 71 | template T rand() { return T(rand64()); } 72 | }; 73 | 74 | #endif // #ifndef RKISS_H_INCLUDED 75 | -------------------------------------------------------------------------------- /src/search.h: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef SEARCH_H_INCLUDED 21 | #define SEARCH_H_INCLUDED 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "misc.h" 29 | #include "position.h" 30 | #include "types.h" 31 | 32 | struct SplitPoint; 33 | 34 | namespace Search { 35 | 36 | /// The Stack struct keeps track of the information we need to remember from 37 | /// nodes shallower and deeper in the tree during the search. Each search thread 38 | /// has its own array of Stack objects, indexed by the current ply. 39 | 40 | struct Stack { 41 | SplitPoint* splitPoint; 42 | int ply; 43 | Move currentMove; 44 | Move excludedMove; 45 | Move killers[2]; 46 | Depth reduction; 47 | Value staticEval; 48 | Value evalMargin; 49 | int skipNullMove; 50 | int futilityMoveCount; 51 | }; 52 | 53 | 54 | /// RootMove struct is used for moves at the root of the tree. For each root 55 | /// move we store a score, a node count, and a PV (really a refutation in the 56 | /// case of moves which fail low). Score is normally set at -VALUE_INFINITE for 57 | /// all non-pv moves. 58 | struct RootMove { 59 | 60 | RootMove(Move m) : score(-VALUE_INFINITE), prevScore(-VALUE_INFINITE) { 61 | pv.push_back(m); pv.push_back(MOVE_NONE); 62 | } 63 | 64 | bool operator<(const RootMove& m) const { return score > m.score; } // Ascending sort 65 | bool operator==(const Move& m) const { return pv[0] == m; } 66 | 67 | void extract_pv_from_tt(Position& pos); 68 | void insert_pv_in_tt(Position& pos); 69 | 70 | Value score; 71 | Value prevScore; 72 | std::vector pv; 73 | }; 74 | 75 | 76 | /// The LimitsType struct stores information sent by GUI about available time 77 | /// to search the current move, maximum depth/time, if we are in analysis mode 78 | /// or if we have to ponder while is our opponent's side to move. 79 | 80 | struct LimitsType { 81 | 82 | LimitsType() { std::memset(this, 0, sizeof(LimitsType)); } 83 | bool use_time_management() const { return !(mate | movetime | depth | nodes | infinite); } 84 | 85 | int time[COLOR_NB], inc[COLOR_NB], movestogo, depth, nodes, movetime, mate, infinite, ponder; 86 | }; 87 | 88 | 89 | /// The SignalsType struct stores volatile flags updated during the search 90 | /// typically in an async fashion, for instance to stop the search by the GUI. 91 | 92 | struct SignalsType { 93 | bool stopOnPonderhit, firstRootMove, stop, failedLowAtRoot; 94 | }; 95 | 96 | typedef std::auto_ptr > StateStackPtr; 97 | 98 | extern volatile SignalsType Signals; 99 | extern LimitsType Limits; 100 | extern std::vector RootMoves; 101 | extern Position RootPos; 102 | extern Color RootColor; 103 | extern Time::point SearchTime; 104 | extern StateStackPtr SetupStates; 105 | 106 | extern void init(); 107 | extern size_t perft(Position& pos, Depth depth); 108 | extern void think(); 109 | 110 | } // namespace Search 111 | 112 | #endif // #ifndef SEARCH_H_INCLUDED 113 | -------------------------------------------------------------------------------- /src/thread.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #include // For std::count 21 | #include 22 | 23 | #include "movegen.h" 24 | #include "search.h" 25 | #include "thread.h" 26 | #include "ucioption.h" 27 | 28 | using namespace Search; 29 | 30 | ThreadPool Threads; // Global object 31 | 32 | namespace { 33 | 34 | // start_routine() is the C function which is called when a new thread 35 | // is launched. It is a wrapper to the virtual function idle_loop(). 36 | 37 | extern "C" { long start_routine(ThreadBase* th) { th->idle_loop(); return 0; } } 38 | 39 | 40 | // Helpers to launch a thread after creation and joining before delete. Must be 41 | // outside Thread c'tor and d'tor because object shall be fully initialized 42 | // when start_routine (and hence virtual idle_loop) is called and when joining. 43 | 44 | template T* new_thread() { 45 | T* th = new T(); 46 | thread_create(th->handle, start_routine, th); // Will go to sleep 47 | return th; 48 | } 49 | 50 | void delete_thread(ThreadBase* th) { 51 | th->exit = true; // Search must be already finished 52 | th->notify_one(); 53 | thread_join(th->handle); // Wait for thread termination 54 | delete th; 55 | } 56 | 57 | } 58 | 59 | 60 | // ThreadBase::notify_one() wakes up the thread when there is some work to do 61 | 62 | void ThreadBase::notify_one() { 63 | 64 | mutex.lock(); 65 | sleepCondition.notify_one(); 66 | mutex.unlock(); 67 | } 68 | 69 | 70 | // ThreadBase::wait_for() set the thread to sleep until condition 'b' turns true 71 | 72 | void ThreadBase::wait_for(volatile const bool& b) { 73 | 74 | mutex.lock(); 75 | while (!b) sleepCondition.wait(mutex); 76 | mutex.unlock(); 77 | } 78 | 79 | 80 | // Thread c'tor just inits data but does not launch any thread of execution that 81 | // instead will be started only upon c'tor returns. 82 | 83 | Thread::Thread() /* : splitPoints() */ { // Value-initialization bug in MSVC 84 | 85 | searching = false; 86 | maxPly = splitPointsSize = 0; 87 | activeSplitPoint = NULL; 88 | activePosition = NULL; 89 | idx = Threads.size(); 90 | } 91 | 92 | 93 | // TimerThread::idle_loop() is where the timer thread waits msec milliseconds 94 | // and then calls check_time(). If msec is 0 thread sleeps until is woken up. 95 | extern void check_time(); 96 | 97 | void TimerThread::idle_loop() { 98 | 99 | while (!exit) 100 | { 101 | mutex.lock(); 102 | 103 | if (!exit) 104 | sleepCondition.wait_for(mutex, msec ? msec : INT_MAX); 105 | 106 | mutex.unlock(); 107 | 108 | if (msec) 109 | check_time(); 110 | } 111 | } 112 | 113 | 114 | // MainThread::idle_loop() is where the main thread is parked waiting to be started 115 | // when there is a new search. Main thread will launch all the slave threads. 116 | 117 | void MainThread::idle_loop() { 118 | 119 | while (true) 120 | { 121 | mutex.lock(); 122 | 123 | thinking = false; 124 | 125 | while (!thinking && !exit) 126 | { 127 | Threads.sleepCondition.notify_one(); // Wake up UI thread if needed 128 | sleepCondition.wait(mutex); 129 | } 130 | 131 | mutex.unlock(); 132 | 133 | if (exit) 134 | return; 135 | 136 | searching = true; 137 | 138 | Search::think(); 139 | 140 | assert(searching); 141 | 142 | searching = false; 143 | } 144 | } 145 | 146 | 147 | // Thread::cutoff_occurred() checks whether a beta cutoff has occurred in the 148 | // current active split point, or in some ancestor of the split point. 149 | 150 | bool Thread::cutoff_occurred() const { 151 | 152 | for (SplitPoint* sp = activeSplitPoint; sp; sp = sp->parentSplitPoint) 153 | if (sp->cutoff) 154 | return true; 155 | 156 | return false; 157 | } 158 | 159 | 160 | // Thread::is_available_to() checks whether the thread is available to help the 161 | // thread 'master' at a split point. An obvious requirement is that thread must 162 | // be idle. With more than two threads, this is not sufficient: If the thread is 163 | // the master of some split point, it is only available as a slave to the slaves 164 | // which are busy searching the split point at the top of slaves split point 165 | // stack (the "helpful master concept" in YBWC terminology). 166 | 167 | bool Thread::is_available_to(const Thread* master) const { 168 | 169 | if (searching) 170 | return false; 171 | 172 | // Make a local copy to be sure doesn't become zero under our feet while 173 | // testing next condition and so leading to an out of bound access. 174 | int size = splitPointsSize; 175 | 176 | // No split points means that the thread is available as a slave for any 177 | // other thread otherwise apply the "helpful master" concept if possible. 178 | return !size || (splitPoints[size - 1].slavesMask & (1ULL << master->idx)); 179 | } 180 | 181 | 182 | // init() is called at startup to create and launch requested threads, that will 183 | // go immediately to sleep due to 'sleepWhileIdle' set to true. We cannot use 184 | // a c'tor becuase Threads is a static object and we need a fully initialized 185 | // engine at this point due to allocation of Endgames in Thread c'tor. 186 | 187 | void ThreadPool::init() { 188 | 189 | sleepWhileIdle = true; 190 | timer = new_thread(); 191 | push_back(new_thread()); 192 | read_uci_options(); 193 | } 194 | 195 | 196 | // exit() cleanly terminates the threads before the program exits 197 | 198 | void ThreadPool::exit() { 199 | 200 | delete_thread(timer); // As first because check_time() accesses threads data 201 | 202 | for (iterator it = begin(); it != end(); ++it) 203 | delete_thread(*it); 204 | } 205 | 206 | 207 | // read_uci_options() updates internal threads parameters from the corresponding 208 | // UCI options and creates/destroys threads to match the requested number. Thread 209 | // objects are dynamically allocated to avoid creating in advance all possible 210 | // threads, with included pawns and material tables, if only few are used. 211 | 212 | void ThreadPool::read_uci_options() { 213 | 214 | maxThreadsPerSplitPoint = Options["Max Threads per Split Point"]; 215 | minimumSplitDepth = Options["Min Split Depth"] * ONE_PLY; 216 | size_t requested = Options["Threads"]; 217 | 218 | assert(requested > 0); 219 | 220 | // Value 0 has a special meaning: We determine the optimal minimum split depth 221 | // automatically. Anyhow the minimumSplitDepth should never be under 4 plies. 222 | if (!minimumSplitDepth) 223 | minimumSplitDepth = (requested < 8 ? 4 : 7) * ONE_PLY; 224 | else 225 | minimumSplitDepth = std::max(4 * ONE_PLY, minimumSplitDepth); 226 | 227 | while (size() < requested) 228 | push_back(new_thread()); 229 | 230 | while (size() > requested) 231 | { 232 | delete_thread(back()); 233 | pop_back(); 234 | } 235 | } 236 | 237 | 238 | // slave_available() tries to find an idle thread which is available as a slave 239 | // for the thread 'master'. 240 | 241 | Thread* ThreadPool::available_slave(const Thread* master) const { 242 | 243 | for (const_iterator it = begin(); it != end(); ++it) 244 | if ((*it)->is_available_to(master)) 245 | return *it; 246 | 247 | return NULL; 248 | } 249 | 250 | 251 | // split() does the actual work of distributing the work at a node between 252 | // several available threads. If it does not succeed in splitting the node 253 | // (because no idle threads are available), the function immediately returns. 254 | // If splitting is possible, a SplitPoint object is initialized with all the 255 | // data that must be copied to the helper threads and then helper threads are 256 | // told that they have been assigned work. This will cause them to instantly 257 | // leave their idle loops and call search(). When all threads have returned from 258 | // search() then split() returns. 259 | 260 | template 261 | void Thread::split(Position& pos, const Stack* ss, Value alpha, Value beta, Value* bestValue, 262 | Move* bestMove, Depth depth, Move threatMove, int moveCount, 263 | MovePicker* movePicker, int nodeType, bool cutNode) { 264 | 265 | assert(pos.pos_is_ok()); 266 | assert(*bestValue <= alpha && alpha < beta && beta <= VALUE_INFINITE); 267 | assert(*bestValue > -VALUE_INFINITE); 268 | assert(depth >= Threads.minimumSplitDepth); 269 | assert(searching); 270 | assert(splitPointsSize < MAX_SPLITPOINTS_PER_THREAD); 271 | 272 | // Pick the next available split point from the split point stack 273 | SplitPoint& sp = splitPoints[splitPointsSize]; 274 | 275 | sp.masterThread = this; 276 | sp.parentSplitPoint = activeSplitPoint; 277 | sp.slavesMask = 1ULL << idx; 278 | sp.depth = depth; 279 | sp.bestValue = *bestValue; 280 | sp.bestMove = *bestMove; 281 | sp.threatMove = threatMove; 282 | sp.alpha = alpha; 283 | sp.beta = beta; 284 | sp.nodeType = nodeType; 285 | sp.cutNode = cutNode; 286 | sp.movePicker = movePicker; 287 | sp.moveCount = moveCount; 288 | sp.pos = &pos; 289 | sp.nodes = 0; 290 | sp.cutoff = false; 291 | sp.ss = ss; 292 | 293 | // Try to allocate available threads and ask them to start searching setting 294 | // 'searching' flag. This must be done under lock protection to avoid concurrent 295 | // allocation of the same slave by another master. 296 | Threads.mutex.lock(); 297 | sp.mutex.lock(); 298 | 299 | splitPointsSize++; 300 | activeSplitPoint = &sp; 301 | activePosition = NULL; 302 | 303 | size_t slavesCnt = 1; // This thread is always included 304 | Thread* slave; 305 | 306 | while ( (slave = Threads.available_slave(this)) != NULL 307 | && ++slavesCnt <= Threads.maxThreadsPerSplitPoint && !Fake) 308 | { 309 | sp.slavesMask |= 1ULL << slave->idx; 310 | slave->activeSplitPoint = &sp; 311 | slave->searching = true; // Slave leaves idle_loop() 312 | slave->notify_one(); // Could be sleeping 313 | } 314 | 315 | // Everything is set up. The master thread enters the idle loop, from which 316 | // it will instantly launch a search, because its 'searching' flag is set. 317 | // The thread will return from the idle loop when all slaves have finished 318 | // their work at this split point. 319 | if (slavesCnt > 1 || Fake) 320 | { 321 | sp.mutex.unlock(); 322 | Threads.mutex.unlock(); 323 | 324 | Thread::idle_loop(); // Force a call to base class idle_loop() 325 | 326 | // In helpful master concept a master can help only a sub-tree of its split 327 | // point, and because here is all finished is not possible master is booked. 328 | assert(!searching); 329 | assert(!activePosition); 330 | 331 | // We have returned from the idle loop, which means that all threads are 332 | // finished. Note that setting 'searching' and decreasing splitPointsSize is 333 | // done under lock protection to avoid a race with Thread::is_available_to(). 334 | Threads.mutex.lock(); 335 | sp.mutex.lock(); 336 | } 337 | 338 | searching = true; 339 | splitPointsSize--; 340 | activeSplitPoint = sp.parentSplitPoint; 341 | activePosition = &pos; 342 | pos.set_nodes_searched(pos.nodes_searched() + sp.nodes); 343 | *bestMove = sp.bestMove; 344 | *bestValue = sp.bestValue; 345 | 346 | sp.mutex.unlock(); 347 | Threads.mutex.unlock(); 348 | } 349 | 350 | // Explicit template instantiations 351 | template void Thread::split(Position&, const Stack*, Value, Value, Value*, Move*, Depth, Move, int, MovePicker*, int, bool); 352 | template void Thread::split< true>(Position&, const Stack*, Value, Value, Value*, Move*, Depth, Move, int, MovePicker*, int, bool); 353 | 354 | 355 | // wait_for_think_finished() waits for main thread to go to sleep then returns 356 | 357 | void ThreadPool::wait_for_think_finished() { 358 | 359 | MainThread* t = main(); 360 | t->mutex.lock(); 361 | while (t->thinking) sleepCondition.wait(t->mutex); 362 | t->mutex.unlock(); 363 | } 364 | 365 | 366 | // start_thinking() wakes up the main thread sleeping in MainThread::idle_loop() 367 | // so to start a new search, then returns immediately. 368 | 369 | void ThreadPool::start_thinking(const Position& pos, const LimitsType& limits, 370 | const std::vector& searchMoves, StateStackPtr& states) { 371 | wait_for_think_finished(); 372 | 373 | SearchTime = Time::now(); // As early as possible 374 | 375 | Signals.stopOnPonderhit = Signals.firstRootMove = false; 376 | Signals.stop = Signals.failedLowAtRoot = false; 377 | 378 | RootMoves.clear(); 379 | RootPos = pos; 380 | Limits = limits; 381 | if (states.get()) // If we don't set a new position, preserve current state 382 | { 383 | SetupStates = states; // Ownership transfer here 384 | assert(!states.get()); 385 | } 386 | 387 | for (MoveList it(pos); *it; ++it) 388 | if ( searchMoves.empty() 389 | || std::count(searchMoves.begin(), searchMoves.end(), *it)) 390 | RootMoves.push_back(RootMove(*it)); 391 | 392 | main()->thinking = true; 393 | main()->notify_one(); // Starts main thread 394 | } 395 | -------------------------------------------------------------------------------- /src/thread.h: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef THREAD_H_INCLUDED 21 | #define THREAD_H_INCLUDED 22 | 23 | #include 24 | 25 | #include "material.h" 26 | #include "movepick.h" 27 | #include "pawns.h" 28 | #include "position.h" 29 | #include "search.h" 30 | 31 | const int MAX_THREADS = 64; // Because SplitPoint::slavesMask is a uint64_t 32 | const int MAX_SPLITPOINTS_PER_THREAD = 8; 33 | 34 | struct Mutex { 35 | Mutex() { lock_init(l); } 36 | ~Mutex() { lock_destroy(l); } 37 | 38 | void lock() { lock_grab(l); } 39 | void unlock() { lock_release(l); } 40 | 41 | private: 42 | friend struct ConditionVariable; 43 | 44 | Lock l; 45 | }; 46 | 47 | struct ConditionVariable { 48 | ConditionVariable() { cond_init(c); } 49 | ~ConditionVariable() { cond_destroy(c); } 50 | 51 | void wait(Mutex& m) { cond_wait(c, m.l); } 52 | void wait_for(Mutex& m, int ms) { timed_wait(c, m.l, ms); } 53 | void notify_one() { cond_signal(c); } 54 | 55 | private: 56 | WaitCondition c; 57 | }; 58 | 59 | struct Thread; 60 | 61 | struct SplitPoint { 62 | 63 | // Const data after split point has been setup 64 | const Position* pos; 65 | const Search::Stack* ss; 66 | Thread* masterThread; 67 | Depth depth; 68 | Value beta; 69 | int nodeType; 70 | Move threatMove; 71 | bool cutNode; 72 | 73 | // Const pointers to shared data 74 | MovePicker* movePicker; 75 | SplitPoint* parentSplitPoint; 76 | 77 | // Shared data 78 | Mutex mutex; 79 | volatile uint64_t slavesMask; 80 | volatile int64_t nodes; 81 | volatile Value alpha; 82 | volatile Value bestValue; 83 | volatile Move bestMove; 84 | volatile int moveCount; 85 | volatile bool cutoff; 86 | }; 87 | 88 | 89 | /// ThreadBase struct is the base of the hierarchy from where we derive all the 90 | /// specialized thread classes. 91 | 92 | struct ThreadBase { 93 | 94 | ThreadBase() : exit(false) {} 95 | virtual ~ThreadBase() {} 96 | virtual void idle_loop() = 0; 97 | void notify_one(); 98 | void wait_for(volatile const bool& b); 99 | 100 | Mutex mutex; 101 | ConditionVariable sleepCondition; 102 | NativeHandle handle; 103 | volatile bool exit; 104 | }; 105 | 106 | 107 | /// Thread struct keeps together all the thread related stuff like locks, state 108 | /// and especially split points. We also use per-thread pawn and material hash 109 | /// tables so that once we get a pointer to an entry its life time is unlimited 110 | /// and we don't have to care about someone changing the entry under our feet. 111 | 112 | struct Thread : public ThreadBase { 113 | 114 | Thread(); 115 | virtual void idle_loop(); 116 | bool cutoff_occurred() const; 117 | bool is_available_to(const Thread* master) const; 118 | 119 | template 120 | void split(Position& pos, const Search::Stack* ss, Value alpha, Value beta, Value* bestValue, Move* bestMove, 121 | Depth depth, Move threatMove, int moveCount, MovePicker* movePicker, int nodeType, bool cutNode); 122 | 123 | SplitPoint splitPoints[MAX_SPLITPOINTS_PER_THREAD]; 124 | Material::Table materialTable; 125 | Endgames endgames; 126 | Pawns::Table pawnsTable; 127 | Position* activePosition; 128 | size_t idx; 129 | int maxPly; 130 | SplitPoint* volatile activeSplitPoint; 131 | volatile int splitPointsSize; 132 | volatile bool searching; 133 | }; 134 | 135 | 136 | /// MainThread and TimerThread are derived classes used to characterize the two 137 | /// special threads: the main one and the recurring timer. 138 | 139 | struct MainThread : public Thread { 140 | MainThread() : thinking(true) {} // Avoid a race with start_thinking() 141 | virtual void idle_loop(); 142 | volatile bool thinking; 143 | }; 144 | 145 | struct TimerThread : public ThreadBase { 146 | TimerThread() : msec(0) {} 147 | virtual void idle_loop(); 148 | int msec; 149 | }; 150 | 151 | 152 | /// ThreadPool struct handles all the threads related stuff like init, starting, 153 | /// parking and, the most important, launching a slave thread at a split point. 154 | /// All the access to shared thread data is done through this class. 155 | 156 | struct ThreadPool : public std::vector { 157 | 158 | void init(); // No c'tor and d'tor, threads rely on globals that should 159 | void exit(); // be initialized and valid during the whole thread lifetime. 160 | 161 | MainThread* main() { return static_cast((*this)[0]); } 162 | void read_uci_options(); 163 | Thread* available_slave(const Thread* master) const; 164 | void wait_for_think_finished(); 165 | void start_thinking(const Position&, const Search::LimitsType&, 166 | const std::vector&, Search::StateStackPtr&); 167 | 168 | bool sleepWhileIdle; 169 | Depth minimumSplitDepth; 170 | size_t maxThreadsPerSplitPoint; 171 | Mutex mutex; 172 | ConditionVariable sleepCondition; 173 | TimerThread* timer; 174 | }; 175 | 176 | extern ThreadPool Threads; 177 | 178 | #endif // #ifndef THREAD_H_INCLUDED 179 | -------------------------------------------------------------------------------- /src/timeman.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | #include "search.h" 24 | #include "timeman.h" 25 | #include "ucioption.h" 26 | 27 | namespace { 28 | 29 | /// Constants 30 | 31 | const int MoveHorizon = 50; // Plan time management at most this many moves ahead 32 | const float MaxRatio = 7.0f; // When in trouble, we can step over reserved time with this ratio 33 | const float StealRatio = 0.33f; // However we must not steal time from remaining moves over this ratio 34 | 35 | 36 | // MoveImportance[] is based on naive statistical analysis of "how many games are still undecided 37 | // after n half-moves". Game is considered "undecided" as long as neither side has >275cp advantage. 38 | // Data was extracted from CCRL game database with some simple filtering criteria. 39 | const int MoveImportance[512] = { 40 | 7780, 7780, 7780, 7780, 7780, 7780, 7780, 7780, 7780, 7780, 7780, 7780, 7780, 7780, 7780, 7780, 41 | 7780, 7780, 7780, 7780, 7778, 7778, 7776, 7776, 7776, 7773, 7770, 7768, 7766, 7763, 7757, 7751, 42 | 7743, 7735, 7724, 7713, 7696, 7689, 7670, 7656, 7627, 7605, 7571, 7549, 7522, 7493, 7462, 7425, 43 | 7385, 7350, 7308, 7272, 7230, 7180, 7139, 7094, 7055, 7010, 6959, 6902, 6841, 6778, 6705, 6651, 44 | 6569, 6508, 6435, 6378, 6323, 6253, 6152, 6085, 5995, 5931, 5859, 5794, 5717, 5646, 5544, 5462, 45 | 5364, 5282, 5172, 5078, 4988, 4901, 4831, 4764, 4688, 4609, 4536, 4443, 4365, 4293, 4225, 4155, 46 | 4085, 4005, 3927, 3844, 3765, 3693, 3634, 3560, 3479, 3404, 3331, 3268, 3207, 3146, 3077, 3011, 47 | 2947, 2894, 2828, 2776, 2727, 2676, 2626, 2589, 2538, 2490, 2442, 2394, 2345, 2302, 2243, 2192, 48 | 2156, 2115, 2078, 2043, 2004, 1967, 1922, 1893, 1845, 1809, 1772, 1736, 1702, 1674, 1640, 1605, 49 | 1566, 1536, 1509, 1479, 1452, 1423, 1388, 1362, 1332, 1304, 1289, 1266, 1250, 1228, 1206, 1180, 50 | 1160, 1134, 1118, 1100, 1080, 1068, 1051, 1034, 1012, 1001, 980, 960, 945, 934, 916, 900, 888, 51 | 878, 865, 852, 828, 807, 787, 770, 753, 744, 731, 722, 706, 700, 683, 676, 671, 664, 652, 641, 52 | 634, 627, 613, 604, 591, 582, 568, 560, 552, 540, 534, 529, 519, 509, 495, 484, 474, 467, 460, 53 | 450, 438, 427, 419, 410, 406, 399, 394, 387, 382, 377, 372, 366, 359, 353, 348, 343, 337, 333, 54 | 328, 321, 315, 309, 303, 298, 293, 287, 284, 281, 277, 273, 265, 261, 255, 251, 247, 241, 240, 55 | 235, 229, 218, 217, 213, 212, 208, 206, 197, 193, 191, 189, 185, 184, 180, 177, 172, 170, 170, 56 | 170, 166, 163, 159, 158, 156, 155, 151, 146, 141, 138, 136, 132, 130, 128, 125, 123, 122, 118, 57 | 118, 118, 117, 115, 114, 108, 107, 105, 105, 105, 102, 97, 97, 95, 94, 93, 91, 88, 86, 83, 80, 58 | 80, 79, 79, 79, 78, 76, 75, 72, 72, 71, 70, 68, 65, 63, 61, 61, 59, 59, 59, 58, 56, 55, 54, 54, 59 | 52, 49, 48, 48, 48, 48, 45, 45, 45, 44, 43, 41, 41, 41, 41, 40, 40, 38, 37, 36, 34, 34, 34, 33, 60 | 31, 29, 29, 29, 28, 28, 28, 28, 28, 28, 28, 27, 27, 27, 27, 27, 24, 24, 23, 23, 22, 21, 20, 20, 61 | 19, 19, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17, 17, 17, 16, 16, 15, 15, 14, 14, 14, 12, 12, 11, 62 | 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 63 | 8, 8, 8, 8, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 64 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 2, 2, 2, 2, 65 | 2, 1, 1, 1, 1, 1, 1, 1 }; 66 | 67 | int move_importance(int ply) { return MoveImportance[std::min(ply, 511)]; } 68 | 69 | 70 | /// Function Prototypes 71 | 72 | enum TimeType { OptimumTime, MaxTime }; 73 | 74 | template 75 | int remaining(int myTime, int movesToGo, int fullMoveNumber, int slowMover); 76 | } 77 | 78 | 79 | void TimeManager::pv_instability(float bestMoveChanges) { 80 | 81 | unstablePVExtraTime = int(bestMoveChanges * optimumSearchTime); 82 | } 83 | 84 | 85 | void TimeManager::init(const Search::LimitsType& limits, int currentPly, Color us) 86 | { 87 | /* We support four different kind of time controls: 88 | 89 | increment == 0 && movesToGo == 0 means: x basetime [sudden death!] 90 | increment == 0 && movesToGo != 0 means: x moves in y minutes 91 | increment > 0 && movesToGo == 0 means: x basetime + z increment 92 | increment > 0 && movesToGo != 0 means: x moves in y minutes + z increment 93 | 94 | Time management is adjusted by following UCI parameters: 95 | 96 | emergencyMoveHorizon: Be prepared to always play at least this many moves 97 | emergencyBaseTime : Always attempt to keep at least this much time (in ms) at clock 98 | emergencyMoveTime : Plus attempt to keep at least this much time for each remaining emergency move 99 | minThinkingTime : No matter what, use at least this much thinking before doing the move 100 | */ 101 | 102 | int hypMTG, hypMyTime, t1, t2; 103 | 104 | // Read uci parameters 105 | int emergencyMoveHorizon = Options["Emergency Move Horizon"]; 106 | int emergencyBaseTime = Options["Emergency Base Time"]; 107 | int emergencyMoveTime = Options["Emergency Move Time"]; 108 | int minThinkingTime = Options["Minimum Thinking Time"]; 109 | int slowMover = Options["Slow Mover"]; 110 | 111 | // Initialize to maximum values but unstablePVExtraTime that is reset 112 | unstablePVExtraTime = 0; 113 | optimumSearchTime = maximumSearchTime = limits.time[us]; 114 | 115 | // We calculate optimum time usage for different hypothetic "moves to go"-values and choose the 116 | // minimum of calculated search time values. Usually the greatest hypMTG gives the minimum values. 117 | for (hypMTG = 1; hypMTG <= (limits.movestogo ? std::min(limits.movestogo, MoveHorizon) : MoveHorizon); hypMTG++) 118 | { 119 | // Calculate thinking time for hypothetic "moves to go"-value 120 | hypMyTime = limits.time[us] 121 | + limits.inc[us] * (hypMTG - 1) 122 | - emergencyBaseTime 123 | - emergencyMoveTime * std::min(hypMTG, emergencyMoveHorizon); 124 | 125 | hypMyTime = std::max(hypMyTime, 0); 126 | 127 | t1 = minThinkingTime + remaining(hypMyTime, hypMTG, currentPly, slowMover); 128 | t2 = minThinkingTime + remaining(hypMyTime, hypMTG, currentPly, slowMover); 129 | 130 | optimumSearchTime = std::min(optimumSearchTime, t1); 131 | maximumSearchTime = std::min(maximumSearchTime, t2); 132 | } 133 | 134 | if (Options["Ponder"]) 135 | optimumSearchTime += optimumSearchTime / 4; 136 | 137 | // Make sure that maxSearchTime is not over absoluteMaxSearchTime 138 | optimumSearchTime = std::min(optimumSearchTime, maximumSearchTime); 139 | } 140 | 141 | 142 | namespace { 143 | 144 | template 145 | int remaining(int myTime, int movesToGo, int currentPly, int slowMover) 146 | { 147 | const float TMaxRatio = (T == OptimumTime ? 1 : MaxRatio); 148 | const float TStealRatio = (T == OptimumTime ? 0 : StealRatio); 149 | 150 | int thisMoveImportance = move_importance(currentPly) * slowMover / 100; 151 | int otherMovesImportance = 0; 152 | 153 | for (int i = 1; i < movesToGo; ++i) 154 | otherMovesImportance += move_importance(currentPly + 2 * i); 155 | 156 | float ratio1 = (TMaxRatio * thisMoveImportance) / float(TMaxRatio * thisMoveImportance + otherMovesImportance); 157 | float ratio2 = (thisMoveImportance + TStealRatio * otherMovesImportance) / float(thisMoveImportance + otherMovesImportance); 158 | 159 | return int(floor(myTime * std::min(ratio1, ratio2))); 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /src/timeman.h: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef TIMEMAN_H_INCLUDED 21 | #define TIMEMAN_H_INCLUDED 22 | 23 | /// The TimeManager class computes the optimal time to think depending on the 24 | /// maximum available time, the move game number and other parameters. 25 | 26 | class TimeManager { 27 | public: 28 | void init(const Search::LimitsType& limits, int currentPly, Color us); 29 | void pv_instability(float bestMoveChanges); 30 | int available_time() const { return optimumSearchTime + unstablePVExtraTime; } 31 | int maximum_time() const { return maximumSearchTime; } 32 | 33 | private: 34 | int optimumSearchTime; 35 | int maximumSearchTime; 36 | int unstablePVExtraTime; 37 | }; 38 | 39 | #endif // #ifndef TIMEMAN_H_INCLUDED 40 | -------------------------------------------------------------------------------- /src/tt.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | #include "bitboard.h" 24 | #include "tt.h" 25 | 26 | TranspositionTable TT; // Our global transposition table 27 | 28 | 29 | /// TranspositionTable::set_size() sets the size of the transposition table, 30 | /// measured in megabytes. Transposition table consists of a power of 2 number 31 | /// of clusters and each cluster consists of ClusterSize number of TTEntry. 32 | 33 | void TranspositionTable::set_size(size_t mbSize) { 34 | 35 | assert(msb((mbSize << 20) / sizeof(TTEntry)) < 32); 36 | 37 | uint32_t size = ClusterSize << msb((mbSize << 20) / sizeof(TTEntry[ClusterSize])); 38 | 39 | if (hashMask == size - ClusterSize) 40 | return; 41 | 42 | hashMask = size - ClusterSize; 43 | free(mem); 44 | mem = calloc(size * sizeof(TTEntry) + CACHE_LINE_SIZE - 1, 1); 45 | 46 | if (!mem) 47 | { 48 | std::cerr << "Failed to allocate " << mbSize 49 | << "MB for transposition table." << std::endl; 50 | exit(EXIT_FAILURE); 51 | } 52 | 53 | table = (TTEntry*)((uintptr_t(mem) + CACHE_LINE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1)); 54 | } 55 | 56 | 57 | /// TranspositionTable::clear() overwrites the entire transposition table 58 | /// with zeroes. It is called whenever the table is resized, or when the 59 | /// user asks the program to clear the table (from the UCI interface). 60 | 61 | void TranspositionTable::clear() { 62 | 63 | std::memset(table, 0, (hashMask + ClusterSize) * sizeof(TTEntry)); 64 | } 65 | 66 | 67 | /// TranspositionTable::probe() looks up the current position in the 68 | /// transposition table. Returns a pointer to the TTEntry or NULL if 69 | /// position is not found. 70 | 71 | const TTEntry* TranspositionTable::probe(const Key key) const { 72 | 73 | const TTEntry* tte = first_entry(key); 74 | uint32_t key32 = key >> 32; 75 | 76 | for (unsigned i = 0; i < ClusterSize; ++i, tte++) 77 | if (tte->key() == key32) 78 | return tte; 79 | 80 | return NULL; 81 | } 82 | 83 | 84 | /// TranspositionTable::store() writes a new entry containing position key and 85 | /// valuable information of current position. The lowest order bits of position 86 | /// key are used to decide on which cluster the position will be placed. 87 | /// When a new entry is written and there are no empty entries available in cluster, 88 | /// it replaces the least valuable of entries. A TTEntry t1 is considered to be 89 | /// more valuable than a TTEntry t2 if t1 is from the current search and t2 is from 90 | /// a previous search, or if the depth of t1 is bigger than the depth of t2. 91 | 92 | void TranspositionTable::store(const Key key, Value v, Bound b, Depth d, Move m, Value statV, Value evalM) { 93 | 94 | int c1, c2, c3; 95 | TTEntry *tte, *replace; 96 | uint32_t key32 = key >> 32; // Use the high 32 bits as key inside the cluster 97 | 98 | tte = replace = first_entry(key); 99 | 100 | for (unsigned i = 0; i < ClusterSize; ++i, tte++) 101 | { 102 | if (!tte->key() || tte->key() == key32) // Empty or overwrite old 103 | { 104 | if (!m) 105 | m = tte->move(); // Preserve any existing ttMove 106 | 107 | replace = tte; 108 | break; 109 | } 110 | 111 | // Implement replace strategy 112 | c1 = (replace->generation() == generation ? 2 : 0); 113 | c2 = (tte->generation() == generation || tte->bound() == BOUND_EXACT ? -2 : 0); 114 | c3 = (tte->depth() < replace->depth() ? 1 : 0); 115 | 116 | if (c1 + c2 + c3 > 0) 117 | replace = tte; 118 | } 119 | 120 | replace->save(key32, v, b, d, m, generation, statV, evalM); 121 | } 122 | -------------------------------------------------------------------------------- /src/tt.h: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef TT_H_INCLUDED 21 | #define TT_H_INCLUDED 22 | 23 | #include "misc.h" 24 | #include "types.h" 25 | 26 | /// The TTEntry is the 128 bit transposition table entry, defined as below: 27 | /// 28 | /// key: 32 bit 29 | /// move: 16 bit 30 | /// bound type: 8 bit 31 | /// generation: 8 bit 32 | /// value: 16 bit 33 | /// depth: 16 bit 34 | /// static value: 16 bit 35 | /// static margin: 16 bit 36 | 37 | struct TTEntry { 38 | 39 | void save(uint32_t k, Value v, Bound b, Depth d, Move m, int g, Value ev, Value em) { 40 | 41 | key32 = (uint32_t)k; 42 | move16 = (uint16_t)m; 43 | bound8 = (uint8_t)b; 44 | generation8 = (uint8_t)g; 45 | value16 = (int16_t)v; 46 | depth16 = (int16_t)d; 47 | evalValue = (int16_t)ev; 48 | evalMargin = (int16_t)em; 49 | } 50 | void set_generation(uint8_t g) { generation8 = g; } 51 | 52 | uint32_t key() const { return key32; } 53 | Depth depth() const { return (Depth)depth16; } 54 | Move move() const { return (Move)move16; } 55 | Value value() const { return (Value)value16; } 56 | Bound bound() const { return (Bound)bound8; } 57 | int generation() const { return (int)generation8; } 58 | Value eval_value() const { return (Value)evalValue; } 59 | Value eval_margin() const { return (Value)evalMargin; } 60 | 61 | private: 62 | uint32_t key32; 63 | uint16_t move16; 64 | uint8_t bound8, generation8; 65 | int16_t value16, depth16, evalValue, evalMargin; 66 | }; 67 | 68 | 69 | /// A TranspositionTable consists of a power of 2 number of clusters and each 70 | /// cluster consists of ClusterSize number of TTEntry. Each non-empty entry 71 | /// contains information of exactly one position. Size of a cluster shall not be 72 | /// bigger than a cache line size. In case it is less, it should be padded to 73 | /// guarantee always aligned accesses. 74 | 75 | class TranspositionTable { 76 | 77 | static const unsigned ClusterSize = 4; // A cluster is 64 Bytes 78 | 79 | public: 80 | ~TranspositionTable() { free(mem); } 81 | void new_search() { generation++; } 82 | 83 | const TTEntry* probe(const Key key) const; 84 | TTEntry* first_entry(const Key key) const; 85 | void refresh(const TTEntry* tte) const; 86 | void set_size(size_t mbSize); 87 | void clear(); 88 | void store(const Key key, Value v, Bound type, Depth d, Move m, Value statV, Value kingD); 89 | 90 | private: 91 | uint32_t hashMask; 92 | TTEntry* table; 93 | void* mem; 94 | uint8_t generation; // Size must be not bigger than TTEntry::generation8 95 | }; 96 | 97 | extern TranspositionTable TT; 98 | 99 | 100 | /// TranspositionTable::first_entry() returns a pointer to the first entry of 101 | /// a cluster given a position. The lowest order bits of the key are used to 102 | /// get the index of the cluster. 103 | 104 | inline TTEntry* TranspositionTable::first_entry(const Key key) const { 105 | 106 | return table + ((uint32_t)key & hashMask); 107 | } 108 | 109 | 110 | /// TranspositionTable::refresh() updates the 'generation' value of the TTEntry 111 | /// to avoid aging. Normally called after a TT hit. 112 | 113 | inline void TranspositionTable::refresh(const TTEntry* tte) const { 114 | 115 | const_cast(tte)->set_generation(generation); 116 | } 117 | 118 | #endif // #ifndef TT_H_INCLUDED 119 | -------------------------------------------------------------------------------- /src/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chinese chess playing engine based on Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef TYPES_H_INCLUDED 21 | #define TYPES_H_INCLUDED 22 | 23 | /// For Linux and OSX configuration is done automatically using Makefile. To get 24 | /// started type 'make help'. 25 | /// 26 | /// For Windows, part of the configuration is detected automatically, but some 27 | /// switches need to be set manually: 28 | /// 29 | /// -DNDEBUG | Disable debugging mode. Use always. 30 | /// 31 | /// -DNO_PREFETCH | Disable use of prefetch asm-instruction. A must if you want 32 | /// | the executable to run on some very old machines. 33 | /// 34 | /// -DUSE_POPCNT | Add runtime support for use of popcnt asm-instruction. Works 35 | /// | only in 64-bit mode. For compiling requires hardware with 36 | /// | popcnt support. 37 | 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #include "platform.h" 44 | #include "boardtype.h" 45 | 46 | #define unlikely(x) (x) // For code annotation purposes 47 | 48 | #if defined(_WIN64) && !defined(IS_64BIT) 49 | # include // MSVC popcnt and bsfq instrinsics 50 | # define IS_64BIT 51 | 52 | #endif 53 | 54 | #if defined(USE_POPCNT) && defined(_MSC_VER) && defined(__INTEL_COMPILER) 55 | # include // Intel header for _mm_popcnt_u64() intrinsic 56 | #endif 57 | 58 | # if !defined(NO_PREFETCH) && (defined(__INTEL_COMPILER) || defined(_MSC_VER)) 59 | # include // Intel and Microsoft header for _mm_prefetch() 60 | # endif 61 | 62 | #define CACHE_LINE_SIZE 64 63 | #if defined(_MSC_VER) || defined(__INTEL_COMPILER) 64 | # define CACHE_LINE_ALIGNMENT __declspec(align(CACHE_LINE_SIZE)) 65 | #else 66 | # define CACHE_LINE_ALIGNMENT __attribute__ ((aligned(CACHE_LINE_SIZE))) 67 | #endif 68 | 69 | #ifdef _MSC_VER 70 | # define FORCE_INLINE __forceinline 71 | #elif defined(__GNUC__) 72 | # define FORCE_INLINE inline __attribute__((always_inline)) 73 | #else 74 | # define FORCE_INLINE inline 75 | #endif 76 | 77 | #ifdef USE_POPCNT 78 | const bool HasPopCnt = true; 79 | #else 80 | const bool HasPopCnt = false; 81 | #endif 82 | 83 | #ifdef IS_64BIT 84 | const bool Is64Bit = true; 85 | #else 86 | const bool Is64Bit = false; 87 | #endif 88 | 89 | typedef uint64_t Key; 90 | typedef bitboardtype Bitboard; 91 | 92 | const int MAX_MOVES = 192; 93 | const int MAX_PLY = 100; 94 | const int MAX_PLY_PLUS_6 = MAX_PLY + 6; 95 | 96 | /// A move needs 16 bits to be stored 97 | /// 98 | /// bit 0- 7: destination square (from 0 to 63) 99 | /// bit 8-15: origin square (from 0 to 63) 100 | 101 | /// Special cases are MOVE_NONE and MOVE_NULL. We can sneak these in because in 102 | /// any normal move destination square is always different from origin square 103 | /// while MOVE_NONE and MOVE_NULL have the same origin and destination square. 104 | 105 | enum Move { 106 | MOVE_NONE, 107 | MOVE_NULL = 89 108 | }; 109 | 110 | enum MoveType { 111 | NORMAL, 112 | }; 113 | 114 | enum Phase { 115 | PHASE_ENDGAME, 116 | PHASE_MIDGAME = 128, 117 | MG = 0, EG = 1, PHASE_NB = 2 118 | }; 119 | 120 | enum ScaleFactor { 121 | SCALE_FACTOR_DRAW = 0, 122 | SCALE_FACTOR_NORMAL = 64, 123 | SCALE_FACTOR_MAX = 128, 124 | SCALE_FACTOR_NONE = 255 125 | }; 126 | 127 | enum Bound { 128 | BOUND_NONE, 129 | BOUND_UPPER, 130 | BOUND_LOWER, 131 | BOUND_EXACT = BOUND_UPPER | BOUND_LOWER 132 | }; 133 | 134 | enum Value { 135 | VALUE_ZERO = 0, 136 | VALUE_DRAW = 0, 137 | VALUE_KNOWN_WIN = 15000, 138 | VALUE_REPEAT = 25000, 139 | VALUE_MATE = 30000, 140 | VALUE_INFINITE = 30001, 141 | VALUE_NONE = 30002, 142 | 143 | VALUE_MATE_IN_MAX_PLY = VALUE_MATE - MAX_PLY, 144 | VALUE_MATED_IN_MAX_PLY = -VALUE_MATE + MAX_PLY, 145 | 146 | VALUE_ENSURE_INTEGER_SIZE_P = INT_MAX, 147 | VALUE_ENSURE_INTEGER_SIZE_N = INT_MIN, 148 | 149 | 150 | PawnValueMg = 89, PawnValueEg = 305, 151 | BishopValueMg = 335, BishopValueEg = 400, 152 | AdvisorValueMg= 400, AdvisorValueEg= 380, 153 | KnightValueMg = 802, KnightValueEg = 865, 154 | CannonValueMg = 865, CannonValueEg = 842, 155 | RookValueMg = 1891, RookValueEg = 2020, 156 | }; 157 | 158 | enum RepeatType { 159 | REPEATE_NONE = 0, 160 | REPEATE_TRUE = 1, 161 | REPEATE_ME_CHECK = 2, 162 | REPEATE_OPP_CHECK= 4 163 | }; 164 | 165 | enum PieceType { 166 | NO_PIECE_TYPE, PAWN, BISHOP, ADVISOR, KNIGHT, CANNON, ROOK, KING, 167 | ALL_PIECES = 0, 168 | PIECE_TYPE_NB = 8 169 | }; 170 | 171 | enum Piece { 172 | NO_PIECE, 173 | W_PAWN = 1, W_BISHOP, W_ADVISOR, W_KNIGHT, W_CANNON, W_ROOK, W_KING, 174 | B_PAWN = 9, B_BISHOP, B_ADVISOR, B_KNIGHT, B_CANNON, B_ROOK, B_KING, 175 | PIECE_NB = 16 176 | }; 177 | 178 | enum Color { 179 | WHITE, BLACK, NO_COLOR, COLOR_NB = 2 180 | }; 181 | 182 | enum Depth { 183 | 184 | ONE_PLY = 2, 185 | 186 | DEPTH_ZERO = 0 * ONE_PLY, 187 | DEPTH_QS_CHECKS = -1 * ONE_PLY, 188 | DEPTH_QS_NO_CHECKS = -2 * ONE_PLY, 189 | DEPTH_QS_RECAPTURES = -5 * ONE_PLY, 190 | 191 | DEPTH_NONE = -127 * ONE_PLY 192 | }; 193 | 194 | enum Square { 195 | SQ_A0, SQ_B0, SQ_C0, SQ_D0, SQ_E0, SQ_F0, SQ_G0, SQ_H0, SQ_I0, 196 | SQ_A1, SQ_B1, SQ_C1, SQ_D1, SQ_E1, SQ_F1, SQ_G1, SQ_H1, SQ_I1, 197 | SQ_A2, SQ_B2, SQ_C2, SQ_D2, SQ_E2, SQ_F2, SQ_G2, SQ_H2, SQ_I2, 198 | SQ_A3, SQ_B3, SQ_C3, SQ_D3, SQ_E3, SQ_F3, SQ_G3, SQ_H3, SQ_I3, 199 | SQ_A4, SQ_B4, SQ_C4, SQ_D4, SQ_E4, SQ_F4, SQ_G4, SQ_H4, SQ_I4, 200 | SQ_A5, SQ_B5, SQ_C5, SQ_D5, SQ_E5, SQ_F5, SQ_G5, SQ_H5, SQ_I5, 201 | SQ_A6, SQ_B6, SQ_C6, SQ_D6, SQ_E6, SQ_F6, SQ_G6, SQ_H6, SQ_I6, 202 | SQ_A7, SQ_B7, SQ_C7, SQ_D7, SQ_E7, SQ_F7, SQ_G7, SQ_H7, SQ_I7, 203 | SQ_A8, SQ_B8, SQ_C8, SQ_D8, SQ_E8, SQ_F8, SQ_G8, SQ_H8, SQ_I8, 204 | SQ_A9, SQ_B9, SQ_C9, SQ_D9, SQ_E9, SQ_F9, SQ_G9, SQ_H9, SQ_I9, 205 | SQ_NONE, 206 | 207 | SQUARE_NB = 90, 208 | 209 | DELTA_N = 9, 210 | DELTA_E = 1, 211 | DELTA_S = -9, 212 | DELTA_W = -1, 213 | 214 | DELTA_NN = DELTA_N + DELTA_N, 215 | DELTA_NE = DELTA_N + DELTA_E, 216 | DELTA_SE = DELTA_S + DELTA_E, 217 | DELTA_SS = DELTA_S + DELTA_S, 218 | DELTA_SW = DELTA_S + DELTA_W, 219 | DELTA_NW = DELTA_N + DELTA_W 220 | }; 221 | 222 | enum File { 223 | FILE_A, FILE_B, FILE_C, FILE_D, FILE_E, FILE_F, FILE_G, FILE_H, FILE_I, FILE_NB 224 | }; 225 | 226 | enum Rank { 227 | RANK_0, RANK_1, RANK_2, RANK_3, RANK_4, RANK_5, RANK_6, RANK_7, RANK_8, RANK_9, RANK_NB 228 | }; 229 | 230 | 231 | /// Score enum keeps a midgame and an endgame value in a single integer (enum), 232 | /// first LSB 16 bits are used to store endgame value, while upper bits are used 233 | /// for midgame value. Compiler is free to choose the enum type as long as can 234 | /// keep its data, so ensure Score to be an integer type. 235 | enum Score { 236 | SCORE_ZERO, 237 | SCORE_ENSURE_INTEGER_SIZE_P = INT_MAX, 238 | SCORE_ENSURE_INTEGER_SIZE_N = INT_MIN 239 | }; 240 | 241 | //Vertical flip 242 | const int8_t VerticalFlip[SQUARE_NB] = 243 | { 244 | SQ_A9, SQ_B9, SQ_C9, SQ_D9, SQ_E9, SQ_F9, SQ_G9, SQ_H9, SQ_I9, 245 | SQ_A8, SQ_B8, SQ_C8, SQ_D8, SQ_E8, SQ_F8, SQ_G8, SQ_H8, SQ_I8, 246 | SQ_A7, SQ_B7, SQ_C7, SQ_D7, SQ_E7, SQ_F7, SQ_G7, SQ_H7, SQ_I7, 247 | SQ_A6, SQ_B6, SQ_C6, SQ_D6, SQ_E6, SQ_F6, SQ_G6, SQ_H6, SQ_I6, 248 | SQ_A5, SQ_B5, SQ_C5, SQ_D5, SQ_E5, SQ_F5, SQ_G5, SQ_H5, SQ_I5, 249 | SQ_A4, SQ_B4, SQ_C4, SQ_D4, SQ_E4, SQ_F4, SQ_G4, SQ_H4, SQ_I4, 250 | SQ_A3, SQ_B3, SQ_C3, SQ_D3, SQ_E3, SQ_F3, SQ_G3, SQ_H3, SQ_I3, 251 | SQ_A2, SQ_B2, SQ_C2, SQ_D2, SQ_E2, SQ_F2, SQ_G2, SQ_H2, SQ_I2, 252 | SQ_A1, SQ_B1, SQ_C1, SQ_D1, SQ_E1, SQ_F1, SQ_G1, SQ_H1, SQ_I1, 253 | SQ_A0, SQ_B0, SQ_C0, SQ_D0, SQ_E0, SQ_F0, SQ_G0, SQ_H0, SQ_I0, 254 | }; 255 | //Horizontal flip 256 | const int8_t HorizontalFlip[SQUARE_NB] = 257 | { 258 | SQ_I0, SQ_H0, SQ_G0, SQ_F0, SQ_E0, SQ_D0, SQ_C0, SQ_B0, SQ_A0, 259 | SQ_I1, SQ_H1, SQ_G1, SQ_F1, SQ_E1, SQ_D1, SQ_C1, SQ_B1, SQ_A1, 260 | SQ_I2, SQ_H2, SQ_G2, SQ_F2, SQ_E2, SQ_D2, SQ_C2, SQ_B2, SQ_A2, 261 | SQ_I3, SQ_H3, SQ_G3, SQ_F3, SQ_E3, SQ_D3, SQ_C3, SQ_B3, SQ_A3, 262 | SQ_I4, SQ_H4, SQ_G4, SQ_F4, SQ_E4, SQ_D4, SQ_C4, SQ_B4, SQ_A4, 263 | SQ_I5, SQ_H5, SQ_G5, SQ_F5, SQ_E5, SQ_D5, SQ_C5, SQ_B5, SQ_A5, 264 | SQ_I6, SQ_H6, SQ_G6, SQ_F6, SQ_E6, SQ_D6, SQ_C6, SQ_B6, SQ_A6, 265 | SQ_I7, SQ_H7, SQ_G7, SQ_F7, SQ_E7, SQ_D7, SQ_C7, SQ_B7, SQ_A7, 266 | SQ_I8, SQ_H8, SQ_G8, SQ_F8, SQ_E8, SQ_D8, SQ_C8, SQ_B8, SQ_A8, 267 | SQ_I9, SQ_H9, SQ_G9, SQ_F9, SQ_E9, SQ_D9, SQ_C9, SQ_B9, SQ_A9, 268 | }; 269 | 270 | //SQUARE 271 | const int8_t SquareMake[RANK_NB][FILE_NB] = 272 | { 273 | SQ_A0, SQ_B0, SQ_C0, SQ_D0, SQ_E0, SQ_F0, SQ_G0, SQ_H0, SQ_I0, 274 | SQ_A1, SQ_B1, SQ_C1, SQ_D1, SQ_E1, SQ_F1, SQ_G1, SQ_H1, SQ_I1, 275 | SQ_A2, SQ_B2, SQ_C2, SQ_D2, SQ_E2, SQ_F2, SQ_G2, SQ_H2, SQ_I2, 276 | SQ_A3, SQ_B3, SQ_C3, SQ_D3, SQ_E3, SQ_F3, SQ_G3, SQ_H3, SQ_I3, 277 | SQ_A4, SQ_B4, SQ_C4, SQ_D4, SQ_E4, SQ_F4, SQ_G4, SQ_H4, SQ_I4, 278 | SQ_A5, SQ_B5, SQ_C5, SQ_D5, SQ_E5, SQ_F5, SQ_G5, SQ_H5, SQ_I5, 279 | SQ_A6, SQ_B6, SQ_C6, SQ_D6, SQ_E6, SQ_F6, SQ_G6, SQ_H6, SQ_I6, 280 | SQ_A7, SQ_B7, SQ_C7, SQ_D7, SQ_E7, SQ_F7, SQ_G7, SQ_H7, SQ_I7, 281 | SQ_A8, SQ_B8, SQ_C8, SQ_D8, SQ_E8, SQ_F8, SQ_G8, SQ_H8, SQ_I8, 282 | SQ_A9, SQ_B9, SQ_C9, SQ_D9, SQ_E9, SQ_F9, SQ_G9, SQ_H9, SQ_I9, 283 | }; 284 | 285 | //SQUARE_FILE 286 | const int8_t SquareFile[SQUARE_NB] = 287 | { 288 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 289 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 290 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 291 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 292 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 293 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 294 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 295 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 296 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 297 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 298 | }; 299 | //SQUARE_RANK 300 | const int8_t SquareRank[SQUARE_NB] = 301 | { 302 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 303 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 304 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 305 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 306 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 307 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 308 | 6, 6, 6, 6, 6, 6, 6, 6, 6, 309 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 310 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 311 | 9, 9, 9, 9, 9, 9, 9, 9, 9, 312 | }; 313 | 314 | inline Score make_score(int mg, int eg) { return Score((mg << 16) + eg); } 315 | 316 | /// Extracting the signed lower and upper 16 bits it not so trivial because 317 | /// according to the standard a simple cast to short is implementation defined 318 | /// and so is a right shift of a signed integer. 319 | 320 | inline Value mg_value(Score s) { 321 | return Value(((s + 0x8000) & ~0xffff) / 0x10000); 322 | } 323 | 324 | /// On Intel 64 bit we have a small speed regression with the standard conforming 325 | /// version, so use a faster code in this case that, although not 100% standard 326 | /// compliant it seems to work for Intel and MSVC. 327 | #if defined(IS_64BIT) && (!defined(__GNUC__) || defined(__INTEL_COMPILER)) 328 | 329 | inline Value eg_value(Score s) { return Value(int16_t(s & 0xffff)); } 330 | 331 | #else 332 | 333 | inline Value eg_value(Score s) { 334 | return Value((int)(unsigned(s) & 0x7fffu) - (int)(unsigned(s) & 0x8000u)); 335 | } 336 | 337 | #endif 338 | 339 | #define ENABLE_SAFE_OPERATORS_ON(T) \ 340 | inline T operator+(const T d1, const T d2) { return T(int(d1) + int(d2)); } \ 341 | inline T operator-(const T d1, const T d2) { return T(int(d1) - int(d2)); } \ 342 | inline T operator*(int i, const T d) { return T(i * int(d)); } \ 343 | inline T operator*(const T d, int i) { return T(int(d) * i); } \ 344 | inline T operator-(const T d) { return T(-int(d)); } \ 345 | inline T& operator+=(T& d1, const T d2) { return d1 = d1 + d2; } \ 346 | inline T& operator-=(T& d1, const T d2) { return d1 = d1 - d2; } \ 347 | inline T& operator*=(T& d, int i) { return d = T(int(d) * i); } 348 | 349 | #define ENABLE_OPERATORS_ON(T) ENABLE_SAFE_OPERATORS_ON(T) \ 350 | inline T& operator++(T& d) { return d = T(int(d) + 1); } \ 351 | inline T& operator--(T& d) { return d = T(int(d) - 1); } \ 352 | inline T operator/(const T d, int i) { return T(int(d) / i); } \ 353 | inline T& operator/=(T& d, int i) { return d = T(int(d) / i); } 354 | 355 | ENABLE_OPERATORS_ON(Value) 356 | ENABLE_OPERATORS_ON(PieceType) 357 | ENABLE_OPERATORS_ON(Piece) 358 | ENABLE_OPERATORS_ON(Color) 359 | ENABLE_OPERATORS_ON(Depth) 360 | ENABLE_OPERATORS_ON(Square) 361 | ENABLE_OPERATORS_ON(File) 362 | ENABLE_OPERATORS_ON(Rank) 363 | 364 | /// Added operators for adding integers to a Value 365 | inline Value operator+(Value v, int i) { return Value(int(v) + i); } 366 | inline Value operator-(Value v, int i) { return Value(int(v) - i); } 367 | 368 | ENABLE_SAFE_OPERATORS_ON(Score) 369 | 370 | /// Only declared but not defined. We don't want to multiply two scores due to 371 | /// a very high risk of overflow. So user should explicitly convert to integer. 372 | inline Score operator*(Score s1, Score s2); 373 | 374 | /// Division of a Score must be handled separately for each term 375 | inline Score operator/(Score s, int i) { 376 | return make_score(mg_value(s) / i, eg_value(s) / i); 377 | } 378 | 379 | #undef ENABLE_OPERATORS_ON 380 | #undef ENABLE_SAFE_OPERATORS_ON 381 | 382 | extern Value PieceValue[PHASE_NB][PIECE_NB]; 383 | 384 | struct ExtMove { 385 | Move move; 386 | int score; 387 | }; 388 | 389 | inline bool operator<(const ExtMove& f, const ExtMove& s) { 390 | return f.score < s.score; 391 | } 392 | 393 | inline Color operator~(Color c) { 394 | return Color(c ^ 1); 395 | } 396 | 397 | inline Square operator~(Square s) { 398 | return Square(VerticalFlip[s]);//Square(s ^ 56); // Vertical flip SQ_A0 -> SQ_A9 399 | } 400 | 401 | inline Square operator|(File f, Rank r) { 402 | return Square(SquareMake[r][f]);//Square((r << 3) | f); 403 | } 404 | 405 | inline Value mate_in(int ply) { 406 | return VALUE_MATE - ply; 407 | } 408 | 409 | inline Value mated_in(int ply) { 410 | return -VALUE_MATE + ply; 411 | } 412 | 413 | inline Value repeat_value(int ply, int reptype) { 414 | int v; 415 | v = (reptype & REPEATE_ME_CHECK) ? (-VALUE_REPEAT + ply) : 0 + (reptype & REPEATE_OPP_CHECK) ? (VALUE_REPEAT - ply) : 0; 416 | return Value(v == 0 ? VALUE_DRAW : v); 417 | } 418 | 419 | inline Piece make_piece(Color c, PieceType pt) { 420 | return Piece((c << 3) | pt); 421 | } 422 | 423 | inline PieceType type_of(Piece p) { 424 | return PieceType(p & 7); 425 | } 426 | 427 | inline Color color_of(Piece p) { 428 | assert(p != NO_PIECE); 429 | return Color(p >> 3); 430 | } 431 | 432 | inline bool is_ok(Square s) { 433 | return s >= SQ_A0 && s <= SQ_I9; 434 | } 435 | 436 | inline bool is_ok(int s){ 437 | return s >= SQ_A0 && s <= SQ_I9; 438 | } 439 | 440 | inline File file_of(Square s) { 441 | return File(SquareFile[s]);//File(s & 7); 442 | } 443 | 444 | inline Rank rank_of(Square s) { 445 | return Rank(SquareRank[s]);//Rank(s >> 3); 446 | } 447 | 448 | inline Square mirror(Square s) { 449 | return Square(HorizontalFlip[s]);//Square(s ^ 7); // Horizontal flip SQ_A1 -> SQ_H1 450 | } 451 | 452 | inline Square relative_square(Color c, Square s) { 453 | //return Square(s ^ (c * 56)); 454 | return c ? (Square(VerticalFlip[s])) : (s); 455 | } 456 | 457 | inline Rank relative_rank(Color c, Rank r) { 458 | // return Rank(r ^ (c * 7)); 459 | return c ? (Rank(9 - r)) : (r); 460 | } 461 | 462 | inline Rank relative_rank(Color c, Square s) { 463 | return relative_rank(c, rank_of(s)); 464 | } 465 | 466 | inline Color square_color(Square s){ 467 | return Color(((int)rank_of(s)) > RANK_4); 468 | } 469 | 470 | inline bool opposite_colors(Square s1, Square s2) { 471 | return square_color(s1) != square_color(s2); 472 | } 473 | 474 | inline char file_to_char(File f, bool tolower = true) { 475 | return char(f - FILE_A + (tolower ? 'a' : 'A')); 476 | } 477 | 478 | inline char rank_to_char(Rank r) { 479 | return char(r - RANK_0 + '0'); 480 | } 481 | 482 | inline Square pawn_push(Color c) { 483 | return c == WHITE ? DELTA_N : DELTA_S; 484 | } 485 | 486 | inline Square from_sq(Move m) { 487 | return Square((m >> 8)); 488 | } 489 | 490 | inline Square to_sq(Move m) { 491 | return Square(m & 0xFF); 492 | } 493 | 494 | inline MoveType type_of(Move m) { 495 | return NORMAL;//chinese chess, all is normal 496 | } 497 | 498 | inline Move make_move(Square from, Square to) { 499 | return Move(to | (from << 8)); 500 | } 501 | 502 | template 503 | inline Move make(Square from, Square to, PieceType pt = KNIGHT) { 504 | return Move(to | (from << 8)); 505 | } 506 | 507 | inline bool is_ok(Move m) { 508 | return from_sq(m) != to_sq(m); // Catches also MOVE_NULL and MOVE_NONE 509 | } 510 | 511 | #include 512 | 513 | inline const std::string square_to_string(Square s) { 514 | char ch[] = { file_to_char(file_of(s)), rank_to_char(rank_of(s)), 0 }; 515 | return ch; 516 | } 517 | 518 | #endif // #ifndef TYPES_H_INCLUDED 519 | -------------------------------------------------------------------------------- /src/uci.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "evaluate.h" 26 | #include "notation.h" 27 | #include "position.h" 28 | #include "search.h" 29 | #include "thread.h" 30 | #include "tt.h" 31 | #include "ucioption.h" 32 | 33 | using namespace std; 34 | 35 | extern void benchmark(const Position& pos, istream& is); 36 | 37 | namespace { 38 | 39 | // FEN string of the initial position, normal chess 40 | const char* StartFEN = "rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1"; 41 | 42 | // Keep track of position keys along the setup moves (from start position to the 43 | // position just before to start searching). Needed by repetition draw detection. 44 | Search::StateStackPtr SetupStates; 45 | 46 | void setoption(istringstream& up); 47 | void position(Position& pos, istringstream& up); 48 | void go(const Position& pos, istringstream& up); 49 | } 50 | 51 | 52 | /// Wait for a command from the user, parse this text string as an UCI command, 53 | /// and call the appropriate functions. Also intercepts EOF from stdin to ensure 54 | /// that we exit gracefully if the GUI dies unexpectedly. In addition to the UCI 55 | /// commands, the function also supports a few debug commands. 56 | 57 | void UCI::loop(const string& args) { 58 | 59 | Position pos(StartFEN, false, Threads.main()); // The root position 60 | string token, cmd = args; 61 | 62 | do { 63 | if (args.empty() && !getline(cin, cmd)) // Block here waiting for input 64 | cmd = "quit"; 65 | 66 | istringstream is(cmd); 67 | 68 | is >> skipws >> token; 69 | 70 | if (token == "quit" || token == "stop" || token == "ponderhit") 71 | { 72 | // GUI sends 'ponderhit' to tell us to ponder on the same move the 73 | // opponent has played. In case Signals.stopOnPonderhit is set we are 74 | // waiting for 'ponderhit' to stop the search (for instance because we 75 | // already ran out of time), otherwise we should continue searching but 76 | // switching from pondering to normal search. 77 | if (token != "ponderhit" || Search::Signals.stopOnPonderhit) 78 | { 79 | Search::Signals.stop = true; 80 | Threads.main()->notify_one(); // Could be sleeping 81 | } 82 | else 83 | Search::Limits.ponder = false; 84 | } 85 | else if (token == "perft" && (is >> token)) // Read perft depth 86 | { 87 | stringstream ss; 88 | 89 | ss << Options["Hash"] << " " 90 | << Options["Threads"] << " " << token << " current perft"; 91 | 92 | benchmark(pos, ss); 93 | } 94 | else if (token == "key") 95 | sync_cout << hex << uppercase << setfill('0') 96 | << "position key: " << setw(16) << pos.key() 97 | << "\nmaterial key: " << setw(16) << pos.material_key() 98 | << "\npawn key: " << setw(16) << pos.pawn_key() 99 | << dec << sync_endl; 100 | 101 | else if (token == "uci") 102 | sync_cout << "id name " << engine_info(true) 103 | << "\n" << Options 104 | << "\nuciok" << sync_endl; 105 | 106 | else if (token == "eval") 107 | { 108 | Search::RootColor = pos.side_to_move(); // Ensure it is set 109 | sync_cout << Eval::trace(pos) << sync_endl; 110 | } 111 | else if (token == "ucinewgame") TT.clear(); 112 | else if (token == "go") go(pos, is); 113 | else if (token == "position" || token == "fen") position(pos, is); 114 | else if (token == "setoption") setoption(is); 115 | else if (token == "flip") pos.flip(); 116 | else if (token == "bench") benchmark(pos, is); 117 | else if (token == "d") sync_cout << pos.pretty() << sync_endl; 118 | else if (token == "isready") sync_cout << "readyok" << sync_endl; 119 | else 120 | sync_cout << "Unknown command: " << cmd << sync_endl; 121 | 122 | } while (token != "quit" && args.empty()); // Args have one-shot behaviour 123 | 124 | Threads.wait_for_think_finished(); // Cannot quit while search is running 125 | } 126 | 127 | 128 | namespace { 129 | 130 | // position() is called when engine receives the "position" UCI command. 131 | // The function sets up the position described in the given fen string ("fen") 132 | // or the starting position ("startpos") and then makes the moves given in the 133 | // following move list ("moves"). 134 | 135 | void position(Position& pos, istringstream& is) { 136 | 137 | Move m; 138 | string token, fen; 139 | 140 | is >> token; 141 | 142 | if (token == "startpos") 143 | { 144 | fen = StartFEN; 145 | is >> token; // Consume "moves" token if any 146 | } 147 | else if (token == "fen") 148 | while (is >> token && token != "moves") 149 | fen += token + " "; 150 | else 151 | while (token != "moves") 152 | { 153 | fen += token + " "; 154 | if( !(is >> token) ) 155 | { 156 | break; 157 | } 158 | } 159 | //else 160 | // return; 161 | 162 | pos.set(fen, Options["UCI_Chess960"], Threads.main()); 163 | SetupStates = Search::StateStackPtr(new std::stack()); 164 | 165 | // Parse move list (if any) 166 | while (is >> token && (m = move_from_uci(pos, token)) != MOVE_NONE) 167 | { 168 | SetupStates->push(StateInfo()); 169 | pos.do_move(m, SetupStates->top()); 170 | } 171 | } 172 | 173 | 174 | // setoption() is called when engine receives the "setoption" UCI command. The 175 | // function updates the UCI option ("name") to the given value ("value"). 176 | 177 | void setoption(istringstream& is) { 178 | 179 | string token, name, value; 180 | 181 | is >> token; // Consume "name" token 182 | 183 | // Read option name (can contain spaces) 184 | while (is >> token && token != "value") 185 | name += string(" ", !name.empty()) + token; 186 | 187 | // Read option value (can contain spaces) 188 | while (is >> token) 189 | value += string(" ", !value.empty()) + token; 190 | 191 | if (Options.count(name)){ 192 | Options[name] = value; 193 | 194 | } 195 | else 196 | sync_cout << "No such option: " << name << sync_endl; 197 | } 198 | 199 | 200 | // go() is called when engine receives the "go" UCI command. The function sets 201 | // the thinking time and other parameters from the input string, and starts 202 | // the search. 203 | 204 | void go(const Position& pos, istringstream& is) { 205 | 206 | Search::LimitsType limits; 207 | vector searchMoves; 208 | string token; 209 | 210 | while (is >> token) 211 | { 212 | if (token == "searchmoves") 213 | while (is >> token) 214 | searchMoves.push_back(move_from_uci(pos, token)); 215 | 216 | else if (token == "wtime") is >> limits.time[WHITE]; 217 | else if (token == "btime") is >> limits.time[BLACK]; 218 | else if (token == "winc") is >> limits.inc[WHITE]; 219 | else if (token == "binc") is >> limits.inc[BLACK]; 220 | else if (token == "movestogo") is >> limits.movestogo; 221 | else if (token == "depth") is >> limits.depth; 222 | else if (token == "nodes") is >> limits.nodes; 223 | else if (token == "movetime") is >> limits.movetime; 224 | else if (token == "mate") is >> limits.mate; 225 | else if (token == "infinite") limits.infinite = true; 226 | else if (token == "ponder") limits.ponder = true; 227 | } 228 | 229 | Threads.start_thinking(pos, limits, searchMoves, SetupStates); 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /src/ucioption.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grefen/challenger/902e706b33a786796920ffe4c92612f5d3e34bf0/src/ucioption.cpp -------------------------------------------------------------------------------- /src/ucioption.h: -------------------------------------------------------------------------------- 1 | /* 2 | Challenger, a UCI chess playing engine derived from Stockfish 3 | 4 | Copyright (C) 2013-2017 grefen 5 | 6 | Challenger is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Challenger is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #ifndef UCIOPTION_H_INCLUDED 21 | #define UCIOPTION_H_INCLUDED 22 | 23 | #include 24 | #include 25 | 26 | namespace UCI { 27 | 28 | class Option; 29 | 30 | /// Custom comparator because UCI options should be case insensitive 31 | struct CaseInsensitiveLess { 32 | bool operator() (const std::string&, const std::string&) const; 33 | }; 34 | 35 | /// Our options container is actually a std::map 36 | typedef std::map OptionsMap; 37 | 38 | /// Option class implements an option as defined by UCI protocol 39 | class Option { 40 | 41 | typedef void (Fn)(const Option&); 42 | 43 | public: 44 | Option(Fn* = NULL); 45 | Option(bool v, Fn* = NULL); 46 | Option(const char* v, Fn* = NULL); 47 | Option(int v, int min, int max, Fn* = NULL); 48 | 49 | Option& operator=(const std::string& v); 50 | operator int() const; 51 | operator std::string() const; 52 | 53 | private: 54 | friend std::ostream& operator<<(std::ostream&, const OptionsMap&); 55 | 56 | std::string defaultValue, currentValue, type; 57 | int min, max; 58 | size_t idx; 59 | Fn* on_change; 60 | }; 61 | 62 | void init(OptionsMap&); 63 | void loop(const std::string&); 64 | 65 | } // namespace UCI 66 | 67 | extern UCI::OptionsMap Options; 68 | 69 | #endif // #ifndef UCIOPTION_H_INCLUDED 70 | -------------------------------------------------------------------------------- /vs2008/Challenger.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Challenger", "Challenger.vcproj", "{E570EDBD-7EE5-4695-97A7-387C21C4FD29}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {E570EDBD-7EE5-4695-97A7-387C21C4FD29}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {E570EDBD-7EE5-4695-97A7-387C21C4FD29}.Debug|Win32.Build.0 = Debug|Win32 14 | {E570EDBD-7EE5-4695-97A7-387C21C4FD29}.Release|Win32.ActiveCfg = Release|Win32 15 | {E570EDBD-7EE5-4695-97A7-387C21C4FD29}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /vs2008/Challenger.vcproj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grefen/challenger/902e706b33a786796920ffe4c92612f5d3e34bf0/vs2008/Challenger.vcproj --------------------------------------------------------------------------------