This is the doxygen documentation for gtkboard.
.00001 /* This file is a part of gtkboard, a board games system. 00002 Copyright (C) 2003, Arvind Narayanan <arvindn@users.sourceforge.net> 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU General Public License as published by 00006 the Free Software Foundation; either version 2 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU General Public License for more details. 00013 00014 You should have received a copy of the GNU General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA 00017 00018 */ 00019 #include <stdio.h> 00020 #include <string.h> 00021 #include <stdlib.h> 00022 00023 #include "game.h" 00024 #include "../pixmaps/chess.xpm" 00025 00026 00027 #define ANTICHESS_CELL_SIZE 54 00028 #define ANTICHESS_NUM_PIECES 12 00029 00030 #define ANTICHESS_BOARD_WID 8 00031 #define ANTICHESS_BOARD_HEIT 8 00032 00033 #define ANTICHESS_WK 1 00034 #define ANTICHESS_WQ 2 00035 #define ANTICHESS_WR 3 00036 #define ANTICHESS_WB 4 00037 #define ANTICHESS_WN 5 00038 #define ANTICHESS_WP 6 00039 #define ANTICHESS_BK 7 00040 #define ANTICHESS_BQ 8 00041 #define ANTICHESS_BR 9 00042 #define ANTICHESS_BB 10 00043 #define ANTICHESS_BN 11 00044 #define ANTICHESS_BP 12 00045 00046 #define ANTICHESS_ISWHITE(x) (x >= 1 && x <= 6) 00047 #define ANTICHESS_ISBLACK(x) (x >= 7 && x <= 12) 00048 00049 #ifndef abs 00050 #define abs(x) ((x) < 0 ? -(x) : (x)) 00051 #endif 00052 00053 static char antichess_colors[] = 00054 {200, 200, 130, 00055 0, 140, 0}; 00056 char antichess_highlight_colors[9] = {0xff, 0, 0}; 00057 00058 static int antichess_init_pos[] = 00059 { 00060 9 , 11, 10, 8 , 7 , 10, 11, 9 , 00061 12, 12, 12, 12, 12, 12, 12, 12 , 00062 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 00063 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 00064 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 00065 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 00066 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 00067 3 , 5 , 4 , 2 , 1 , 4 , 5 , 3 , 00068 }; 00069 static int antichess_max_moves = 200; 00070 00071 static char ** antichess_pixmaps[] = 00072 00073 { 00074 chess_wk_54_xpm, 00075 chess_wq_54_xpm, 00076 chess_wr_54_xpm, 00077 chess_wb_54_xpm, 00078 chess_wn_54_xpm, 00079 chess_wp_54_xpm, 00080 chess_bk_54_xpm, 00081 chess_bq_54_xpm, 00082 chess_br_54_xpm, 00083 chess_bb_54_xpm, 00084 chess_bn_54_xpm, 00085 chess_bp_54_xpm, 00086 }; 00087 00088 00089 00090 void antichess_init (); 00091 int antichess_getmove (Pos *, int, int, GtkboardEventType, Player, byte **, int **); 00092 ResultType antichess_who_won (Pos *, Player, char **); 00093 byte *antichess_movegen (Pos *); 00094 ResultType antichess_eval (Pos *, Player, float *); 00095 ResultType antichess_eval_incr (Pos *, Player, byte *, float *); 00096 00097 Game Antichess = 00098 { ANTICHESS_CELL_SIZE, ANTICHESS_BOARD_WID, ANTICHESS_BOARD_HEIT, 00099 ANTICHESS_NUM_PIECES, 00100 antichess_colors, antichess_init_pos, antichess_pixmaps, "Antichess", 00101 antichess_init}; 00102 00103 Game * plugin_game = &Antichess; 00104 00105 void antichess_init () 00106 { 00107 game_getmove = antichess_getmove; 00108 game_who_won = antichess_who_won; 00109 game_movegen = antichess_movegen; 00110 game_eval = antichess_eval; 00111 // game_eval_incr = antichess_eval_incr; 00112 game_file_label = FILERANK_LABEL_TYPE_ALPHA; 00113 game_rank_label = FILERANK_LABEL_TYPE_NUM | FILERANK_LABEL_DESC; 00114 game_highlight_colors = antichess_highlight_colors; 00115 game_allow_flip = TRUE; 00116 game_doc_about = 00117 "Antichess\n" 00118 "Two player game\n" 00119 "Status: Fully implemented\n" 00120 "URL: "GAME_DEFAULT_URL("antichess"); 00121 game_doc_rules = 00122 "Antichess rules\n" 00123 "\n" 00124 "The objective of the game is to force your opponent to capture all your pieces or to stalemate you. What makes this possible is that if you can capture, then you MUST.\n" 00125 "\n" 00126 "The pieces move as in chess. However:\n" 00127 " - The king is NOT a special piece. No check(mate), no castling. The king can be captured like any other piece.\n" 00128 " - No taking en passant.\n" 00129 " - Pawn promotion is as in chess.\n" 00130 "\n" 00131 "A couple of notes on the gtkboard implementation of chess and antichess:\n" 00132 " - Drag and drop doesn't work (yet). To make the move 1. e4, you have to click on e2 and then on e4.\n" 00133 " - To promote, after clicking on the pawn and then on the promotion square, you have to click on a third square which indicates which piece you want to promote to. This square should be any one of the squares of the file of that piece. (Thus, to queen, click anywhere on the 'd' file, etc.)"; 00134 } 00135 00136 static int isfreeline (byte *pos, int oldx, int oldy, int newx, int newy) 00137 { 00138 int x = oldx, y = oldy, dx, dy, diffx = newx - oldx, diffy = newy - oldy; 00139 if (abs (diffx) != abs(diffy) && diffx != 0 && diffy != 0) 00140 return 0; 00141 dx = (diffx ? (diffx / abs (diffx)) : 0); 00142 dy = (diffy ? (diffy / abs (diffy)) : 0); 00143 for (x+=dx, y+=dy; x != newx || y != newy; x+=dx, y+=dy) 00144 if (pos [y * board_wid + x] != 0) 00145 return 0; 00146 return 1; 00147 } 00148 00149 static int islegal (Pos *pos, int oldx, int oldy, int x, int y, int player) 00150 { 00151 int piece = pos->board [oldy * board_wid + oldx]; 00152 byte *board = pos->board; 00153 switch (piece) 00154 { 00155 case ANTICHESS_WK: 00156 case ANTICHESS_BK: 00157 { 00158 int diffx = abs (x - oldx), diffy = abs (y - oldy); 00159 return diffx <= 1 && diffy <= 1; 00160 } 00161 case ANTICHESS_WQ: 00162 case ANTICHESS_BQ: 00163 return isfreeline (board, oldx, oldy, x, y); 00164 case ANTICHESS_WR: 00165 case ANTICHESS_BR: 00166 if (!isfreeline (board, oldx, oldy, x, y)) 00167 return 0; 00168 if (oldx == x || oldy == y) 00169 return 1; 00170 return 0; 00171 case ANTICHESS_WB: 00172 case ANTICHESS_BB: 00173 if (!isfreeline (board, oldx, oldy, x, y)) 00174 return 0; 00175 if (oldx == x || oldy == y) 00176 return 0; 00177 return 1; 00178 case ANTICHESS_WN: 00179 case ANTICHESS_BN: 00180 { 00181 int diffx = abs (x - oldx), diffy = abs (y - oldy); 00182 if (diffx == 2 && diffy == 1) 00183 return 1; 00184 if (diffx == 1 && diffy == 2) 00185 return 1; 00186 return 0; 00187 } 00188 case ANTICHESS_WP: 00189 if (board [y * board_wid + x] == 0) 00190 return (x == oldx && (y == oldy + 1 || 00191 (y == 3 && oldy == 1 && board [(2*board_wid + x)] == 0))); 00192 return y == oldy + 1 && (x == oldx + 1 || x == oldx - 1) ; 00193 case ANTICHESS_BP: 00194 if (board [y * board_wid + x] == 0) 00195 return (x == oldx && (y == oldy - 1 || 00196 (y == 4 && oldy == 6 && board [5*board_wid + x] == 0))); 00197 return y == oldy - 1 && (x == oldx + 1 || x == oldx - 1) ; 00198 default: 00199 return 1; 00200 } 00201 } 00202 00203 static int can_capture (Pos *pos, int player) 00204 { 00205 int x1, y1, x2, y2, val; 00206 for (x1 = 0; x1 < board_wid; x1++) 00207 for (y1 = 0; y1 < board_heit; y1++) 00208 { 00209 val = pos->board [y1 * board_wid + x1]; 00210 if (player == WHITE && !ANTICHESS_ISWHITE (val)) continue; 00211 if (player == BLACK && !ANTICHESS_ISBLACK (val)) continue; 00212 for (x2 = 0; x2 < board_wid; x2++) 00213 for (y2 = 0; y2 < board_heit; y2++) 00214 { 00215 val = pos->board [y2 * board_wid + x2]; 00216 if (player == WHITE && !ANTICHESS_ISBLACK (val)) continue; 00217 if (player == BLACK && !ANTICHESS_ISWHITE (val)) continue; 00218 if (islegal (pos, x1, y1, x2, y2, player)) return 1; 00219 } 00220 } 00221 return 0; 00222 } 00223 00224 static int oppcolor (byte *pos, int oldx, int oldy, int x, int y) 00225 /* True if one square is W and the other is B */ 00226 { 00227 int oldv = pos [oldy * board_wid + oldx], v = pos [y * board_wid + x]; 00228 if (ANTICHESS_ISWHITE (oldv) && ANTICHESS_ISBLACK (v)) return 1; 00229 if (ANTICHESS_ISBLACK (oldv) && ANTICHESS_ISWHITE (v)) return 1; 00230 return 0; 00231 } 00232 00233 static int oldx = -1, oldy = -1, oldval = -1; 00234 static int prom = 0, prom_x, prom_oldx; 00235 00236 void antichess_free () 00237 { 00238 oldx = -1, oldy = -1, prom = 0; 00239 } 00240 00241 int antichess_getmove (Pos *pos, int x, int y, 00242 GtkboardEventType type, Player player, byte ** movep, int ** rmovep) 00243 /* Translate mouse clicks into move */ 00244 { 00245 static byte move [7]; 00246 static int rmove [7]; 00247 int *rp = rmove; 00248 int val; 00249 if (type != GTKBOARD_BUTTON_RELEASE) 00250 return 0; 00251 00252 val = pos->board [y * board_wid + x]; 00253 00254 if (oldx >= 0 && x == oldx && y == oldy) 00255 { 00256 *rp++ = oldx; *rp++ = oldy; *rp++ = RENDER_NONE; *rp++ = -1; *rmovep = rmove; 00257 oldx = -1; oldy = -1; return 0; 00258 } 00259 00260 // if you can capture you must capture 00261 if (oldx >= 0 && can_capture (pos, player) && 00262 !((ANTICHESS_ISWHITE (val) && ANTICHESS_ISBLACK (oldval)) 00263 || (ANTICHESS_ISBLACK (val) && ANTICHESS_ISWHITE (oldval)))) 00264 { 00265 *rp++ = oldx; *rp++ = oldy; *rp++ = RENDER_NONE; *rp++ = -1; *rmovep = rmove; 00266 oldx = oldy = -1; 00267 return -1; 00268 } 00269 00270 /* pawn promotion */ 00271 if (prom) 00272 { 00273 int new_p = -1; 00274 prom = 0; 00275 switch(x) 00276 { 00277 case 0: case 7: 00278 new_p = (player == WHITE ? ANTICHESS_WR : ANTICHESS_BR); break; 00279 case 1: case 6: 00280 new_p = (player == WHITE ? ANTICHESS_WN : ANTICHESS_BN); break; 00281 case 2: case 5: 00282 new_p = (player == WHITE ? ANTICHESS_WB : ANTICHESS_BB); break; 00283 case 3: case 4: 00284 new_p = (player == WHITE ? ANTICHESS_WQ : ANTICHESS_BQ); break; 00285 } 00286 move[0] = prom_oldx; 00287 move[1] = (player == WHITE ? 6 : 1); 00288 move[2] = 0; 00289 move[3] = prom_x; 00290 move[4] = (player == WHITE ? 7 : 0); 00291 move[5] = new_p; 00292 move[6] = -1; 00293 00294 if (movep) 00295 *movep = move; 00296 return 1; 00297 } 00298 if (oldx == -1) 00299 { 00300 if (val == 0) return -1; 00301 if (player == WHITE && !ANTICHESS_ISWHITE (val)) 00302 return -1; 00303 if (player == BLACK && !ANTICHESS_ISBLACK (val)) 00304 return -1; 00305 oldx = x; oldy = y, oldval = val; 00306 *rp++ = oldx; *rp++ = oldy; *rp++ = RENDER_HIGHLIGHT1; *rp++ = -1; *rmovep = rmove; 00307 return 0; 00308 } 00309 if (player == WHITE && ANTICHESS_ISWHITE (val)) 00310 { 00311 *rp++ = oldx; *rp++ = oldy; *rp++ = RENDER_NONE; *rp++ = -1; *rmovep = rmove; 00312 oldx = -1; oldy = -1; 00313 return -1; 00314 } 00315 if (player == BLACK && ANTICHESS_ISBLACK (val)) 00316 { 00317 *rp++ = oldx; *rp++ = oldy; *rp++ = RENDER_NONE; *rp++ = -1; *rmovep = rmove; 00318 oldx = -1; oldy = -1; 00319 return -1; 00320 } 00321 00322 if (!islegal (pos, oldx, oldy, x, y, player)) 00323 // FIXME 00324 //|| (can_capture (pos, player) && !oppcolor (pos, oldx, oldy, x, y))) 00325 { 00326 *rp++ = oldx; *rp++ = oldy; *rp++ = RENDER_NONE; *rp++ = -1; *rmovep = rmove; 00327 oldx = -1; oldy = -1; 00328 return -1; 00329 } 00330 00331 /* pawn promotion */ 00332 if ((oldval == ANTICHESS_WP || oldval == ANTICHESS_BP) && 00333 (y == 0 || y == board_heit - 1)) 00334 { 00335 prom = 1; 00336 prom_oldx = oldx; 00337 prom_x = x; 00338 *rp++ = oldx; *rp++ = oldy; *rp++ = RENDER_NONE; *rp++ = -1; *rmovep = rmove; 00339 oldx = oldy = -1; 00340 return 0; 00341 } 00342 00343 move[0] = oldx; move[1] = oldy; move[2] = 0; 00344 move[3] = x; move[4] = y; move[5] = pos->board [oldy * board_wid + oldx]; 00345 move[6] = -1; 00346 00347 *rp++ = oldx; *rp++ = oldy; *rp++ = RENDER_NONE; *rp++ = -1; *rmovep = rmove; 00348 oldx = -1; oldy = -1; 00349 00350 if (movep) 00351 *movep = move; 00352 return 1; 00353 /*if (player == WHITE && ANTICHESS_ISWHITE (val)) 00354 return 0;*/ 00355 } 00356 00357 static int hasmove (Pos *pos, int player) 00358 { 00359 int x1, y1, x2, y2, val; 00360 for (x1 = 0; x1 < board_wid; x1++) 00361 for (y1 = 0; y1 < board_heit; y1++) 00362 { 00363 val = pos->board [y1 * board_wid + x1]; 00364 if (player == WHITE && !ANTICHESS_ISWHITE (val)) continue; 00365 if (player == BLACK && !ANTICHESS_ISBLACK (val)) continue; 00366 for (x2 = 0; x2 < board_wid; x2++) 00367 for (y2 = 0; y2 < board_heit; y2++) 00368 if (islegal (pos, x1, y1, x2, y2, player)) return 1; 00369 } 00370 return 0; 00371 } 00372 00373 ResultType antichess_who_won (Pos *pos, Player player, char **commp) 00374 { 00375 static char comment[32]; 00376 char *who_str [3] = { "White won", "Black won", "Draw" }; 00377 *commp = NULL; 00378 if (hasmove (pos, player)) //return RESULT_NOTYET; 00379 { 00380 if (pos->num_moves > antichess_max_moves) 00381 { 00382 fprintf (stderr, "max moves reached\n"); 00383 snprintf (comment, 32, "%s", who_str[2]); 00384 *commp = comment; 00385 return RESULT_TIE; 00386 } 00387 return RESULT_NOTYET; 00388 } 00389 *commp = comment; 00390 if (hasmove (pos, player == WHITE ? BLACK : WHITE)) 00391 { 00392 strncpy (comment, who_str[player == WHITE ? 0 : 1], 31); 00393 return player == WHITE ? RESULT_WHITE : RESULT_BLACK; 00394 } 00395 else 00396 { 00397 strncpy (comment, who_str[2], 31); 00398 return RESULT_TIE; 00399 } 00400 } 00401 00402 int antichess_movegen_square (byte *pos, byte **movp, int player, 00403 int oldx, int oldy, int x, int y) 00404 { 00405 int val; 00406 if (!ISINBOARD(x, y)) return 0; 00407 val = pos [y * board_heit + x]; 00408 if ((player == WHITE && ANTICHESS_ISWHITE (val)) 00409 || (player == BLACK && ANTICHESS_ISBLACK (val))) 00410 return 0; 00411 *(*movp)++ = oldx; 00412 *(*movp)++ = oldy; 00413 *(*movp)++ = 0; 00414 *(*movp)++ = x; 00415 *(*movp)++ = y; 00416 *(*movp)++ = pos [oldy * board_heit + oldx]; 00417 *(*movp)++ = -1; 00418 return 1; 00419 } 00420 00421 int antichess_movegen_line (byte *pos, byte **movp, int player, 00422 int x, int y, int incx, int incy) 00423 { 00424 int oldx = x, oldy = y; 00425 int capture = 0, val; 00426 do 00427 { 00428 if (capture) return 1; 00429 x += incx; 00430 y += incy; 00431 val = pos [y * board_heit + x]; 00432 if (ISINBOARD (x, y) && oppcolor (pos, oldx, oldy, x, y)) 00433 capture = 1; 00434 } while (antichess_movegen_square (pos, movp, player, oldx, oldy, x, y)); 00435 return 0; 00436 } 00437 00438 static void antichess_movegen_promote (byte *board, byte **movp, int player, 00439 int oldx, int oldy, int x, int y) 00440 { 00441 int i, j; 00442 int promote_pieces[2][4] = { 00443 {ANTICHESS_WQ, ANTICHESS_WR, ANTICHESS_WB, ANTICHESS_WN}, 00444 {ANTICHESS_BQ, ANTICHESS_BR, ANTICHESS_BB, ANTICHESS_BN} 00445 }; 00446 i = (player == WHITE ? 0 : 1); 00447 for(j=0; j<4; j++) 00448 { 00449 *(*movp)++ = oldx; 00450 *(*movp)++ = oldy; 00451 *(*movp)++ = 0; 00452 *(*movp)++ = x; 00453 *(*movp)++ = y; 00454 *(*movp)++ = promote_pieces[i][j]; 00455 *(*movp)++ = -1; 00456 } 00457 } 00458 00459 byte *antichess_movegen (Pos *pos) 00460 { 00461 byte realbuf[4096]; 00462 byte *realp = realbuf; 00463 byte movbuf[4096], *movp = movbuf; 00464 byte *movlist; 00465 int i, j, k, x, y, capture = 0; 00466 int incxr[] = {0, 0, 1, -1}; 00467 int incyr[] = {1, -1, 0, 0}; 00468 int incxb[] = {1, 1, -1, -1}; 00469 int incyb[] = {1, -1, 1, -1}; 00470 int incxn[] = {2, 2, -2, -2, 1, 1, -1, -1}; 00471 int incyn[] = {1, -1, 1, -1, 2, -2, 2, -2}; 00472 byte *board = pos->board; 00473 Player player = pos->player; 00474 for (i=0; i<board_wid; i++) 00475 for (j=0; j<board_heit; j++) 00476 { 00477 int val = board[j * board_heit + i]; 00478 if ((player == WHITE && ANTICHESS_ISWHITE (val)) 00479 || (player == BLACK && ANTICHESS_ISBLACK (val))) 00480 { 00481 switch (val) 00482 { 00483 case ANTICHESS_WP: 00484 if (ISINBOARD (i, j+1) && board [(j+1) * board_heit + i] == 0) 00485 { 00486 if (j == board_heit - 2) 00487 antichess_movegen_promote(board, &movp, player, 00488 i, j, i, j+1); 00489 else 00490 antichess_movegen_square (board, &movp, player, 00491 i, j, i, j+1); 00492 } 00493 if (ISINBOARD (i+1, j+1) && 00494 ANTICHESS_ISBLACK (board [(j+1) * board_heit + i+1])) 00495 { 00496 if (j == board_heit - 2) 00497 antichess_movegen_promote (board, &movp, player, 00498 i, j, i+1, j+1); 00499 else 00500 antichess_movegen_square (board, &movp, player, 00501 i, j, i+1, j+1); 00502 capture ++; 00503 } 00504 if (ISINBOARD (i-1, j+1) && 00505 ANTICHESS_ISBLACK (board [(j+1) * board_heit + i-1])) 00506 { 00507 if (j == board_heit - 2) 00508 antichess_movegen_promote (board, &movp, player, 00509 i, j, i-1, j+1); 00510 else 00511 antichess_movegen_square (board, &movp, player, 00512 i, j, i-1, j+1); 00513 capture ++; 00514 } 00515 if (j == 1 && board [2 * board_heit + i] == 0 00516 && board [3 * board_heit + i] == 0) 00517 antichess_movegen_square (board, &movp, player, 00518 i, j, i, j+2); 00519 break; 00520 case ANTICHESS_BP: 00521 if (ISINBOARD (i, j-1) && board [(j-1) * board_heit + i] == 0) 00522 { 00523 if (j == 1) 00524 antichess_movegen_promote (board, &movp, player, 00525 i, j, i, j-1); 00526 else 00527 antichess_movegen_square (board, &movp, player, 00528 i, j, i, j-1); 00529 } 00530 if (ISINBOARD (i+1, j-1) && 00531 ANTICHESS_ISWHITE (board [(j-1) * board_heit + i+1])) 00532 { 00533 if (j == 1) 00534 antichess_movegen_promote (board, &movp, player, 00535 i, j, i+1, j-1); 00536 else 00537 antichess_movegen_square (board, &movp, player, 00538 i, j, i+1, j-1); 00539 capture ++; 00540 } 00541 if (ISINBOARD (i-1, j-1) && 00542 ANTICHESS_ISWHITE (board [(j-1) * board_heit + i-1])) 00543 { 00544 if (j == 1) 00545 antichess_movegen_promote (board, &movp, player, 00546 i, j, i-1, j-1); 00547 else 00548 antichess_movegen_square (board, &movp, player, 00549 i, j, i-1, j-1); 00550 capture ++; 00551 } 00552 if (j == 6 && board [5 * board_heit + i] == 0 00553 && board [4 * board_heit + i] == 0) 00554 antichess_movegen_square (board, &movp, player, 00555 i, j, i, j-2); 00556 break; 00557 case ANTICHESS_WK: 00558 case ANTICHESS_BK: 00559 for (k=0; k<4; k++) 00560 { 00561 antichess_movegen_square(board, &movp, player, 00562 i, j, i + incxr[k], j + incyr[k]); 00563 if (ISINBOARD(i + incxr[k], j + incyr[k]) 00564 && oppcolor (board, i, j, i+incxr[k], j+incyr[k])) 00565 capture ++; 00566 } 00567 for (k=0; k<4; k++) 00568 { 00569 antichess_movegen_square(board, &movp, player, 00570 i, j, i + incxb[k], j + incyb[k]); 00571 if (ISINBOARD(i + incxb[k], j + incyb[k]) 00572 && oppcolor (board, i, j, i+incxb[k], j+incyb[k])) 00573 capture ++; 00574 } 00575 break; 00576 case ANTICHESS_WB: 00577 case ANTICHESS_BB: 00578 for (k=0; k<4; k++) 00579 capture += antichess_movegen_line (board, &movp, player, 00580 i, j, incxb[k], incyb[k]); 00581 break; 00582 case ANTICHESS_WR: 00583 case ANTICHESS_BR: 00584 for (k=0; k<4; k++) 00585 capture += antichess_movegen_line (board, &movp, player, 00586 i, j, incxr[k], incyr[k]); 00587 break; 00588 case ANTICHESS_WQ: 00589 case ANTICHESS_BQ: 00590 for (k=0; k<4; k++) 00591 capture += antichess_movegen_line (board, &movp, player, 00592 i, j, incxb[k], incyb[k]); 00593 for (k=0; k<4; k++) 00594 capture += antichess_movegen_line (board, &movp, player, 00595 i, j, incxr[k], incyr[k]); 00596 break; 00597 case ANTICHESS_WN: 00598 case ANTICHESS_BN: 00599 for (k=0; k<8; k++) 00600 { 00601 antichess_movegen_square(board, &movp, player, 00602 i, j, i + incxn[k], j + incyn[k]); 00603 if (ISINBOARD(i + incxn[k], j + incyn[k]) 00604 && oppcolor (board, i, j, i+incxn[k], j+incyn[k])) 00605 capture ++; 00606 } 00607 break; 00608 } 00609 } 00610 } 00611 *movp++ = -2; 00612 00613 /* if there is a capture eliminate all other moves */ 00614 if (!capture) 00615 { 00616 movlist = (byte *) malloc (movp - movbuf); 00617 memcpy (movlist, movbuf, movp - movbuf); 00618 return movlist; 00619 } 00620 movp = movbuf; 00621 realp = realbuf; 00622 while (1) 00623 { 00624 byte *tmp; 00625 int w = 0, b = 0; 00626 if (*movp == -2) 00627 break; 00628 /* a capture is a move that involves a W as well as a B piece */ 00629 for (tmp = movp; *tmp != -1; tmp += 3) 00630 { 00631 if (ANTICHESS_ISWHITE (board [tmp[1] * board_heit + tmp[0]])) w = 1; 00632 if (ANTICHESS_ISBLACK (board [tmp[1] * board_heit + tmp[0]])) b = 1; 00633 } 00634 if (w && b) 00635 { 00636 while (*movp != -1) 00637 { 00638 *realp++ = *movp++; 00639 *realp++ = *movp++; 00640 *realp++ = *movp++; 00641 } 00642 *realp++ = *movp++; 00643 } 00644 else 00645 movp = tmp+1; 00646 } 00647 *realp++ = -2; 00648 movlist = (byte *) malloc (realp - realbuf); 00649 memcpy (movlist, realbuf, realp - realbuf); 00650 return movlist; 00651 } 00652 00653 ResultType antichess_eval (Pos * pos, Player player, float *eval) 00654 // TODO: detect end of game by stalemate 00655 { 00656 int wsum = 0, bsum = 0, i; 00657 for (i=0; i < board_wid * board_heit; i++) 00658 if (ANTICHESS_ISWHITE (pos->board[i])) 00659 wsum++; 00660 else if (ANTICHESS_ISBLACK (pos->board[i])) 00661 bsum++; 00662 if (wsum == 0) 00663 { 00664 *eval = GAME_EVAL_INFTY; 00665 return RESULT_WHITE; 00666 } 00667 if (bsum == 0) 00668 { 00669 *eval = -GAME_EVAL_INFTY; 00670 return RESULT_BLACK; 00671 } 00672 *eval = bsum - wsum; 00673 return RESULT_NOTYET; 00674 } 00675 00676 ResultType antichess_eval_incr (Pos *pos, Player player, byte *move, float *eval) 00677 // check if there's a capture 00678 { 00679 byte *board = pos->board; 00680 if (player == WHITE) 00681 { 00682 if (move[2] && board[move[1] * board_wid + move[0]]) *eval = -1; 00683 else if (move[5] && board[move[4] * board_wid + move[3]]) return -1; 00684 else *eval = 0; 00685 } 00686 else 00687 { 00688 if (move[2] && board[move[1] * board_wid + move[0]]) *eval = 1; 00689 else if (move[5] && board[move[4] * board_wid + move[3]]) *eval = 1; 00690 else *eval = 0; 00691 } 00692 return RESULT_NOTYET; 00693 }