Rev 108 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 108 | Rev 154 | ||
---|---|---|---|
Line 4... | Line 4... | ||
4 | # include <unistd.h> |
4 | # include <unistd.h> |
5 | # include <pwd.h> |
5 | # include <pwd.h> |
6 | # include <sys/types.h> |
6 | # include <sys/types.h> |
7 | #endif |
7 | #endif |
8 | #include <signal.h> |
8 | #include <signal.h> |
- | 9 | #if defined(SYZYGY) |
|
- | 10 | # include "tbprobe.h" |
|
- | 11 | #endif |
|
9 | /* last modified |
12 | /* last modified 08/03/16 */ |
10 | /* |
13 | /* |
11 | ******************************************************************************* |
14 | ******************************************************************************* |
12 | * * |
15 | * * |
13 | * Crafty, copyright 1996- |
16 | * Crafty, copyright 1996-2016 by Robert M. Hyatt, Ph.D. * |
14 | * of Computer and Information Sciences, University of Alabama at Birmingham. * |
- | |
15 | * * |
17 | * * |
16 | * Crafty is a team project consisting of the following members. These are * |
18 | * Crafty is a team project consisting of the following members. These are * |
17 | * the people involved in the continuing development of this program, there * |
19 | * the people involved in the continuing development of this program, there * |
18 | * are no particular members responsible for any specific aspect of Crafty, * |
20 | * are no particular members responsible for any specific aspect of Crafty, * |
19 | * although R. Hyatt wrote 99%+ of the existing code, excepting the Magic . * |
21 | * although R. Hyatt wrote 99%+ of the existing code, excepting the Magic . * |
20 | * move stuff by Pradu Kaanan, |
22 | * move stuff by Pradu Kaanan, syzygy code written by Ronald de Man, and the * |
21 | * epd stuff written by S. Edwards. * |
23 | * epd stuff written by S. Edwards. * |
22 | * * |
24 | * * |
23 | * Robert Hyatt, |
25 | * Robert Hyatt, Pelham, AL. * |
24 | * Mike Byrne, Pen Argyl, PA. * |
26 | * Mike Byrne, Pen Argyl, PA. * |
25 | * Tracy Riegle, Hershey, PA. * |
27 | * Tracy Riegle, Hershey, PA. * |
26 | * Peter Skinner, Edmonton, AB Canada. * |
28 | * Peter Skinner, Edmonton, AB Canada. * |
27 | * * |
29 | * * |
28 | * All rights reserved. No part of this program may be reproduced in any * |
30 | * All rights reserved. No part of this program may be reproduced in any * |
Line 4188... | Line 4190... | ||
4188 | * used to watch the log file while a game is in progress. This is * |
4190 | * used to watch the log file while a game is in progress. This is * |
4189 | * a bit trickier than you might think since Crafty displays the * |
4191 | * a bit trickier than you might think since Crafty displays the * |
4190 | * game move numbers in the PV. Penalty for pawns on same color as * |
4192 | * game move numbers in the PV. Penalty for pawns on same color as * |
4191 | * bishop now only applies when there is one bishop. * |
4193 | * bishop now only applies when there is one bishop. * |
4192 | * * |
4194 | * * |
4193 | * 25 |
4195 | * 25.1 Cleanup of NextMove() plus a minor ordering bug fix that would * |
4194 | * skip counter moves at ply = 2. Added NUMA code to force the hash * |
4196 | * skip counter moves at ply = 2. Added NUMA code to force the hash * |
4195 | * tables to be spread across the numa nodes as equally as possible * |
4197 | * tables to be spread across the numa nodes as equally as possible * |
4196 | * rather than all of the data sitting on just onenode. This makes * |
4198 | * rather than all of the data sitting on just onenode. This makes * |
4197 | * one specific user policy important. BEFORE you set the hash size * |
4199 | * one specific user policy important. BEFORE you set the hash size * |
4198 | * for any of the four hash tables, you should ALWAYS set the max * |
4200 | * for any of the four hash tables, you should ALWAYS set the max * |
Line 4202... | Line 4204... | ||
4202 | * routines. A new "smpnuma" command is now used to enable/disable * |
4204 | * routines. A new "smpnuma" command is now used to enable/disable * |
4203 | * NUMA mode (which really only affects how the hash tables are * |
4205 | * NUMA mode (which really only affects how the hash tables are * |
4204 | * cleared, all the other NUMA code works just fine no matter * |
4206 | * cleared, all the other NUMA code works just fine no matter * |
4205 | * whether this is enabled or disabled. Fixed a bug with the xboard * |
4207 | * whether this is enabled or disabled. Fixed a bug with the xboard * |
4206 | * memory command that could overflow and cause preposterous malloc * |
4208 | * memory command that could overflow and cause preposterous malloc * |
- | 4209 | * requests. Change to LMP that now enables it in the last 16 plies * |
|
- | 4210 | * of search depth, although only the last 8-10 plies really have * |
|
- | 4211 | * a chance for this to kick in unless there are more than 100 legal * |
|
- | 4212 | * moves to try. Minor change to hash path in HashStore() that made * |
|
- | 4213 | * it hard to store entries on the first search after the table was * |
|
- | 4214 | * cleared. Removed Nalimov DTM EGTB code and converted to SYZYGY * |
|
- | 4215 | * WDL/DTC tables instead (courtesy of Ronald de Man). This * |
|
- | 4216 | * correctly handles the 50 move rule where the Nalimov tables * |
|
- | 4217 | * would walk into forced draws (by 50 move rule) while convincing * |
|
- | 4218 | * the search it was winning. Swindle mode now also activates when * |
|
- | 4219 | * in a drawn ending with a material plus for the side on move, as * |
|
- | 4220 | * well as when the best root move is a "cursed win" (forced win, * |
|
- | 4221 | * but drawn because of the 50 move rule). This gives the non-EGTB * |
|
- | 4222 | * opponent the opportunity to turn that 50 move draw into a loss. * |
|
- | 4223 | * There are some changes in the scoring output as a result of this. * |
|
- | 4224 | * The usual +/-MatNN scores show up for real mates, but when in * |
|
- | 4225 | * EGTB endings, the scores are of the form Win or Lose with the * |
|
- | 4226 | * appropriate sign correction (-Win means black is winning, +Lose * |
|
- | 4227 | * means white is losing.) Basil Falcinelli contributed to the new * |
|
- | 4228 | * syzygy code used in this version. Minor change to skill code to * |
|
- | 4229 | * avoid altering search parameters since the speed reduction and * |
|
- | 4230 | * randomness in the eval is more than enough to reduce the Elo. * |
|
- | 4231 | * Minor change to HashProbe() where I now only update the AGE of an * |
|
- | 4232 | * entry that matches the current hash signature if the entry * |
|
- | 4233 | * actually causes a search termination, rather than updating it * |
|
- | 4234 | * each time there is a signature match. If the search is not * |
|
- | 4235 | * terminated on the spot, we have to store an entry when the search * |
|
- | 4236 | * ends which will also overwrite the current exact match and update * |
|
- | 4237 | * the age as well. Suggested by J. Wesley Cleveland on CCC. * |
|
4207 | * |
4238 | * * |
- | 4239 | * 25.2 Minor bug in the fail-high / fail-low code. Crafty is supposed * |
|
- | 4240 | * to deal with the case where the first move produces a score, then * |
|
- | 4241 | * a later move fails high but then produces a worse score. We are * |
|
- | 4242 | * supposed to revert to the better move. An "optimization" made * |
|
- | 4243 | * this fail, but it has been fixed here. "new" command removed as * |
|
- | 4244 | * it is pretty difficult to restore everything once a game has been * |
|
- | 4245 | * started. To start a new game, quit crafty and restart. Crafty * |
|
- | 4246 | * now notifies xboard/winboard to do this automatically so using * |
|
- | 4247 | * those interfaces requires no changes to anything. * |
|
4208 | * * |
4248 | * * |
4209 | ******************************************************************************* |
4249 | ******************************************************************************* |
4210 | */ |
4250 | */ |
4211 | int main(int argc, char **argv) { |
4251 | int main(int argc, char **argv) { |
4212 | TREE *tree; |
4252 | TREE *tree; |
Line 4217... | Line 4257... | ||
4217 | #if defined(UNIX) |
4257 | #if defined(UNIX) |
4218 | char path[1024]; |
4258 | char path[1024]; |
4219 | struct passwd *pwd; |
4259 | struct passwd *pwd; |
4220 | #else |
4260 | #else |
4221 | char crafty_rc_file_spec[FILENAME_MAX]; |
4261 | char crafty_rc_file_spec[FILENAME_MAX]; |
- | 4262 | SYSTEM_INFO sysinfo; |
|
- | 4263 | #endif |
|
- | 4264 | #if defined(UNIX) |
|
- | 4265 | hardware_processors = sysconf(_SC_NPROCESSORS_ONLN); |
|
- | 4266 | #else |
|
- | 4267 | GetSystemInfo(&sysinfo); |
|
- | 4268 | hardware_processors = sysinfo.dwNumberOfProcessors; |
|
4222 | #endif |
4269 | #endif |
4223 | /* Collect environmental variables */ |
4270 | /* Collect environmental variables */ |
4224 | char *directory_spec = getenv("CRAFTY_BOOK_PATH"); |
4271 | char *directory_spec = getenv("CRAFTY_BOOK_PATH"); |
4225 | 4272 | ||
4226 | if (directory_spec) |
4273 | if (directory_spec) |
Line 4354... | Line 4401... | ||
4354 | if (!input_stream) |
4401 | if (!input_stream) |
4355 | if ((pwd = getpwuid(getuid()))) { |
4402 | if ((pwd = getpwuid(getuid()))) { |
4356 | sprintf(path, "%s/.craftyrc", pwd->pw_dir); |
4403 | sprintf(path, "%s/.craftyrc", pwd->pw_dir); |
4357 | input_stream = fopen(path, "r"); |
4404 | input_stream = fopen(path, "r"); |
4358 | } |
4405 | } |
4359 | if (input_stream) |
4406 | if (input_stream) { |
4360 | #else |
4407 | #else |
4361 | sprintf(crafty_rc_file_spec, "%s/crafty.rc", rc_path); |
4408 | sprintf(crafty_rc_file_spec, "%s/crafty.rc", rc_path); |
4362 | if ((input_stream = fopen(crafty_rc_file_spec, "r"))) |
4409 | if ((input_stream = fopen(crafty_rc_file_spec, "r"))) { |
4363 | #endif |
4410 | #endif |
4364 | while (1) { |
4411 | while (1) { |
4365 | readstat = Read(1, buffer); |
4412 | readstat = Read(1, buffer); |
4366 | if (readstat < 0) |
4413 | if (readstat < 0) |
4367 | break; |
4414 | break; |
Line 4371... | Line 4418... | ||
4371 | if (result == 0) |
4418 | if (result == 0) |
4372 | Print(2048, "ERROR \"%s\" is unknown rc-file option\n", buffer); |
4419 | Print(2048, "ERROR \"%s\" is unknown rc-file option\n", buffer); |
4373 | if (input_stream == stdin) |
4420 | if (input_stream == stdin) |
4374 | break; |
4421 | break; |
4375 | } |
4422 | } |
- | 4423 | } |
|
4376 | input_stream = stdin; |
4424 | input_stream = stdin; |
4377 | #if defined(UNIX) |
4425 | #if defined(UNIX) |
4378 | if (xboard) |
4426 | if (xboard) |
4379 | signal(SIGINT, SIG_IGN); |
4427 | signal(SIGINT, SIG_IGN); |
4380 | #endif |
4428 | #endif |
- | 4429 | if (smp_max_threads) |
|
4381 | Print(32, "\nCrafty v%s (%d |
4430 | Print(32, "\nCrafty v%s (%d threads)\n\n", version, smp_max_threads); |
4382 |
|
4431 | else |
- | 4432 | Print(32, "\nCrafty v%s\n\n", version); |
|
- | 4433 | if (hardware_processors > 0) |
|
- | 4434 | Print(32, "machine has %d processors\n\n", hardware_processors); |
|
- | 4435 | ||
4383 | /* |
4436 | /* |
4384 | ************************************************************ |
4437 | ************************************************************ |
4385 | * * |
4438 | * * |
4386 | * Check to see if we can find a "crafty.cpf" personality * |
4439 | * Check to see if we can find a "crafty.cpf" personality * |
4387 | * file which contains the default personality settings to * |
4440 | * file which contains the default personality settings to * |
Line 4455... | Line 4508... | ||
4455 | ************************************************************ |
4508 | ************************************************************ |
4456 | */ |
4509 | */ |
4457 | while (1) { |
4510 | while (1) { |
4458 | presult = 0; |
4511 | presult = 0; |
4459 | do { |
4512 | do { |
4460 | if (new_game) |
- | |
4461 | NewGame(0); |
- | |
4462 | opponent_start_time = ReadClock(); |
4513 | opponent_start_time = ReadClock(); |
4463 | input_status = 0; |
4514 | input_status = 0; |
4464 | display = tree->position; |
4515 | display = tree->position; |
4465 | move = 0; |
4516 | move = 0; |
4466 | presult = 0; |
4517 | presult = 0; |
Line 4564... | Line 4615... | ||
4564 | value = DrawScore(game_wtm); |
4615 | value = DrawScore(game_wtm); |
4565 | if (xboard) |
4616 | if (xboard) |
4566 | Print(-1, "1/2-1/2 {Drawn by 3-fold repetition}\n"); |
4617 | Print(-1, "1/2-1/2 {Drawn by 3-fold repetition}\n"); |
4567 | } |
4618 | } |
4568 | if (draw_type == 2) { |
4619 | if (draw_type == 2) { |
- | 4620 | if (!Mated(tree, 0, game_wtm)) { |
|
4569 | Print(1, "I claim a draw by the 50 move rule.\n"); |
4621 | Print(1, "I claim a draw by the 50 move rule.\n"); |
4570 | value = DrawScore(game_wtm); |
4622 | value = DrawScore(game_wtm); |
4571 | if (xboard) |
4623 | if (xboard) |
4572 | Print(-1, "1/2-1/2 {Drawn by 50-move rule}\n"); |
4624 | Print(-1, "1/2-1/2 {Drawn by 50-move rule}\n"); |
- | 4625 | } |
|
4573 | } |
4626 | } |
4574 | if (Drawn(tree, last_search_value) == 2) { |
4627 | if (Drawn(tree, last_search_value) == 2) { |
4575 | Print(1, "I claim a draw due to insufficient material.\n"); |
4628 | Print(1, "I claim a draw due to insufficient material.\n"); |
4576 | if (xboard) |
4629 | if (xboard) |
4577 | Print(-1, "1/2-1/2 {Insufficient material}\n"); |
4630 | Print(-1, "1/2-1/2 {Insufficient material}\n"); |
4578 | } |
4631 | } |
4579 | } else |
4632 | } else |
4580 | tree->status[1] = tree->status[0]; |
- | |
4581 | presult = 0; |
4633 | presult = 0; |
4582 | } |
- | |
4583 | #if defined(DEBUG) |
4634 | #if defined(DEBUG) |
4584 | ValidatePosition(tree, 0, move, "Main(1)"); |
4635 | ValidatePosition(tree, 0, move, "Main(1)"); |
4585 | #endif |
4636 | #endif |
4586 | } while (force); |
4637 | } while (force); |
4587 | /* |
4638 | /* |
Line 4610... | Line 4661... | ||
4610 | if (presult != 1) { |
4661 | if (presult != 1) { |
4611 | strcpy(kibitz_text, "n/a"); |
4662 | strcpy(kibitz_text, "n/a"); |
4612 | last_pv.pathd = 0; |
4663 | last_pv.pathd = 0; |
4613 | last_pv.pathl = 0; |
4664 | last_pv.pathl = 0; |
4614 | display = tree->position; |
4665 | display = tree->position; |
- | 4666 | tree->status[1] = tree->status[0]; |
|
4615 | value = Iterate(game_wtm, think, 0); |
4667 | value = Iterate(game_wtm, think, 0); |
4616 | } |
4668 | } |
4617 | /* |
4669 | /* |
4618 | ************************************************************ |
4670 | ************************************************************ |
4619 | * * |
4671 | * * |
Line 4684... | Line 4736... | ||
4684 | last_value = value; |
4736 | last_value = value; |
4685 | if (MateScore(last_value)) |
4737 | if (MateScore(last_value)) |
4686 | last_mate_score = last_value; |
4738 | last_mate_score = last_value; |
4687 | thinking = 0; |
4739 | thinking = 0; |
4688 | if (!last_pv.pathl) { |
4740 | if (!last_pv.pathl) { |
4689 | if ( |
4741 | if (Check(game_wtm)) { |
4690 | over = 1; |
4742 | over = 1; |
4691 | if (game_wtm) { |
4743 | if (game_wtm) { |
4692 | Print(-1, "0-1 {Black mates}\n"); |
4744 | Print(-1, "0-1 {Black mates}\n"); |
4693 | strcpy(pgn_result, "0-1"); |
4745 | strcpy(pgn_result, "0-1"); |
4694 | } else { |
4746 | } else { |
Line 4782... | Line 4834... | ||
4782 | last_pv.path[1])); |
4834 | last_pv.path[1])); |
4783 | last_search_value = value; |
4835 | last_search_value = value; |
4784 | if (kibitz) { |
4836 | if (kibitz) { |
4785 | if (kibitz_depth) |
4837 | if (kibitz_depth) |
4786 | Kibitz(2, game_wtm, kibitz_depth, end_time - start_time, value, |
4838 | Kibitz(2, game_wtm, kibitz_depth, end_time - start_time, value, |
4787 | tree->nodes_searched, busy_percent, |
4839 | tree->nodes_searched, busy_percent, tree->egtb_hits, |
4788 | kibitz_text); |
4840 | kibitz_text); |
4789 | else |
4841 | else |
4790 | Kibitz(4, game_wtm, 0, 0, 0, 0, 0, 0, kibitz_text); |
4842 | Kibitz(4, game_wtm, 0, 0, 0, 0, 0, 0, kibitz_text); |
4791 | } |
4843 | } |
4792 | MakeMoveRoot(tree, game_wtm, last_pv.path[1]); |
4844 | MakeMoveRoot(tree, game_wtm, last_pv.path[1]); |