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