89 board[move->torow][fileidx('d')] = color|ROOK; |
89 board[move->torow][fileidx('d')] = color|ROOK; |
90 } |
90 } |
91 } |
91 } |
92 } |
92 } |
93 |
93 |
94 static _Bool validate_move(Board board, uint8_t mycolor, Move *move) { |
94 static _Bool validate_move(Board board, Move *move) { |
95 _Bool result; |
95 _Bool result; |
96 |
96 |
97 /* does piece exist */ |
97 /* does piece exist */ |
98 result = board[move->fromrow][move->fromfile] == move->piece; |
98 result = board[move->fromrow][move->fromfile] == move->piece; |
99 |
99 |
127 } |
127 } |
128 |
128 |
129 /* is piece pinned */ |
129 /* is piece pinned */ |
130 // TODO: make it so |
130 // TODO: make it so |
131 |
131 |
|
132 /* correct check and checkmate flags */ |
|
133 // TODO: make it so |
|
134 |
132 return result; |
135 return result; |
133 } |
136 } |
134 |
137 |
135 static _Bool eval_move(Board board, uint8_t mycolor, char *mstr, Move *move) { |
138 static _Bool eval_move(Board board, uint8_t mycolor, char *mstr, Move *move) { |
136 memset(move, 0, sizeof(Move)); |
139 memset(move, 0, sizeof(Move)); |
137 |
140 |
138 size_t len = strlen(mstr); |
141 size_t len = strlen(mstr); |
139 |
142 |
140 /* remove check */ |
143 /* evaluate check/checkmate flags */ |
141 if (mstr[len-1] == '+') { |
144 if (mstr[len-1] == '+') { |
142 len--; mstr[len] = '\0'; |
145 len--; mstr[len] = '\0'; |
143 move->check = TRUE; |
146 move->check = TRUE; |
|
147 } else if (mstr[len-1] == '#') { |
|
148 len--; mstr[len] = '\0'; |
|
149 move->checkmate = TRUE; |
144 } |
150 } |
145 |
151 |
146 if (len == 2) { |
152 if (len == 2) { |
147 /* pawn move (e.g. "e4") */ |
153 /* pawn move (e.g. "e4") */ |
148 if (isfile(mstr[0]) && isrow(mstr[1])) { |
154 if (isfile(mstr[0]) && isrow(mstr[1])) { |
192 |
198 |
193 static int sendmove(Board board, uint8_t mycolor, int opponent) { |
199 static int sendmove(Board board, uint8_t mycolor, int opponent) { |
194 const size_t buflen = 8; |
200 const size_t buflen = 8; |
195 char movestr[buflen]; |
201 char movestr[buflen]; |
196 _Bool remisrejected = FALSE; |
202 _Bool remisrejected = FALSE; |
|
203 uint8_t code; |
197 |
204 |
198 while (1) { |
205 while (1) { |
199 move(boardy+3, 0); |
206 move(boardy+3, 0); |
200 if (remisrejected) { |
207 if (remisrejected) { |
201 printw( |
208 printw( |
234 } else { |
241 } else { |
235 Move move; |
242 Move move; |
236 if (eval_move(board, mycolor, movestr, &move)) { |
243 if (eval_move(board, mycolor, movestr, &move)) { |
237 net_send_code(opponent, NETCODE_MOVE); |
244 net_send_code(opponent, NETCODE_MOVE); |
238 net_send_data(opponent, &move, sizeof(Move)); |
245 net_send_data(opponent, &move, sizeof(Move)); |
239 if (net_recieve_code(opponent) == NETCODE_ACCEPT) { |
246 code = net_recieve_code(opponent); |
240 apply_move(board, &move); |
247 move.check = code == NETCODE_CHECK; |
241 return 0; |
248 move.checkmate = code == NETCODE_CHECKMATE; |
242 } else { |
249 // TODO: record move |
|
250 if (code == NETCODE_DECLINE) { |
243 printw("Invalid move."); |
251 printw("Invalid move."); |
244 clrtoeol(); |
252 clrtoeol(); |
|
253 } else { |
|
254 apply_move(board, &move); |
|
255 if (move.checkmate) { |
|
256 printw("Checkmate!"); |
|
257 return 1; |
|
258 } |
245 } |
259 } |
246 } else { |
260 } else { |
247 printw("Can't interpret move - please use algebraic notation."); |
261 printw("Can't interpret move - please use algebraic notation."); |
248 } |
262 } |
249 } |
263 } |
250 } |
264 } |
251 } |
265 } |
252 |
266 |
253 static int recvmove(Board board, uint8_t mycolor, int opponent) { |
267 static int recvmove(Board board, int opponent) { |
254 |
268 |
255 while (1) { |
269 while (1) { |
256 move(boardy+3, 0); |
270 move(boardy+3, 0); |
257 printw("Awaiting opponent move..."); |
271 printw("Awaiting opponent move..."); |
258 clrtoeol(); |
272 clrtoeol(); |
278 net_send_code(opponent, NETCODE_DECLINE); |
292 net_send_code(opponent, NETCODE_DECLINE); |
279 } |
293 } |
280 break; |
294 break; |
281 case NETCODE_MOVE: |
295 case NETCODE_MOVE: |
282 net_recieve_data(opponent, &move, sizeof(Move)); |
296 net_recieve_data(opponent, &move, sizeof(Move)); |
283 if (validate_move(board, mycolor, &move)) { |
297 if (validate_move(board, &move)) { |
284 apply_move(board, &move); |
298 apply_move(board, &move); |
285 net_send_code(opponent, NETCODE_ACCEPT); |
299 // TODO: record move |
|
300 if (move.check) { |
|
301 net_send_code(opponent, NETCODE_CHECK); |
|
302 } else if (move.checkmate) { |
|
303 net_send_code(opponent, NETCODE_CHECKMATE); |
|
304 } else { |
|
305 net_send_code(opponent, NETCODE_ACCEPT); |
|
306 } |
286 return 0; |
307 return 0; |
287 } else { |
308 } else { |
288 net_send_code(opponent, NETCODE_DECLINE); |
309 net_send_code(opponent, NETCODE_DECLINE); |
289 } |
310 } |
290 } |
311 } |
313 clear(); |
334 clear(); |
314 draw_board(board, mycolor); |
335 draw_board(board, mycolor); |
315 if (myturn) { |
336 if (myturn) { |
316 running = !sendmove(board, mycolor, opponent); |
337 running = !sendmove(board, mycolor, opponent); |
317 } else { |
338 } else { |
318 running = !recvmove(board, mycolor, opponent); |
339 running = !recvmove(board, opponent); |
319 flushinp(); // flush any input the user hacked in while waiting |
340 flushinp(); // flush any input the user hacked in while waiting |
320 } |
341 } |
321 myturn ^= 1; |
342 myturn ^= TRUE; |
322 } while (running); |
343 } while (running); |
323 |
344 |
324 mvaddstr(getmaxy(tchess_window)-1, 0, |
345 mvaddstr(getmaxy(tchess_window)-1, 0, |
325 "Game has ended. Press any key to leave..."); |
346 "Game has ended. Press any key to leave..."); |
326 getch(); |
347 getch(); |