Subversion Repositories Games.Chess Giants

Rev

Go to most recent revision | Details | 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
 */
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
}