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