Subversion Repositories Games.Chess Giants

Rev

Rev 33 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include "chess.h"
  2. #include "data.h"
  3. /* last modified 02/24/14 */
  4. /*
  5.  *******************************************************************************
  6.  *                                                                             *
  7.  *   OutputMove() is responsible for converting the internal move format to a  *
  8.  *   string that can be displayed.  First, it simply converts the from/to      *
  9.  *   squares to fully-qualified algebraic (which includes O-O and O-O-O for    *
  10.  *   castling moves).  Next, we try several "shortcut" forms and call          *
  11.  *   input_move(silent=1) to let it silently check the move for uniqueness.    *
  12.  *   as soon as we get a non-ambiguous move, we return that text string.       *
  13.  *                                                                             *
  14.  *******************************************************************************
  15.  */
  16. char *OutputMove(TREE * RESTRICT tree, int ply, int wtm, int move) {
  17.   static char text_move[10], new_text[10];
  18.   unsigned *mvp;
  19.   char *text = text_move;
  20.   static const char piece_names[7] = { ' ', 'P', 'N', 'B', 'R', 'Q', 'K' };
  21. /*
  22.  ************************************************************
  23.  *                                                          *
  24.  *  Special case for null-move which will only be used in a *
  25.  *  search trace which dumps the entire tree.               *
  26.  *                                                          *
  27.  ************************************************************
  28.  */
  29.   if (move == 0) {
  30.     strcpy(text, "null");
  31.     return text;
  32.   }
  33.   do {
  34. /*
  35.  ************************************************************
  36.  *                                                          *
  37.  *  Check for castling moves first.                         *
  38.  *                                                          *
  39.  ************************************************************
  40.  */
  41.     if ((Piece(move) == king) && (Abs(From(move) - To(move)) == 2)) {
  42.       if (wtm) {
  43.         if (To(move) == 2)
  44.           strcpy(text_move, "O-O-O");
  45.         else
  46.           strcpy(text_move, "O-O");
  47.       } else {
  48.         if (To(move) == 58)
  49.           strcpy(text_move, "O-O-O");
  50.         else
  51.           strcpy(text_move, "O-O");
  52.       }
  53.       break;
  54.     }
  55. /*
  56.  ************************************************************
  57.  *                                                          *
  58.  *  Not a castling move.  Convert the move to a fully-      *
  59.  *  qualified algebraic move as a starting point.           *
  60.  *                                                          *
  61.  ************************************************************
  62.  */
  63.     text = new_text;
  64.     if ((int) Piece(move) > pawn)
  65.       *text++ = piece_names[Piece(move)];
  66.     *text++ = File(From(move)) + 'a';
  67.     *text++ = Rank(From(move)) + '1';
  68.     if (Captured(move))
  69.       *text++ = 'x';
  70.     *text++ = File(To(move)) + 'a';
  71.     *text++ = Rank(To(move)) + '1';
  72.     if (Promote(move)) {
  73.       *text++ = '=';
  74.       *text++ = piece_names[Promote(move)];
  75.     }
  76.     *text = '\0';
  77.     strcpy(text_move, new_text);
  78.     if (output_format > 0)
  79.       break;
  80. /*
  81.  ************************************************************
  82.  *                                                          *
  83.  *  Now we try some short forms.  If this is a pawn move    *
  84.  *  (first character is "P") and the move is not a capture  *
  85.  *  move, we can try just the destination square (Pe2e4     *
  86.  *  becomes e4).                                            *
  87.  *                                                          *
  88.  ************************************************************
  89.  */
  90.     if (Piece(move) == pawn) {
  91.       if (!Captured(move)) {
  92.         strcpy(text_move, new_text + 2);
  93.         if (InputMove(tree, ply, wtm, 1, 0, text_move))
  94.           break;
  95.       }
  96. /*
  97.  ************************************************************
  98.  *                                                          *
  99.  *  If this is a pawn and it is capturing something, try    *
  100.  *  the usual pawn capture format (Pe4xd5 becomes exd5).    *
  101.  *                                                          *
  102.  ************************************************************
  103.  */
  104.       text_move[0] = new_text[0];
  105.       strcpy(text_move + 1, new_text + 2);
  106.       if (InputMove(tree, ply, wtm, 1, 0, text_move))
  107.         break;
  108. /*
  109.  ************************************************************
  110.  *                                                          *
  111.  *  It is a pawn move and we can't find a shorter form, so  *
  112.  *  leave it as a fully-qualified move and go with it as    *
  113.  *  is.  (this will not normally happen).                   *
  114.  *                                                          *
  115.  ************************************************************
  116.  */
  117.       strcpy(text_move, new_text);
  118.       break;
  119.     }
  120. /*
  121.  ************************************************************
  122.  *                                                          *
  123.  *  If the move is a normal piece move, and does not        *
  124.  *  capture anything, we try the piece + destination format *
  125.  *  first (Ng1f3 becomes Nf3).                              *
  126.  *                                                          *
  127.  ************************************************************
  128.  */
  129.     if (!Captured(move)) {
  130.       text_move[0] = new_text[0];
  131.       strcpy(text_move + 1, new_text + 3);
  132.       if (InputMove(tree, ply, wtm, 1, 0, text_move))
  133.         break;
  134. /*
  135.  ************************************************************
  136.  *                                                          *
  137.  *  If that is ambiguous, we will try two alternatives:     *
  138.  *  (1) add in the origin file;  (2) add in the origin rank *
  139.  *  (Ng1f3 becomes Ngf3 or N1f3).                           *
  140.  *                                                          *
  141.  ************************************************************
  142.  */
  143.       text_move[0] = new_text[0];
  144.       text_move[1] = new_text[1];
  145.       strcpy(text_move + 2, new_text + 3);
  146.       if (InputMove(tree, ply, wtm, 1, 0, text_move))
  147.         break;
  148.       text_move[0] = new_text[0];
  149.       strcpy(text_move + 1, new_text + 2);
  150.       if (InputMove(tree, ply, wtm, 1, 0, text_move))
  151.         break;
  152. /*
  153.  ************************************************************
  154.  *                                                          *
  155.  *  Nothing worked, so we go with the fully-qualified move. *
  156.  *                                                          *
  157.  ************************************************************
  158.  */
  159.       strcpy(text_move, new_text);
  160.       break;
  161.     } else {
  162. /*
  163.  ************************************************************
  164.  *                                                          *
  165.  *  If this is a capture, we try the short form of a        *
  166.  *  capture move (Ng1xf3 becomes Nxf3)                      *
  167.  *                                                          *
  168.  ************************************************************
  169.  */
  170.       text_move[0] = new_text[0];
  171.       strcpy(text_move + 1, new_text + 3);
  172.       if (InputMove(tree, ply, wtm, 1, 0, text_move))
  173.         break;
  174. /*
  175.  ************************************************************
  176.  *                                                          *
  177.  *  If that didn't work, we try adding in the origin file   *
  178.  *  or the origin rank (Ng1xf3 becomes Ngxf3 or N1xf3).     *
  179.  *                                                          *
  180.  ************************************************************
  181.  */
  182.       text_move[0] = new_text[0];
  183.       text_move[1] = new_text[1];
  184.       strcpy(text_move + 2, new_text + 3);
  185.       if (InputMove(tree, ply, wtm, 1, 0, text_move))
  186.         break;
  187.       text_move[0] = new_text[0];
  188.       strcpy(text_move + 1, new_text + 2);
  189.       if (InputMove(tree, ply, wtm, 1, 0, text_move))
  190.         break;
  191. /*
  192.  ************************************************************
  193.  *                                                          *
  194.  *  Nothing worked, return the fully-qualified move.        *
  195.  *                                                          *
  196.  ************************************************************
  197.  */
  198.       strcpy(text_move, new_text);
  199.       break;
  200.     }
  201.   } while (0);
  202. /*
  203.  ************************************************************
  204.  *                                                          *
  205.  *  If the move is a check, or mate, append either "+" or   *
  206.  *  "#" as appropriate.                                     *
  207.  *                                                          *
  208.  ************************************************************
  209.  */
  210.   if (output_format == 0) {
  211.     text = text_move + strlen(text_move);
  212.     tree->status[MAXPLY] = tree->status[ply];
  213.     MakeMove(tree, MAXPLY, wtm, move);
  214.     if (Check(Flip(wtm))) {
  215.       mvp =
  216.           GenerateCheckEvasions(tree, MAXPLY + 1, Flip(wtm),
  217.           tree->move_list + 4800);
  218.       if (mvp == (tree->move_list + 4800))
  219.         *text++ = '#';
  220.       else
  221.         *text++ = '+';
  222.     }
  223.     UnmakeMove(tree, MAXPLY, wtm, move);
  224.     *text = 0;
  225.   }
  226.   return text_move;
  227. }
  228.