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

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "chess.h"
  4. #include "data.h"
  5.  
  6. /* last modified 03/11/98 */
  7. /*
  8. ********************************************************************************
  9. *                                                                              *
  10. *   NextEvasion() is used to select the next move from the current move list   *
  11. *   when the king is in check.  it tries the following things to get out of    *
  12. *   check:                                                                     *
  13. *                                                                              *
  14. *     1.  if one piece is attacking the king (aren't bitboard attack vectors   *
  15. *         wonderful?) try to capture the checking piece first.  we use the     *
  16. *         normal capture logic that tries winning or even captures first, and  *
  17. *         postpones losing captures until other safe moves have been tried.    *
  18. *                                                                              *
  19. *     2.  try moving the king to a safe square (one that is not already under  *
  20. *         attack, otherwise this would do nothing...)                          *
  21. *                                                                              *
  22. *     3.  If more than one piece is attacking the king, we can give up as we   *
  23. *         can't do anything but move the king, which we've already tried.      *
  24. *         therefore, assuming one attacker, if it's a knight, again we are     *
  25. *         done as we can't interpose anything.  if it's a bishop, rook, or     *
  26. *         queen, try interposing.  we simply have to find the attacker (easy)  *
  27. *         the attackee (the king's square, also easy) and use the precomputed  *
  28. *         mask to produce a bit vector of the squares between these two        *
  29. *         squares.  then pass this to GenerateCheckEvasions() as targets       *
  30. *         and we have all interposing moves.  of course, we still try them     *
  31. *         in "sane" order of safe followed by any.                             *
  32. *                                                                              *
  33. ********************************************************************************
  34. */
  35. int NextEvasion(TREE *tree, int ply, int wtm)
  36. {
  37.   register int *movep, *sortv;
  38.   register int done, temp;
  39.  
  40.   switch (tree->next_status[ply].phase) {
  41. /*
  42.  ----------------------------------------------------------
  43. |                                                          |
  44. |   first generate all legal moves by using the special    |
  45. |   GenerateCheckEvasions() function, so we can determine  |
  46. |   if this is a one-legal-reply-to-check position.        |
  47. |                                                          |
  48.  ----------------------------------------------------------
  49. */
  50.   case HASH_MOVE:
  51.     tree->last[ply]=GenerateCheckEvasions(tree, ply, wtm, tree->last[ply-1]);
  52. /*
  53.  ----------------------------------------------------------
  54. |                                                          |
  55. |   now try the transposition table move (which might be   |
  56. |   the principal variation move as we first move down the |
  57. |   tree).                                                 |
  58. |                                                          |
  59.  ----------------------------------------------------------
  60. */
  61.     if (tree->hash_move[ply]) {
  62.       tree->next_status[ply].phase=SORT_ALL_MOVES;
  63.       tree->current_move[ply]=tree->hash_move[ply];
  64.       if (ValidMove(tree,ply,wtm,tree->current_move[ply])) return(HASH_MOVE);
  65.       else Print(128,"bad move from hash table, ply=%d\n",ply);
  66.     }
  67. /*
  68.  ----------------------------------------------------------
  69. |                                                          |
  70. |   now sort the moves based on the expected gain or loss. |
  71. |   this is deferred until now to see if the hash move is  |
  72. |   good enough to produce a cutoff and avoid this work.   |
  73. |                                                          |
  74.  ----------------------------------------------------------
  75. */
  76.   case SORT_ALL_MOVES:
  77.     tree->next_status[ply].phase=REMAINING_MOVES;
  78.     if (tree->hash_move[ply]) {
  79.       for (movep=tree->last[ply-1],sortv=tree->sort_value;
  80.            movep<tree->last[ply];movep++,sortv++)
  81.         if (*movep == tree->hash_move[ply]) {
  82.           *sortv=-999999;
  83.           *movep=0;
  84.         }
  85.         else {
  86.           if (p_values[Piece(*movep)+7] < p_values[Captured(*movep)+7]) 
  87.             *sortv=p_values[Captured(*movep)+7]-p_values[Piece(*movep)+7];
  88.           else *sortv=Swap(tree,From(*movep),To(*movep),wtm);
  89.         }
  90.     }
  91.     else {
  92.       for (movep=tree->last[ply-1],sortv=tree->sort_value;
  93.            movep<tree->last[ply];movep++,sortv++)
  94.         if (p_values[Piece(*movep)+7] < p_values[Captured(*movep)+7]) 
  95.           *sortv=p_values[Captured(*movep)+7]-p_values[Piece(*movep)+7];
  96.         else *sortv=Swap(tree,From(*movep),To(*movep),wtm);
  97.     }
  98. /*
  99.  ----------------------------------------------------------
  100. |                                                          |
  101. |   don't disdain the lowly bubble sort here.  the list of |
  102. |   captures is always short, and experiments with other   |
  103. |   algorithms are always slightly slower.                 |
  104. |                                                          |
  105.  ----------------------------------------------------------
  106. */
  107.     do {
  108.       done=1;
  109.       for (movep=tree->last[ply-1],sortv=tree->sort_value;
  110.            movep<tree->last[ply]-1;movep++,sortv++)
  111.         if (*sortv < *(sortv+1)) {
  112.           temp=*sortv;
  113.           *sortv=*(sortv+1);
  114.           *(sortv+1)=temp;
  115.           temp=*movep;
  116.           *movep=*(movep+1);
  117.           *(movep+1)=temp;
  118.           done=0;
  119.         }
  120.     } while(!done);
  121.     tree->next_status[ply].last=tree->last[ply-1];
  122. /*
  123.  ----------------------------------------------------------
  124. |                                                          |
  125. |   now try the rest of the set of moves.                  |
  126. |                                                          |
  127.  ----------------------------------------------------------
  128. */
  129.   case REMAINING_MOVES:
  130.     for (;tree->next_status[ply].last<tree->last[ply];
  131.            tree->next_status[ply].last++)
  132.       if ((*tree->next_status[ply].last)) {
  133.         tree->current_move[ply]=*tree->next_status[ply].last++;
  134.         return(REMAINING_MOVES);
  135.       }  
  136.     return(NONE);
  137.  
  138.   default:
  139.     printf("oops!  next_status.phase is bad! [evasion %d]\n",
  140.            tree->next_status[ply].phase);
  141.     return(NONE);
  142.   }
  143. }
  144.