Subversion Repositories Games.Chess Giants

Rev

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

Rev Author Line No. Line
33 pmbaty 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
 */
108 pmbaty 16
char *OutputMove(TREE * RESTRICT tree, int ply, int wtm, int move) {
33 pmbaty 17
  static char text_move[10], new_text[10];
108 pmbaty 18
  unsigned *mvp;
19
  char *text = text_move;
33 pmbaty 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) {
108 pmbaty 30
    strcpy(text, "null");
33 pmbaty 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)
108 pmbaty 44
          strcpy(text_move, "O-O-O");
33 pmbaty 45
        else
108 pmbaty 46
          strcpy(text_move, "O-O");
33 pmbaty 47
      } else {
48
        if (To(move) == 58)
108 pmbaty 49
          strcpy(text_move, "O-O-O");
33 pmbaty 50
        else
108 pmbaty 51
          strcpy(text_move, "O-O");
33 pmbaty 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';
108 pmbaty 77
    strcpy(text_move, new_text);
33 pmbaty 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)) {
108 pmbaty 92
        strcpy(text_move, new_text + 2);
93
        if (InputMove(tree, ply, wtm, 1, 0, text_move))
33 pmbaty 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];
108 pmbaty 105
      strcpy(text_move + 1, new_text + 2);
106
      if (InputMove(tree, ply, wtm, 1, 0, text_move))
33 pmbaty 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
 */
108 pmbaty 117
      strcpy(text_move, new_text);
33 pmbaty 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];
108 pmbaty 131
      strcpy(text_move + 1, new_text + 3);
132
      if (InputMove(tree, ply, wtm, 1, 0, text_move))
33 pmbaty 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];
108 pmbaty 145
      strcpy(text_move + 2, new_text + 3);
146
      if (InputMove(tree, ply, wtm, 1, 0, text_move))
33 pmbaty 147
        break;
148
      text_move[0] = new_text[0];
108 pmbaty 149
      strcpy(text_move + 1, new_text + 2);
150
      if (InputMove(tree, ply, wtm, 1, 0, text_move))
33 pmbaty 151
        break;
152
/*
153
 ************************************************************
154
 *                                                          *
155
 *  Nothing worked, so we go with the fully-qualified move. *
156
 *                                                          *
157
 ************************************************************
158
 */
108 pmbaty 159
      strcpy(text_move, new_text);
33 pmbaty 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];
108 pmbaty 171
      strcpy(text_move + 1, new_text + 3);
172
      if (InputMove(tree, ply, wtm, 1, 0, text_move))
33 pmbaty 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];
108 pmbaty 184
      strcpy(text_move + 2, new_text + 3);
185
      if (InputMove(tree, ply, wtm, 1, 0, text_move))
33 pmbaty 186
        break;
187
      text_move[0] = new_text[0];
108 pmbaty 188
      strcpy(text_move + 1, new_text + 2);
189
      if (InputMove(tree, ply, wtm, 1, 0, text_move))
33 pmbaty 190
        break;
191
/*
192
 ************************************************************
193
 *                                                          *
194
 *  Nothing worked, return the fully-qualified move.        *
195
 *                                                          *
196
 ************************************************************
197
 */
108 pmbaty 198
      strcpy(text_move, new_text);
33 pmbaty 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];
108 pmbaty 213
    MakeMove(tree, MAXPLY, wtm, move);
33 pmbaty 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
    }
108 pmbaty 223
    UnmakeMove(tree, MAXPLY, wtm, move);
33 pmbaty 224
    *text = 0;
225
  }
226
  return text_move;
227
}