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