1/* 2 Sjeng - a chess variants playing program 3 Copyright (C) 2000-2001 Gian-Carlo Pascutto 4 Originally based on Faile, Copyright (c) 2000 Adrien M. Regimbald 5 6 This program 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 2 of the License, or 9 (at your option) any later version. 10 11 This program 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, write to the Free Software 18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 20 As a special exception, Gian-Carlo Pascutto gives permission 21 to link this program with the Nalimov endgame database access 22 code. See the Copying/Distribution section in the README file 23 for more details. 24 25 File: sjeng.c 26 Purpose: main program, xboard/user interface 27 28*/ 29 30#include "sjeng.h" 31#include "protos.h" 32#include "extvars.h" 33#include "config.h" 34#include <machine/endian.h> 35 36char divider[50] = "-------------------------------------------------"; 37move_s dummy = {0,0,0,0,0}; 38 39int board[144], moved[144], ep_square, white_to_move, comp_color, wking_loc, 40 bking_loc, white_castled, black_castled, result, ply, pv_length[PV_BUFF], 41 pieces[62], squares[144], num_pieces, i_depth, fifty, piece_count; 42 43int32_t nodes, raw_nodes, qnodes, killer_scores[PV_BUFF], 44 killer_scores2[PV_BUFF], killer_scores3[PV_BUFF], moves_to_tc, min_per_game, 45 sec_per_game, inc, time_left, opp_time, time_cushion, time_for_move, cur_score; 46 47uint32_t history_h[144][144]; 48 49uint32_t hash_history[600]; 50int move_number; 51 52bool captures, searching_pv, post, time_exit, time_failure; 53 54int xb_mode, maxdepth; 55 56int phase; 57int root_to_move; 58 59int my_rating, opp_rating; 60 61char setcode[30]; 62 63move_s pv[PV_BUFF][PV_BUFF], killer1[PV_BUFF], killer2[PV_BUFF], 64 killer3[PV_BUFF]; 65 66move_x path_x[PV_BUFF]; 67move_s path[PV_BUFF]; 68 69rtime_t start_time; 70 71int is_promoted[62]; 72 73int NTries, NCuts, TExt; 74uint32_t PVS, FULL, PVSF; 75int EGTBHits, EGTBProbes; 76 77bool is_pondering, allow_pondering, is_analyzing; 78 79int Variant; 80int Giveaway; 81 82char my_partner[STR_BUFF]; 83bool have_partner; 84bool must_sit; 85bool go_fast; 86 87int32_t fixed_time; 88 89FILE *lrn_standard; 90FILE *lrn_zh; 91FILE *lrn_suicide; 92FILE *lrn_losers; 93 94/* 95 * sjeng expects to get away with calling fclose(NULL), which crashes 96 * on MacOS X 97 */ 98void safe_fclose(FILE * f) 99{ 100 if (f) fclose(f); 101} 102 103/* 104 * We'll keep different learning files on big endian and little endian machines. 105 */ 106FILE * learn_open(const char * name, const char * label) 107{ 108 FILE *lrn; 109 char fname[30]; 110 111 sprintf(fname, "%s_%cE.lrn", label, 112#if __DARWIN_BYTE_ORDER == __DARWIN_BIG_ENDIAN 113 'B' 114#elif __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN 115 'L' 116#else 117#error Unknown Byte Order 118#endif 119 ); 120 121 if ((lrn = fopen (fname, "rb+")) == NULL) { 122 printf("No %s learn file.\n", name); 123 124 if ((lrn = fopen (fname, "wb+")) == NULL) { 125 printf("Error creating %s learn file.\n", name); 126 } else { 127 fclose(lrn); 128 lrn = fopen (fname, "rb+"); 129 } 130 } 131 return lrn; 132} 133 134 135int main (int argc, char *argv[]) { 136 137 char input[STR_BUFF], *p, output[STR_BUFF]; 138 char readbuff[STR_BUFF]; 139 move_s move, comp_move; 140 int depth = 4; 141 bool force_mode, show_board; 142 double nps, elapsed; 143 clock_t cpu_start, cpu_end; 144 move_s game_history[600]; 145 move_x game_history_x[600]; 146 int is_edit_mode, edit_color; 147 int confirm_moves; 148 int pingnum; 149 int braindeadinterface; 150 int automode; 151 rtime_t xstart_time; 152 153 read_rcfile(); 154 initialize_zobrist(); 155 156 Variant = Normal; 157 //Variant = Crazyhouse; 158 159 memcpy(material, std_material, sizeof(std_material)); 160 //memcpy(material, zh_material, sizeof(zh_material)); 161 162 if (!init_book()) 163 printf("No .OPN opening book found.\n"); 164 165 lrn_standard = learn_open("standard", "standard"); 166 lrn_zh = learn_open("crazyhouse", "bug"); 167 lrn_suicide = learn_open("suicide", "suicide"); 168 lrn_losers = learn_open("losers", "losers"); 169 170 start_up (); 171 init_game (); 172 173 initialize_hash(); 174 clear_tt(); 175 reset_ecache(); 176 177 if (init_segtb()) 178 SEGTB = TRUE; 179 else 180 SEGTB = FALSE; 181 182 EGTBProbes = 0; 183 EGTBHits = 0; 184 ECacheProbes = 0; 185 ECacheHits = 0; 186 TTProbes = 0; 187 TTStores = 0; 188 TTHits = 0; 189 bookidx = 0; 190 total_moves = 0; 191 ply = 0; 192 braindeadinterface = 0; 193 moves_to_tc = 40; 194 min_per_game = 5; 195 time_left = 30000; 196 my_rating = opp_rating = 2000; 197 maxdepth = 40; 198 must_go = 1; 199 tradefreely = 1; 200 automode = 0; 201 202 xb_mode = FALSE; 203 force_mode = FALSE; 204 comp_color = 0; 205 show_board = TRUE; 206 is_pondering = FALSE; 207 allow_pondering = TRUE; 208 is_analyzing = FALSE; 209 is_edit_mode = FALSE; 210 have_partner = FALSE; 211 must_sit = FALSE; 212 go_fast = FALSE; 213 fixed_time = FALSE; 214 phase = Opening; 215 root_to_move = WHITE; 216 kibitzed = FALSE; 217 confirm_moves = FALSE; 218 219 move_number = 0; 220 memset(game_history, 0, sizeof(game_history)); 221 memset(game_history_x, 0, sizeof(game_history_x)); 222 223 hash_history[move_number] = hash; 224 225 setbuf (stdout, NULL); 226 setbuf (stdin, NULL); 227 228 /* keep looping for input, and responding to it: */ 229 while (TRUE) { 230 231 /* case where it's the computer's turn to move: */ 232 if (!is_edit_mode && (comp_color == white_to_move || automode) 233 && !force_mode && !must_sit && !result) { 234 235 /* whatever happens, never allow pondering in normal search */ 236 is_pondering = FALSE; 237 238 cpu_start = clock (); 239 comp_move = think (); 240 cpu_end = clock(); 241 242 ply = 0; 243 244 /* must_sit can be changed by search */ 245 if (!must_sit || must_go != 0) 246 { 247 /* check for a game end: */ 248 if (( 249 ((Variant == Losers || Variant == Suicide) 250 && 251 ((result != white_is_mated) && (result != black_is_mated))) 252 || 253 ((Variant == Normal || Variant == Crazyhouse || Variant == Bughouse) 254 && ((comp_color == 1 && result != white_is_mated) 255 || 256 (comp_color == 0 && result != black_is_mated) 257 ))) 258 && result != stalemate 259 && result != draw_by_fifty 260 && result != draw_by_rep) 261 { 262 263 comp_to_coord (comp_move, output); 264 265 hash_history[move_number] = hash; 266 267 game_history[move_number] = comp_move; 268 make (&comp_move, 0); 269 270 /* saves state info */ 271 game_history_x[move_number++] = path_x[0]; 272 273 userealholdings = 0; 274 must_go--; 275 276 /* check to see if we draw by rep/fifty after our move: */ 277 if (is_draw ()) { 278 result = draw_by_rep; 279 } 280 else if (fifty > 100) { 281 result = draw_by_fifty; 282 } 283 284 root_to_move ^= 1; 285 286 reset_piece_square (); 287 288 if (book_ply < 40) { 289 if (!book_ply) { 290 strcpy(opening_history, output); 291 } 292 else { 293 strcat(opening_history, output); 294 } 295 } 296 297 book_ply++; 298 299 printf ("\nNodes: %d (%0.2f%% qnodes)\n", nodes, 300 (float) ((float) qnodes / (float) nodes * 100.0)); 301 302 elapsed = (cpu_end-cpu_start)/(double) CLOCKS_PER_SEC; 303 nps = (float) nodes/(float) elapsed; 304 305 if (!elapsed) 306 printf ("NPS: N/A\n"); 307 else 308 printf ("NPS: %d\n", (int32_t) nps); 309 310 printf("ECacheProbes : %d ECacheHits : %d HitRate : %f%%\n", 311 ECacheProbes, ECacheHits, 312 ((float)ECacheHits/((float)ECacheProbes+1)) * 100); 313 314 printf("TTStores : %d TTProbes : %d TTHits : %d HitRate : %f%%\n", 315 TTStores, TTProbes, TTHits, 316 ((float)TTHits/((float)TTProbes+1)) * 100); 317 318 printf("NTries : %d NCuts : %d CutRate : %f%% TExt: %d\n", 319 NTries, NCuts, (((float)NCuts*100)/((float)NTries+1)), TExt); 320 321 printf("Check extensions: %d Razor drops : %d Razor Material : %d\n", ext_check, razor_drop, razor_material); 322 323 printf("EGTB Hits: %d EGTB Probes: %d Efficiency: %3.1f%%\n", EGTBHits, EGTBProbes, 324 (((float)EGTBHits*100)/(float)(EGTBProbes+1))); 325 326 printf("Move ordering : %f%%\n", (((float)FHF*100)/(float)(FH+1))); 327 328 printf("Material score: %d Eval : %d White hand: %d Black hand : %d\n", 329 Material, (int)eval(), white_hand_eval, black_hand_eval); 330 331 printf("Hash : %X HoldHash : %X\n", (unsigned)hash, (unsigned)hold_hash); 332 333 /* check to see if we mate our opponent with our current move: */ 334 if (!result) { 335 if (xb_mode) { 336 337 /* safety in place here */ 338 if (comp_move.from != dummy.from || comp_move.target != dummy.target) 339 printf ("move %s\n", output); 340 341 if (Variant == Bughouse) 342 { 343 CheckBadFlow(FALSE); 344 } 345 } 346 else { 347 if (comp_move.from != dummy.from || comp_move.target != dummy.target) 348 printf ("\n%s\n", output); 349 } 350 } 351 else { 352 if (xb_mode) { 353 if (comp_move.from != dummy.from || comp_move.target != dummy.target) 354 printf ("move %s\n", output); 355 } 356 else { 357 if (comp_move.from != dummy.from || comp_move.target != dummy.target) 358 printf ("\n%s\n", output); 359 } 360 if (result == white_is_mated) { 361 printf ("0-1 {Black Mates}\n"); 362 } 363 else if (result == black_is_mated) { 364 printf ("1-0 {White Mates}\n"); 365 } 366 else if (result == draw_by_fifty) { 367 printf ("1/2-1/2 {Fifty move rule}\n"); 368 } 369 else if (result == draw_by_rep) { 370 printf ("1/2-1/2 {3 fold repetition}\n"); 371 } 372 else { 373 printf ("1/2-1/2 {Draw}\n"); 374 } 375 automode = 0; 376 } 377 } 378 /* we have been mated or stalemated: */ 379 else { 380 if (result == white_is_mated) { 381 printf ("0-1 {Black Mates}\n"); 382 } 383 else if (result == black_is_mated) { 384 printf ("1-0 {White Mates}\n"); 385 } 386 else if (result == draw_by_fifty) { 387 printf ("1/2-1/2 {Fifty move rule}\n"); 388 } 389 else if (result == draw_by_rep) { 390 printf ("1/2-1/2 {3 fold repetition}\n"); 391 } 392 else { 393 printf ("1/2-1/2 {Draw}\n"); 394 } 395 automode = 0; 396 } 397 } 398 } 399 400 /* get our input: */ 401 if (!xb_mode) { 402 if (show_board) { 403 printf ("\n"); 404 display_board (stdout, 1-comp_color); 405 } 406 if (!automode) 407 { 408 printf ("Sjeng: "); 409 rinput (input, STR_BUFF, stdin); 410 } 411 } 412 else { 413 /* start pondering */ 414 415 if ((must_sit || (allow_pondering && !is_edit_mode && !force_mode && 416 move_number != 0) || is_analyzing) && !result && !automode) 417 { 418 is_pondering = TRUE; 419 think(); 420 is_pondering = FALSE; 421 422 ply = 0; 423 } 424 if (!automode) 425 { 426 rinput (input, STR_BUFF, stdin); 427 } 428 } 429 430 /* check to see if we have a move. If it's legal, play it. */ 431 if (!is_edit_mode && is_move (&input[0])) { 432 if (verify_coord (input, &move)) { 433 434 if (confirm_moves) printf ("Legal move: %s\n", input); 435 436 game_history[move_number] = move; 437 hash_history[move_number] = hash; 438 439 make (&move, 0); 440 game_history_x[move_number++] = path_x[0]; 441 442 reset_piece_square (); 443 444 root_to_move ^= 1; 445 446 if (book_ply < 40) { 447 if (!book_ply) { 448 strcpy(opening_history, input); 449 } 450 else { 451 strcat(opening_history, input); 452 } 453 } 454 455 book_ply++; 456 457 if (show_board) { 458 printf ("\n"); 459 display_board (stdout, 1-comp_color); 460 } 461 } 462 else { 463 printf ("Illegal move: %s\n", input); 464 } 465 } 466 else { 467 468 /* make everything lower case for convenience: */ 469 /* GCP: except for setboard, which is case sensitive */ 470 if (!strstr(input, "setboard")) 471 for (p = input; *p; p++) *p = tolower (*p); 472 473 /* command parsing: */ 474 if (!strcmp (input, "quit") || (!input[0] && feof(stdin))) { 475 safe_fclose(lrn_standard); 476 safe_fclose(lrn_zh); 477 safe_fclose(lrn_suicide); 478 safe_fclose(lrn_losers); 479 free_hash(); 480 free_ecache(); 481 exit (EXIT_SUCCESS); 482 } 483 else if (!strcmp (input, "exit")) 484 { 485 if (is_analyzing) 486 { 487 is_analyzing = FALSE; 488 is_pondering = FALSE; 489 time_for_move = 0; 490 } 491 else 492 { 493 safe_fclose(lrn_standard); 494 safe_fclose(lrn_zh); 495 safe_fclose(lrn_suicide); 496 safe_fclose(lrn_losers); 497 free_hash(); 498 free_ecache(); 499 exit (EXIT_SUCCESS); 500 } 501 } 502 else if (!strcmp (input, "diagram") || !strcmp (input, "d")) { 503 toggle_bool (&show_board); 504 } 505 else if (!strncmp (input, "perft", 5)) { 506 sscanf (input+6, "%d", &depth); 507 raw_nodes = 0; 508 xstart_time = rtime(); 509 perft (depth); 510 printf ("Raw nodes for depth %d: %d\n", depth, raw_nodes); 511 printf("Time : %.2f\n", (float)rdifftime(rtime(), xstart_time)/100.); 512 } 513 else if (!strcmp (input, "confirm_moves")) { 514 confirm_moves = TRUE; 515 printf("Will now confirm moves.\n"); 516 } 517 else if (!strcmp (input, "new")) { 518 519 if (xb_mode) 520 { 521 printf("tellics set 1 Sjeng " VERSION " (2001-9-28/%s)\n", setcode); 522 } 523 524 if (!is_analyzing) 525 { 526 memcpy(material, std_material, sizeof(std_material)); 527 Variant = Normal; 528 529 // memcpy(material, zh_material, sizeof(zh_material)); 530 //Variant = Crazyhouse; 531 532 init_game (); 533 initialize_hash(); 534 535 if (!braindeadinterface) 536 { 537 clear_tt(); 538 init_book(); 539 reset_ecache(); 540 } 541 542 force_mode = FALSE; 543 must_sit = FALSE; 544 go_fast = FALSE; 545 piecedead = FALSE; 546 partnerdead = FALSE; 547 kibitzed = FALSE; 548 fixed_time = FALSE; 549 550 root_to_move = WHITE; 551 552 comp_color = 0; 553 move_number = 0; 554 hash_history[move_number] = 0; 555 bookidx = 0; 556 my_rating = opp_rating = 2000; 557 must_go = 0; 558 tradefreely = 1; 559 automode = 0; 560 561 CheckBadFlow(TRUE); 562 ResetHandValue(); 563 } 564 else 565 { 566 init_game (); 567 move_number = 0; 568 } 569 570 } 571 else if (!strcmp (input, "xboard")) { 572 xb_mode = TRUE; 573 toggle_bool (&show_board); 574 signal (SIGINT, SIG_IGN); 575 printf ("\n"); 576 577 /* Reset f5 in case we left with partner */ 578 printf("tellics set f5 1=1\n"); 579 580 BegForPartner(); 581 } 582 else if (!strcmp (input, "nodes")) { 583 printf ("Number of nodes: %d (%0.2f%% qnodes)\n", nodes, 584 (float) ((float) qnodes / (float) nodes * 100.0)); 585 } 586 else if (!strcmp (input, "nps")) { 587 elapsed = (cpu_end-cpu_start)/(double) CLOCKS_PER_SEC; 588 nps = (float) nodes/(float) elapsed; 589 if (!elapsed) 590 printf ("NPS: N/A\n"); 591 else 592 printf ("NPS: %d\n", (int32_t) nps); 593 } 594 else if (!strcmp (input, "post")) { 595 toggle_bool (&post); 596 if (xb_mode) 597 post = TRUE; 598 } 599 else if (!strcmp (input, "nopost")) { 600 post = FALSE; 601 } 602 else if (!strcmp (input, "random")) { 603 continue; 604 } 605 else if (!strcmp (input, "hard")) { 606 607 allow_pondering = TRUE; 608 609 continue; 610 } 611 else if (!strcmp (input, "easy")) { 612 613 allow_pondering = FALSE; 614 615 continue; 616 } 617 else if (!strcmp (input, "?")) { 618 continue; 619 } 620 else if (!strcmp (input, "white")) { 621 white_to_move = 1; 622 root_to_move = WHITE; 623 comp_color = 0; 624 } 625 else if (!strcmp (input, "black")) { 626 white_to_move = 0; 627 root_to_move = BLACK; 628 comp_color = 1; 629 } 630 else if (!strcmp (input, "force")) { 631 force_mode = TRUE; 632 } 633 else if (!strcmp (input, "eval")) { 634 check_phase(); 635 printf("Eval: %d\n", (int)eval()); 636 } 637 else if (!strcmp (input, "go")) { 638 comp_color = white_to_move; 639 force_mode = FALSE; 640 } 641 else if (!strncmp (input, "time", 4)) { 642 sscanf (input+5, "%d", &time_left); 643 } 644 else if (!strncmp (input, "otim", 4)) { 645 sscanf (input+5, "%d", &opp_time); 646 } 647 else if (!strncmp (input, "level", 5)) { 648 if (strstr(input+6, ":")) 649 { 650 /* time command with seconds */ 651 sscanf (input+6, "%d %d:%d %d", &moves_to_tc, &min_per_game, 652 &sec_per_game, &inc); 653 time_left = (min_per_game*6000) + (sec_per_game * 100); 654 opp_time = time_left; 655 } 656 else 657 { 658 /* extract the time controls: */ 659 sscanf (input+6, "%d %d %d", &moves_to_tc, &min_per_game, &inc); 660 time_left = min_per_game*6000; 661 opp_time = time_left; 662 } 663 fixed_time = FALSE; 664 time_cushion = 0; 665 } 666 else if (!strncmp (input, "rating", 6)) { 667 sscanf (input+7, "%d %d", &my_rating, &opp_rating); 668 if (my_rating == 0) my_rating = 2000; 669 if (opp_rating == 0) opp_rating = 2000; 670 } 671 else if (!strncmp (input, "holding", 7)) { 672 ProcessHoldings(input); 673 } 674 else if (!strncmp (input, "variant", 7)) { 675 if (strstr(input, "normal")) 676 { 677 Variant = Normal; 678 memcpy(material, std_material, sizeof(std_material)); 679 init_book(); 680 } 681 else if (strstr(input, "crazyhouse")) 682 { 683 Variant = Crazyhouse; 684 memcpy(material, zh_material, sizeof(zh_material)); 685 init_book(); 686 } 687 else if (strstr(input, "bughouse")) 688 { 689 Variant = Bughouse; 690 memcpy(material, zh_material, sizeof(zh_material)); 691 init_book(); 692 } 693 else if (strstr(input, "suicide")) 694 { 695 Variant = Suicide; 696 Giveaway = FALSE; 697 memcpy(material, suicide_material, sizeof(suicide_material)); 698 init_book(); 699 } 700 else if (strstr(input, "giveaway")) 701 { 702 Variant = Suicide; 703 Giveaway = TRUE; 704 memcpy(material, suicide_material, sizeof(suicide_material)); 705 init_book(); 706 } 707 else if (strstr(input, "losers")) 708 { 709 Variant = Losers; 710 memcpy(material, losers_material, sizeof(losers_material)); 711 init_book(); 712 } 713 714 initialize_hash(); 715 clear_tt(); 716 reset_ecache(); 717 718 } 719 else if (!strncmp (input, "analyze", 7)) { 720 is_analyzing = TRUE; 721 is_pondering = TRUE; 722 think(); 723 ply = 0; 724 } 725 else if (!strncmp (input, "undo", 4)) { 726 printf("Move number : %d\n", move_number); 727 if (move_number > 0) 728 { 729 ply = 1; 730 path_x[0] = game_history_x[--move_number]; 731 unmake(&game_history[move_number], 0); 732 reset_piece_square(); 733 root_to_move ^= 1; 734 } 735 result = 0; 736 } 737 else if (!strncmp (input, "remove", 5)) { 738 if (move_number > 1) 739 { 740 ply = 1; 741 path_x[0] = game_history_x[--move_number]; 742 unmake(&game_history[move_number], 0); 743 reset_piece_square(); 744 745 ply = 1; 746 path_x[0] = game_history_x[--move_number]; 747 unmake(&game_history[move_number], 0); 748 reset_piece_square(); 749 } 750 result = 0; 751 } 752 else if (!strncmp (input, "edit", 4)) { 753 is_edit_mode = TRUE; 754 edit_color = WHITE; 755 } 756 else if (!strncmp (input, ".", 1) && is_edit_mode) { 757 is_edit_mode = FALSE; 758 if (wking_loc == 30) white_castled = no_castle; 759 if (bking_loc == 114) black_castled = no_castle; 760 book_ply = 50; 761 ep_square = 0; 762 move_number = 0; 763 memset(opening_history, 0, sizeof(opening_history)); 764 clear_tt(); 765 initialize_hash(); 766 reset_piece_square(); 767 } 768 else if (is_edit_mode && !strncmp (input, "c", 1)) { 769 if (edit_color == WHITE) edit_color = BLACK; else edit_color = WHITE; 770 } 771 else if (is_edit_mode && !strncmp (input, "#", 1)) { 772 reset_board(); 773 move_number = 0; 774 } 775 else if (is_edit_mode 776 && isalpha(input[0]) 777 && isalpha(input[1]) 778 && isdigit(input[2])) { 779 PutPiece(edit_color, input[0], input[1], input[2]); 780 } 781 else if (!strncmp (input, "partner", 7)) { 782 HandlePartner(input+7); 783 } 784 else if (!strncmp (input, "$partner", 8)) { 785 HandlePartner(input+8); 786 } 787 else if (!strncmp (input, "ptell", 5)) { 788 HandlePtell(input); 789 } 790 else if (!strncmp (input, "test", 4)) { 791 run_epd_testsuite(); 792 } 793 else if (!strncmp (input, "st", 2)) { 794 sscanf(input+3, "%d", &fixed_time); 795 fixed_time = fixed_time * 100; 796 } 797 else if (!strncmp (input, "book", 4)) { 798 build_book(); 799 } 800 else if (!strncmp (input, "speed", 5)) { 801 speed_test(); 802 } 803 else if (!strncmp (input, "result", 6)) { 804 if (cfg_booklearn) 805 { 806 if (strstr (input+7, "1-0")) 807 { 808 if (comp_color == 1) 809 book_learning(WIN); 810 else 811 book_learning(LOSS); 812 } 813 else if (strstr(input+7, "0-1")) 814 { 815 if (comp_color == 1) 816 book_learning(LOSS); 817 else 818 book_learning(WIN); 819 } 820 else if (strstr(input+7, "1/2-1/2")) 821 { 822 book_learning(DRAW); 823 }; 824 } 825 } 826 else if (!strncmp (input, "prove", 5)) { 827 printf("\nMax time to search (s): "); 828 start_time = rtime(); 829 rinput(readbuff, STR_BUFF, stdin); 830 pn_time = atoi(readbuff) * 100; 831 printf("\n"); 832 proofnumbersearch(); 833 } 834 else if (!strncmp (input, "ping", 4)) { 835 sscanf (input+5, "%d", &pingnum); 836 printf("pong %d\n", pingnum); 837 } 838 else if (!strncmp (input, "fritz", 5)) { 839 braindeadinterface = TRUE; 840 } 841 else if (!strncmp (input, "reset", 5)) { 842 843 memcpy(material, std_material, sizeof(std_material)); 844 Variant = Normal; 845 846 init_game (); 847 initialize_hash(); 848 849 clear_tt(); 850 init_book(); 851 reset_ecache(); 852 853 force_mode = FALSE; 854 fixed_time = FALSE; 855 856 root_to_move = WHITE; 857 858 comp_color = 0; 859 move_number = 0; 860 bookidx = 0; 861 my_rating = opp_rating = 2000; 862 } 863 else if (!strncmp (input, "setboard", 8)) { 864 setup_epd_line(input+9); 865 } 866 else if (!strncmp (input, "buildegtb", 9)) { 867 Variant = Suicide; 868 gen_all_tables(); 869 } 870 else if (!strncmp (input, "lookup", 6)) { 871 Variant = Suicide; 872 printf("Value : %d\n", egtb(white_to_move)); 873 } 874 else if (!strncmp (input, ".", 1)) { 875 /* periodic updating and were not searching */ 876 /* most likely due to proven mate */ 877 continue; 878 } 879 else if (!strncmp (input, "sd", 2)) { 880 sscanf(input+3, "%d", &maxdepth); 881 printf("New max depth set to: %d\n", maxdepth); 882 continue; 883 } 884 else if (!strncmp (input, "auto", 4)) { 885 automode = 1; 886 continue; 887 } 888 else if (!strncmp (input, "protover", 8)) { 889 printf("feature ping=1 setboard=1 playother=0 san=0 usermove=0 time=1\n"); 890 printf("feature draw=0 sigint=0 sigterm=0 reuse=1 analyze=1\n"); 891 printf("feature myname=\"Sjeng " VERSION "\"\n"); 892 printf("feature variants=\"normal,bughouse,crazyhouse,suicide,giveaway,losers\"\n"); 893 printf("feature colors=1 ics=0 name=0 pause=0 done=1\n"); 894 xb_mode = 2; 895 } 896 else if (!strncmp (input, "accepted", 8)) { 897 /* do nothing as of yet */ 898 } 899 else if (!strncmp (input, "rejected", 8)) { 900 printf("Interface does not support a required feature...expect trouble.\n"); 901 } 902 else if (!strncmp (input, "warranty", 8)) { 903 printf("\n BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n" 904 "FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\n" 905 "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n" 906 "PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n" 907 "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n" 908 "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\n" 909 "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\n" 910 "PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n" 911 "REPAIR OR CORRECTION.\n" 912 "\n"); 913 printf(" IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n" 914 "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n" 915 "REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n" 916 "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n" 917 "OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n" 918 "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n" 919 "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n" 920 "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n" 921 "POSSIBILITY OF SUCH DAMAGES.\n\n"); 922 923 } 924 else if (!strncmp (input, "distribution", 12)) { 925 printf("\n You may copy and distribute verbatim copies of the Program's\n" 926 "source code as you receive it, in any medium, provided that you\n" 927 "conspicuously and appropriately publish on each copy an appropriate\n" 928 "copyright notice and disclaimer of warranty; keep intact all the\n" 929 "notices that refer to this License and to the absence of any warranty;\n" 930 "and give any other recipients of the Program a copy of this License\n" 931 "along with the Program.\n" 932 "\n" 933 "You may charge a fee for the physical act of transferring a copy, and\n" 934 "you may at your option offer warranty protection in exchange for a fee.\n\n"); 935 936 } 937 else if (!strcmp (input, "help")) { 938 printf ("\n%s\n\n", divider); 939 printf ("diagram/d: toggle diagram display\n"); 940 printf ("exit/quit: terminate Sjeng\n"); 941 printf ("go: make Sjeng play the side to move\n"); 942 printf ("new: start a new game\n"); 943 printf ("level <x>: the xboard style command to set time\n"); 944 printf (" <x> should be in the form: <a> <b> <c> where:\n"); 945 printf (" a -> moves to TC (0 if using an ICS style TC)\n"); 946 printf (" b -> minutes per game\n"); 947 printf (" c -> increment in seconds\n"); 948 printf ("nodes: outputs the number of nodes searched\n"); 949 printf ("nps: outputs Sjeng's NPS in search\n"); 950 printf ("perft <x>: compute raw nodes to depth x\n"); 951 printf ("post: toggles thinking output\n"); 952 printf ("xboard: put Sjeng into xboard mode\n"); 953 printf ("test: run an EPD testsuite\n"); 954 printf ("speed: test movegen and evaluation speed\n"); 955 printf ("warranty: show warranty details\n"); 956 printf ("distribution: show distribution details\n"); 957 printf( "proof: try to prove or disprove the current pos\n"); 958 printf( "sd <x>: limit thinking to depth x\n"); 959 printf( "st <x>: limit thinking to x centiseconds\n"); 960 printf( "setboard <FEN>: set board to a specified FEN string\n"); 961 printf( "undo: back up a half move\n"); 962 printf( "remove: back up a full move\n"); 963 printf( "force: disable computer moving\n"); 964 printf( "auto: computer plays both sides\n"); 965 printf ("\n%s\n\n", divider); 966 967 show_board = 0; 968 } 969 else if (!xb_mode) { 970 printf ("Illegal move: %s\n", input); 971 } 972 973 } 974 975 } 976 977 return 0; 978 979} 980