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