Subversion Repositories Games.Chess Giants

Rev

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