home *** CD-ROM | disk | FTP | other *** search
/ Dream 57 / Amiga_Dream_57.iso / Amiga / Jeux / Reflexion / Crafty-15.19.lha / crafty-15.19 / src / ponder.c < prev    next >
C/C++ Source or Header  |  1998-09-13  |  9KB  |  201 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "chess.h"
  5. #include "data.h"
  6.  
  7. /* last modified 07/08/98 */
  8. /*
  9. ********************************************************************************
  10. *                                                                              *
  11. *   Ponder() is the driver for "pondering" (thinking on the opponent's time.)  *
  12. *   its operation is simple:  find a predicted move by (a) taking the second   *
  13. *   move from the principal variation, or (b) call lookup to see if it finds   *
  14. *   a suggested move from the transposition table.  then, make this move and   *
  15. *   do a search from the resulting position.  while pondering, one of three    *
  16. *   things can happen:  (1) a move is entered, and it matches the predicted    *
  17. *   move.  we then switch from pondering to thinking and search as normal;     *
  18. *   (2) a move is entered, but it does not match the predicted move.  we then  *
  19. *   abort the search, unmake the pondered move, and then restart with the move *
  20. *   entered.  (3) a command is entered.  if it is a simple command, it can be  *
  21. *   done without aborting the search or losing time.  if not, we abort the     *
  22. *   search, execute the command, and then attempt to restart pondering if the  *
  23. *   command didn't make that impossible.                                       *
  24. *                                                                              *
  25. ********************************************************************************
  26. */
  27. int Ponder(int wtm)
  28. {
  29.   int dummy=0, i, *n_ponder_moves, *mv;
  30.   int save_move_number;
  31.   TREE *tree=local[0];
  32. /*
  33.  ----------------------------------------------------------
  34. |                                                          |
  35. |   first, let's check to see if pondering is allowed, or  |
  36. |   if we should avoid pondering on this move since it is  |
  37. |   the first move of a game, or if the game is over, or   |
  38. |   "force" mode is active, or there is input in the queue |
  39. |   that needs to be read and processed.                   |
  40. |                                                          |
  41.  ----------------------------------------------------------
  42. */
  43.   if (!ponder || force || over || CheckInput()) return(0);
  44.   save_move_number=move_number;
  45. /*
  46.  ----------------------------------------------------------
  47. |                                                          |
  48. |   if we don't have a predicted move to ponder, try two   |
  49. |   sources:  (1) look up the current position in the      |
  50. |   transposition table and see if it has a suggested best |
  51. |   move;  (2) do a short tree search to calculate a move  |
  52. |   that we should ponder.                                 |
  53. |                                                          |
  54.  ----------------------------------------------------------
  55. */
  56.   strcpy(hint,"none");
  57.   if (ponder_move) {
  58.     if (!LegalMove(tree,1,wtm,ponder_move)) {
  59.       ponder_move=0;
  60.       Print(4095,"ERROR.  ponder_move is illegal (1).\n");
  61.       Print(4095,"ERROR.  PV path_length=%d\n",last_pv.path_length);
  62.       Print(4095,"ERROR.  move=%d  %x\n",last_pv,last_pv);
  63.     }
  64.   }
  65.   if (!ponder_move) {
  66.     (void) LookUp(tree,0,0,wtm,&dummy,&dummy,&dummy);
  67.     if (tree->hash_move[0]) ponder_move=tree->hash_move[0];
  68.     if (ponder_move) {
  69.       if (!LegalMove(tree,1,wtm,ponder_move)) {
  70.         ponder_move=0;
  71.         Print(4095,"ERROR.  ponder_move is illegal (2).\n");
  72.         Print(4095,"ERROR.  PV path_length=%d\n",last_pv.path_length);
  73.         Print(4095,"ERROR.  move=%d  %x\n",last_pv,last_pv);
  74.       }
  75.     }
  76.   }
  77.   if (!ponder_move) {
  78.     TimeSet(puzzle);
  79.     if (time_limit < 10) return(0);
  80.     puzzling=1;
  81.     tree->position[1]=tree->position[0];
  82.     Print(128,"              puzzling over a move to ponder.\n");
  83.     last_pv.path_length=0;
  84.     last_pv.path_iteration_depth=0;
  85.     for (i=0;i<MAXPLY;i++) {
  86.       tree->killer_move1[i]=0;
  87.       tree->killer_move2[i]=0;
  88.     }
  89.     (void) Iterate(wtm,puzzle,0);
  90.     for (i=0;i<MAXPLY;i++) {
  91.       tree->killer_move1[i]=0;
  92.       tree->killer_move2[i]=0;
  93.     }
  94.     puzzling=0;
  95.     if (tree->pv[0].path_length) ponder_move=tree->pv[0].path[1];
  96.     if (!ponder_move) return(0);
  97.     for (i=1;i<(int) tree->pv[0].path_length;i++) last_pv.path[i]=tree->pv[0].path[i+1];
  98.     last_pv.path_length=tree->pv[0].path_length-1;
  99.     last_pv.path_iteration_depth=0;
  100.     if (!LegalMove(tree,1,wtm,ponder_move)) {
  101.       ponder_move=0;
  102.       Print(4095,"ERROR.  ponder_move is illegal (3).\n");
  103.       Print(4095,"ERROR.  PV path_length=%d\n",last_pv.path_length);
  104.       return(0);
  105.     }
  106.   }
  107. /*
  108.  ----------------------------------------------------------
  109. |                                                          |
  110. |   display the move we are going to "ponder".             |
  111. |                                                          |
  112.  ----------------------------------------------------------
  113. */
  114.   if (wtm)
  115.     Print(128,"White(%d): %s [pondering]\n",
  116.           move_number,OutputMove(tree,ponder_move,0,wtm));
  117.   else
  118.     Print(128,"Black(%d): %s [pondering]\n",
  119.           move_number,OutputMove(tree,ponder_move,0,wtm));
  120.   sprintf(hint,"%s",OutputMove(tree,ponder_move,0,wtm));
  121.   if (post) printf("Hint: %s\n",hint);
  122. /*
  123.  ----------------------------------------------------------
  124. |                                                          |
  125. |   set the ponder move list and eliminate illegal moves.  |
  126. |                                                          |
  127.  ----------------------------------------------------------
  128. */
  129.   n_ponder_moves=GenerateCaptures(tree, 0, wtm, ponder_moves);
  130.   num_ponder_moves=GenerateNonCaptures(tree, 0, wtm, n_ponder_moves)-ponder_moves;
  131.   for (mv=ponder_moves;mv<ponder_moves+num_ponder_moves;mv++) {
  132.     MakeMove(tree,0, *mv, wtm);
  133.     if (Check(wtm)) {
  134.       UnMakeMove(tree,0, *mv, wtm);
  135.       *mv=0;
  136.       }
  137.     else UnMakeMove(tree,0, *mv, wtm);
  138.   }
  139. /*
  140.  ----------------------------------------------------------
  141. |                                                          |
  142. |   now, perform an iterated search, but with the special  |
  143. |   "pondering" flag set which changes the time controls   |
  144. |   since there is no need to stop searching until the     |
  145. |   opponent makes a move.                                 |
  146. |                                                          |
  147.  ----------------------------------------------------------
  148. */
  149.   MakeMove(tree,0,ponder_move,wtm);
  150.   if (Rule50Moves(1)==90 || Rule50Moves(1)==91) ClearHashTables();
  151.   last_opponent_move=ponder_move;
  152.   if (ChangeSide(wtm))
  153.     *tree->rephead_w++=HashKey;
  154.   else
  155.     *tree->rephead_b++=HashKey;
  156.   if (RepetitionDraw(tree,wtm)) Print(4095,"game is a draw by repetition\n");
  157.   if (whisper) strcpy(whisper_text,"n/a");
  158.   thinking=0;
  159.   pondering=1;
  160.   if (!wtm) move_number++;
  161.   (void) Iterate(ChangeSide(wtm),think,0);
  162.   move_number=save_move_number;
  163.   pondering=0;
  164.   thinking=0;
  165.   if (ChangeSide(wtm))
  166.     tree->rephead_w--;
  167.   else
  168.     tree->rephead_b--;
  169.   last_opponent_move=0;
  170.   UnMakeMove(tree,0,ponder_move,wtm);
  171. /*
  172.  ----------------------------------------------------------
  173. |                                                          |
  174. |   search completed. the possible return values are:      |
  175. |                                                          |
  176. |   (0) no pondering was done, period.                     |
  177. |                                                          |
  178. |   (1) pondering was done, opponent made the predicted    |
  179. |       move, and we searched until time ran out in a      |
  180. |       normal manner.                                     |
  181. |                                                          |
  182. |   (2) pondering was done, but the ponder search          |
  183. |       terminated due to either finding a mate, or the    |
  184. |       maximum search depth was reached.  the result of   |
  185. |       this ponder search are valid, but only if the      |
  186. |       opponent makes the correct (predicted) move.       |
  187. |                                                          |
  188. |   (3) pondering was done, but the opponent either made   |
  189. |       a different move, or entered a command that has to |
  190. |       interrupt the pondering search before the command  |
  191. |       (or move) can be processed.  this forces Main() to |
  192. |       avoid reading in a move/command since one has been |
  193. |       read into the command buffer already.              |
  194. |                                                          |
  195.  ----------------------------------------------------------
  196. */
  197.   if (made_predicted_move) return(1);
  198.   if (abort_search) return(3);
  199.   return(2);
  200. }
  201.