![]() |
Cinnamon
1.0
chess engine
|
00001 #include "GenMoves.h" 00002 00003 GenMoves::GenMoves() { 00004 perftMode=false; 00005 currentPly=0; 00006 gen_list = (_TmoveP*) calloc(MAX_PLY, sizeof(_TmoveP)); 00007 assert(gen_list); 00008 for (int i = 0; i < MAX_PLY; i++) { 00009 gen_list[i].moveList = (_Tmove*) calloc(MAX_MOVE, sizeof(_Tmove)); 00010 assert(gen_list[i].moveList); 00011 } 00012 repetitionMap=(u64*)malloc(sizeof(u64)*MAX_REP_COUNT); 00013 assert(repetitionMap); 00014 listId = -1; 00015 repetitionMapCount=0; 00016 } 00017 00018 void GenMoves::generateMoves( const int side, u64 allpieces) { 00019 side?generateMoves<WHITE>(allpieces):generateMoves<BLACK>(allpieces); 00020 } 00021 00022 template <int side> 00023 void GenMoves::generateMoves(u64 allpieces) { 00024 ASSERT( chessboard[KING_BLACK]); 00025 ASSERT(chessboard[KING_WHITE]); 00026 tryAllCastle(side, allpieces); 00027 performBishopShift( BISHOP_BLACK+side, side, allpieces); 00028 performRookQueenShift( ROOK_BLACK+side, side, allpieces); 00029 performRookQueenShift( QUEEN_BLACK+side, side, allpieces); 00030 performBishopShift( QUEEN_BLACK+side, side, allpieces); 00031 performPawnShift<side>(~allpieces); 00032 performKnightShiftCapture( KNIGHT_BLACK+side, ~allpieces, side); 00033 performKingShiftCapture(side,~allpieces); 00034 } 00035 00036 bool GenMoves::generateCaptures( const int side, u64 enemies,u64 friends,u64* key) { 00037 return side?generateCaptures<WHITE>( enemies,friends,key):generateCaptures<BLACK>( enemies,friends,key); 00038 } 00039 00040 template <int side> 00041 bool GenMoves::generateCaptures( u64 enemies,u64 friends,u64* key) { 00042 ASSERT(chessboard[KING_BLACK]); 00043 ASSERT(chessboard[KING_WHITE]); 00044 u64 allpieces = enemies|friends; 00045 00046 if (performPawnCapture<side>( enemies,key)) 00047 return true; 00048 if (performKingShiftCapture(side, enemies)) 00049 return true; 00050 00051 if (performKnightShiftCapture( KNIGHT_BLACK+side, enemies, side)) 00052 return true; 00053 00054 if (performBishopCapture( BISHOP_BLACK+side, enemies, side, allpieces)) 00055 return true; 00056 00057 if (performRookQueenCapture( ROOK_BLACK+side, enemies, side, allpieces)) 00058 return true; 00059 00060 if (performRookQueenCapture( QUEEN_BLACK+side, enemies, side, allpieces)) 00061 return true; 00062 if (performBishopCapture( QUEEN_BLACK+side, enemies, side, allpieces)) 00063 return true; 00064 00065 return false; 00066 } 00067 00068 void GenMoves::setKillerHeuristic(int from, int to, int value) { 00069 ASSERT(from >= 0 && from <64 && to >=0 && to <64); 00070 killerHeuristic[from][to] = value; 00071 } 00072 00073 void GenMoves::incKillerHeuristic(int from, int to, int value) { 00074 ASSERT(from >= 0 && from <64 && to >=0 && to <64); 00075 ASSERT (killerHeuristic[from][to] <= killerHeuristic[from][to] + value); 00076 killerHeuristic[from][to] += value; 00077 } 00078 00079 void GenMoves::setPerft(bool b) { 00080 perftMode=b; 00081 } 00082 00083 void GenMoves::clearKillerHeuristic() { 00084 memset(killerHeuristic, 0, sizeof(killerHeuristic)); 00085 } 00086 00087 _Tmove* GenMoves::getNextMove(_TmoveP* list) { 00088 _Tmove* gen_list1=list->moveList; 00089 int listcount = list->size; 00090 int bestId = -1; 00091 int j,bestScore; 00092 for (j = 0; j < listcount; j++) { 00093 if (!gen_list1[j].used) { 00094 bestId = j; 00095 bestScore=gen_list1[bestId].score; 00096 break; 00097 } 00098 } 00099 if (bestId == -1) 00100 return NULL; 00101 for (int i = j+1; i < listcount; i++) { 00102 if (!gen_list1[i].used && gen_list1[i].score > bestScore) 00103 bestId = i; 00104 bestScore=gen_list1[bestId].score; 00105 } 00106 gen_list1[bestId].used = true; 00107 return &gen_list1[bestId]; 00108 } 00109 00110 GenMoves::~GenMoves() { 00111 for (int i = 0; i < MAX_PLY; i++) 00112 free(gen_list[i].moveList); 00113 free(gen_list); 00114 free(repetitionMap); 00115 } 00116 00117 bool GenMoves::isPinned(const int side, const uchar position, const uchar piece) { 00118 u64 king = chessboard[KING_BLACK + side]; 00119 int posKing =BITScanForward(king); 00120 u64 pow2position=POW2[position]; 00121 if(!(LEFT_RIGHT_RANK_FILE[posKing] & pow2position)) 00122 return false; 00123 int xside = side ^ 1; 00124 chessboard[piece] &= NOTPOW2[position]; 00125 u64 allpieces = getBitBoard<WHITE>()|getBitBoard<BLACK>(); 00126 u64 qr=chessboard[QUEEN_BLACK + xside]|chessboard[ROOK_BLACK + xside]; 00127 u64 qb=chessboard[QUEEN_BLACK + xside]|chessboard[BISHOP_BLACK + xside]; 00128 00129 if (king & RANK[position] && RANK[position]&qr) { 00130 //rank 00131 for(int n=position+1; n<=ORIZ_LEFT[position]; n++) { 00132 if(qr & POW2[n]) { 00133 chessboard[piece] |= pow2position; 00134 return true; 00135 } 00136 if(allpieces & POW2[n])break; 00137 } 00138 for(int n=position-1; n>=ORIZ_RIGHT[position]; n--) { 00139 if(qr & POW2[n]) { 00140 chessboard[piece] |= pow2position; 00141 return true; 00142 } 00143 if(allpieces & POW2[n])break; 00144 00145 } 00146 } else if (king & FILE_[position] && FILE_[position] & qr) { 00147 for(int n=posKing+8; n<=VERT_UPPER[posKing]; n+=8) { 00148 if(qr & POW2[n]) { 00149 chessboard[piece] |= pow2position; 00150 return true; 00151 } 00152 if(POW2[n]&allpieces)break; 00153 } 00154 for(int n=posKing-8; n>=VERT_LOWER[posKing]; n-=8) { 00155 if(qr & POW2[n]) { 00156 chessboard[piece] |= pow2position; 00157 return true; 00158 } 00159 if(POW2[n]&allpieces)break; 00160 } 00161 } else if (king & LEFT_DIAG[position] && LEFT_DIAG[position] &qb) { 00162 for(int n=position+7; n<=LEFT_UPPER[position]; n+=7) { 00163 if(qb & POW2[n]) { 00164 chessboard[piece] |= pow2position; 00165 return true; 00166 } 00167 if(allpieces & POW2[n])break; 00168 } 00169 for(int n=position-7; n>=LEFT_LOWER[position]; n-=7) { 00170 if(qb & POW2[n]) { 00171 chessboard[piece] |= pow2position; 00172 return true; 00173 } 00174 if(allpieces & POW2[n])break; 00175 } 00176 } else if (king & RIGHT_DIAG[position] && RIGHT_DIAG[position] & qb) { 00177 for(int n=position+9; n<=RIGHT_UPPER[position]; n+=9) { 00178 if(qb & POW2[n]) { 00179 chessboard[piece] |= pow2position; 00180 return true; 00181 } 00182 if(allpieces & POW2[n])break; 00183 } 00184 for(int n=position-9; n>=RIGHT_LOWER[position]; n-=9) { 00185 if(qb & POW2[n]) { 00186 chessboard[piece] |= pow2position; 00187 return true; 00188 } 00189 if(allpieces & POW2[n])break; 00190 } 00191 } 00192 chessboard[piece] |= pow2position; 00193 return false; 00194 } 00195 00196 00197 void GenMoves::performCastle(const int side, const uchar type, u64*key) { 00198 if (side == WHITE) { 00199 if (type & KING_SIDE_CASTLE_MOVE_MASK) { 00200 ASSERT(getPieceAt(side, POW2_3) == KING_WHITE); 00201 ASSERT(getPieceAt(side, POW2_1) == SQUARE_FREE); 00202 ASSERT(getPieceAt(side, POW2_2) == SQUARE_FREE); 00203 ASSERT(getPieceAt(side, POW2_0) == ROOK_WHITE); 00204 00205 updateZobristKey(key, KING_WHITE, 3); 00206 updateZobristKey(key, KING_WHITE, 1); 00207 chessboard[KING_WHITE] = (chessboard[KING_WHITE] | POW2_1) & NOTPOW2_3; 00208 00209 updateZobristKey(key, ROOK_WHITE, 2); 00210 updateZobristKey(key, ROOK_WHITE, 0); 00211 chessboard[ROOK_WHITE] = (chessboard[ROOK_WHITE] | POW2_2) & NOTPOW2_0; 00212 00213 } else { 00214 ASSERT(type & QUEEN_SIDE_CASTLE_MOVE_MASK); 00215 ASSERT(getPieceAt(side, POW2_3) == KING_WHITE); 00216 ASSERT(getPieceAt(side, POW2_4) == SQUARE_FREE); 00217 ASSERT(getPieceAt(side, POW2_5) == SQUARE_FREE); 00218 ASSERT(getPieceAt(side, POW2_6) == SQUARE_FREE); 00219 ASSERT(getPieceAt(side, POW2_7) == ROOK_WHITE); 00220 chessboard[KING_WHITE] = (chessboard[KING_WHITE] | POW2_5) & NOTPOW2_3; 00221 00222 updateZobristKey(key, KING_WHITE, 5); 00223 updateZobristKey(key, KING_WHITE, 3); 00224 chessboard[ROOK_WHITE] = (chessboard[ROOK_WHITE] | POW2_4) & NOTPOW2_7; 00225 00226 updateZobristKey(key, ROOK_WHITE, 4); 00227 updateZobristKey(key, ROOK_WHITE, 7); 00228 } 00229 } else { 00230 if (type & KING_SIDE_CASTLE_MOVE_MASK) { 00231 00232 ASSERT(getPieceAt(side, POW2_59) == KING_BLACK); 00233 ASSERT(getPieceAt(side, POW2_58) == SQUARE_FREE); 00234 ASSERT(getPieceAt(side, POW2_57) == SQUARE_FREE); 00235 ASSERT(getPieceAt(side, POW2_56) == ROOK_BLACK); 00236 00237 chessboard[KING_BLACK] = (chessboard[KING_BLACK] | POW2_57) & NOTPOW2_59; 00238 00239 updateZobristKey(key, KING_BLACK, 57); 00240 updateZobristKey(key, KING_BLACK, 59); 00241 chessboard[ROOK_BLACK] = (chessboard[ROOK_BLACK] | POW2_58) & NOTPOW2_56; 00242 00243 updateZobristKey(key, ROOK_BLACK, 58); 00244 updateZobristKey(key, ROOK_BLACK, 56); 00245 } else { 00246 ASSERT(type & QUEEN_SIDE_CASTLE_MOVE_MASK); 00247 ASSERT(getPieceAt(side, POW2_59) == KING_BLACK); 00248 ASSERT(getPieceAt(side, POW2_60) == SQUARE_FREE); 00249 ASSERT(getPieceAt(side, POW2_61) == SQUARE_FREE); 00250 ASSERT(getPieceAt(side, POW2_62) == SQUARE_FREE); 00251 ASSERT(getPieceAt(side, POW2_63) == ROOK_BLACK); 00252 00253 chessboard[KING_BLACK] = (chessboard[KING_BLACK] | POW2_61) & NOTPOW2_59; 00254 00255 updateZobristKey(key, KING_BLACK, 61); 00256 updateZobristKey(key, KING_BLACK, 59); 00257 chessboard[ROOK_BLACK] = (chessboard[ROOK_BLACK] | POW2_60) & NOTPOW2_63; 00258 00259 updateZobristKey(key, ROOK_BLACK, 60); 00260 updateZobristKey(key, ROOK_BLACK, 63); 00261 } 00262 } 00263 } 00264 00265 void GenMoves::performRookQueenShift(const int piece, const int side, const u64 allpieces) { 00266 ASSERT(piece >= 0 && piece < 12); 00267 int n, position; 00268 u64 x2 = chessboard[piece]; 00269 while (x2) { 00270 position = BITScanForward(x2); 00271 for(n=position+1; n<=ORIZ_LEFT[position]; n++) { 00272 if((allpieces & POW2[n])==0) 00273 pushmove<STANDARD_MOVE_MASK>( position, n, side, NO_PROMOTION,piece); 00274 else break; 00275 } 00276 for(n=position-1; n>=ORIZ_RIGHT[position]; n--) { 00277 if((allpieces & POW2[n])==0) 00278 pushmove<STANDARD_MOVE_MASK>( position, n, side, NO_PROMOTION,piece); 00279 else break; 00280 } 00281 for(n=position+8; n<=VERT_UPPER[position]; n+=8) { 00282 if((allpieces & POW2[n])==0) 00283 pushmove<STANDARD_MOVE_MASK>( position, n, side, NO_PROMOTION,piece); 00284 else break; 00285 } 00286 for(n=position-8; n>=VERT_LOWER[position]; n-=8) { 00287 if((allpieces & POW2[n])==0) 00288 pushmove<STANDARD_MOVE_MASK>( position, n, side, NO_PROMOTION,piece); 00289 else break; 00290 } 00291 x2 &= NOTPOW2[position]; 00292 }; 00293 } 00294 00295 void GenMoves::performBishopShift( const int piece, const int side, const u64 allpieces) { 00296 ASSERT(piece >= 0 && piece < 12); 00297 int position; 00298 int n; 00299 u64 x2 = chessboard[piece]; 00300 while (x2) { 00301 position = BITScanForward(x2); 00302 for(n=position+7; n<=LEFT_UPPER[position]; n+=7) { 00303 if((allpieces & POW2[n])==0) 00304 pushmove<STANDARD_MOVE_MASK>( position, n, side, NO_PROMOTION,piece); 00305 else break; 00306 } 00307 00308 for(n=position-7; n>=LEFT_LOWER[position]; n-=7) { 00309 if((allpieces & POW2[n])==0) 00310 pushmove<STANDARD_MOVE_MASK>( position, n, side, NO_PROMOTION,piece); 00311 else break; 00312 } 00313 00314 for(n=position+9; n<=RIGHT_UPPER[position]; n+=9) { 00315 if((allpieces & POW2[n])==0) 00316 pushmove<STANDARD_MOVE_MASK>( position, n, side, NO_PROMOTION,piece); 00317 else 00318 break; 00319 } 00320 00321 for(n=position-9; n>=RIGHT_LOWER[position]; n-=9) { 00322 if((allpieces & POW2[n])==0) 00323 pushmove<STANDARD_MOVE_MASK>( position, n, side, NO_PROMOTION,piece); 00324 else break; 00325 } 00326 x2 &= NOTPOW2[position]; 00327 }; 00328 } 00329 00330 void GenMoves::tryAllCastle(const int side, const u64 allpieces) { 00331 if (side == WHITE) { 00332 if (POW2_3 & chessboard[KING_WHITE] && !(allpieces & 0x6ULL) && RIGHT_CASTLE & RIGHT_KING_CASTLE_WHITE_MASK 00333 && chessboard[ROOK_WHITE] & POW2_0 && !attackSquare<WHITE>( 1) && !attackSquare<WHITE>( 2) && !attackSquare<WHITE>( 3)) { 00334 pushmove<KING_SIDE_CASTLE_MOVE_MASK>( -1, -1, WHITE, NO_PROMOTION,-1); 00335 } 00336 if (POW2_3 & chessboard[KING_WHITE] && !(allpieces & 0x70ULL) && RIGHT_CASTLE & RIGHT_QUEEN_CASTLE_WHITE_MASK 00337 && chessboard[ROOK_WHITE] & POW2_7 && !attackSquare<WHITE>( 3) && !attackSquare<WHITE>( 4) && !attackSquare<WHITE>(5)) { 00338 pushmove<QUEEN_SIDE_CASTLE_MOVE_MASK>( -1, -1, WHITE, NO_PROMOTION,-1); 00339 } 00340 } else { 00341 if (POW2_59 & chessboard[KING_BLACK] && RIGHT_CASTLE & RIGHT_KING_CASTLE_BLACK_MASK && !(allpieces & 0x600000000000000ULL) 00342 && chessboard[ROOK_BLACK] & POW2_56 && !attackSquare<BLACK>( 57) && !attackSquare<BLACK>(58) && !attackSquare<BLACK>(59)) { 00343 pushmove<KING_SIDE_CASTLE_MOVE_MASK>( -1, -1, BLACK, NO_PROMOTION,-1); 00344 } 00345 if (POW2_59 & chessboard[KING_BLACK] && RIGHT_CASTLE & RIGHT_QUEEN_CASTLE_BLACK_MASK && !(allpieces & 0x7000000000000000ULL) 00346 && chessboard[ROOK_BLACK] & POW2_63 && !attackSquare<BLACK>(59) && !attackSquare<BLACK>(60) && !attackSquare<BLACK>(61)) { 00347 pushmove<QUEEN_SIDE_CASTLE_MOVE_MASK>( -1, -1, BLACK, NO_PROMOTION,-1); 00348 } 00349 } 00350 } 00351 00352 bool GenMoves::performRookQueenCapture( const int piece, const u64 enemies, const int side, const u64 allpieces) { 00353 ASSERT(piece >= 0 && piece < 12); 00354 int n, position; 00355 u64 x2 = chessboard[piece]; 00356 while (x2) { 00357 position = BITScanForward(x2); 00358 for(n=position+1; n<=ORIZ_LEFT[position]; n++) { 00359 if(allpieces & POW2[n]) { 00360 if(enemies & POW2[n])if(pushmove<STANDARD_MOVE_MASK>( position, n, side, NO_PROMOTION,piece))return true; 00361 break; 00362 } 00363 } 00364 for(n=position-1; n>=ORIZ_RIGHT[position]; n--) { 00365 if(allpieces & POW2[n]) { 00366 if(enemies & POW2[n])if(pushmove<STANDARD_MOVE_MASK>( position, n, side, NO_PROMOTION,piece))return true; 00367 break; 00368 } 00369 } 00370 00371 for(n=position+8; n<=VERT_UPPER[position]; n+=8) { 00372 if(allpieces & POW2[n]) { 00373 if(enemies & POW2[n])if(pushmove<STANDARD_MOVE_MASK>( position, n, side, NO_PROMOTION,piece))return true; 00374 break; 00375 } 00376 } 00377 for(n=position-8; n>=VERT_LOWER[position]; n-=8) { 00378 if(allpieces & POW2[n]) { 00379 if(enemies & POW2[n])if(pushmove<STANDARD_MOVE_MASK>( position, n, side, NO_PROMOTION,piece))return true; 00380 break; 00381 } 00382 } 00383 x2 &= NOTPOW2[position]; 00384 }; 00385 return false; 00386 } 00387 00388 bool GenMoves::performBishopCapture( const int piece, const u64 enemies, const int side, const u64 allpieces) { 00389 ASSERT(piece >= 0 && piece < 12); 00390 int position,n; 00391 u64 x2 = chessboard[piece]; 00392 while (x2) { 00393 position = BITScanForward(x2); 00394 00395 for(n=position+7; n<=LEFT_UPPER[position]; n+=7) { 00396 if(allpieces & POW2[n]) { 00397 if (enemies & POW2[n]) if(pushmove<STANDARD_MOVE_MASK>( position, n, side, NO_PROMOTION,piece))return true; 00398 break; 00399 } 00400 } 00401 00402 for(n=position-7; n>=LEFT_LOWER[position]; n-=7) { 00403 if((allpieces & POW2[n])) { 00404 if (enemies & POW2[n])if(pushmove<STANDARD_MOVE_MASK>( position, n, side, NO_PROMOTION,piece))return true; 00405 break; 00406 } 00407 } 00408 00409 for(n=position+9; n<=RIGHT_UPPER[position]; n+=9) { 00410 if((allpieces & POW2[n])) { 00411 if (enemies & POW2[n]) if(pushmove<STANDARD_MOVE_MASK>( position, n, side, NO_PROMOTION,piece))return true; 00412 break; 00413 } 00414 } 00415 00416 for(n=position-9; n>=RIGHT_LOWER[position]; n-=9) { 00417 if((allpieces & POW2[n])) { 00418 if (enemies & POW2[n]) if(pushmove<STANDARD_MOVE_MASK>( position, n, side, NO_PROMOTION,piece))return true; 00419 break; 00420 } 00421 } 00422 x2 &= NOTPOW2[position]; 00423 }; 00424 return false; 00425 } 00426 00427 bool GenMoves::performKnightShiftCapture(const int piece, const u64 enemies, const int side) { 00428 u64 x1; 00429 int o, pos; 00430 u64 x = chessboard[piece]; 00431 while (x) { 00432 pos = BITScanForward(x); 00433 x1 = enemies & KNIGHT_MASK[pos]; 00434 while (x1) { 00435 o = BITScanForward(x1); 00436 if (pushmove<STANDARD_MOVE_MASK>( pos, o, side, NO_PROMOTION,piece)) 00437 return true; 00438 x1 &= NOTPOW2[o]; 00439 }; 00440 x &= NOTPOW2[pos]; 00441 } 00442 return false; 00443 } 00444 00445 bool GenMoves::performKingShiftCapture(int side , const u64 enemies) { 00446 int o; 00447 int pos = BITScanForward(chessboard[KING_BLACK+side]); 00448 ASSERT(pos != -1); 00449 u64 x1 = enemies & NEAR_MASK1[pos]; 00450 while (x1) { 00451 o = BITScanForward(x1); 00452 if (pushmove<STANDARD_MOVE_MASK>( pos, o, side, NO_PROMOTION,KING_BLACK+side)) 00453 return true; 00454 x1 &= NOTPOW2[o]; 00455 }; 00456 return false; 00457 } 00458 00459 template <int side> 00460 void GenMoves::checkJumpPawn(u64 x, const u64 xallpieces) { 00461 x &= TABJUMPPAWN; 00462 if (side) { 00463 x=(((x<<8)&xallpieces)<<8)&xallpieces; 00464 } else { 00465 x=(((x>>8)&xallpieces)>>8)&xallpieces; 00466 }; 00467 int o; 00468 while (x) { 00469 o = BITScanForward(x); 00470 pushmove<STANDARD_MOVE_MASK>( o + (side?-16:16), o, side, NO_PROMOTION,side); 00471 x &= NOTPOW2[o]; 00472 }; 00473 } 00474 00475 template <int side> 00476 void GenMoves::performPawnShift( const u64 xallpieces) { 00477 int o, tt; 00478 u64 x = chessboard[side]; 00479 if (x & PAWNS_7_2[side]) 00480 checkJumpPawn<side>( x, xallpieces); 00481 if (side) { 00482 x <<= 8; 00483 tt = -8; 00484 } else { 00485 tt = 8; 00486 x >>= 8; 00487 }; 00488 x &= xallpieces; 00489 while (x) { 00490 o = BITScanForward(x); 00491 ASSERT(getPieceAt(side, POW2[o + tt]) != SQUARE_FREE); 00492 ASSERT(getBitBoard(side) & POW2[o + tt]); 00493 if (o > 55 || o < 8) { 00494 pushmove<PROMOTION_MOVE_MASK>( o + tt, o, side, QUEEN_BLACK + side,side); //queen 00495 if( perftMode) { 00496 pushmove<PROMOTION_MOVE_MASK>( o + tt, o, side, KNIGHT_BLACK + side,side); //knight 00497 pushmove<PROMOTION_MOVE_MASK>( o + tt, o, side, BISHOP_BLACK + side,side);//bishop 00498 pushmove<PROMOTION_MOVE_MASK>( o + tt, o, side, ROOK_BLACK + side,side);//rock 00499 } 00500 } else 00501 pushmove<STANDARD_MOVE_MASK>( o + tt, o, side, NO_PROMOTION,side); 00502 x &= NOTPOW2[o]; 00503 }; 00504 } 00505 00506 template <int side> 00507 bool GenMoves::performPawnCapture( const u64 enemies,u64*key) { 00508 if (!chessboard[side]) { 00509 if(enpassantPosition!=-1) 00510 updateZobristKey(key, 13, enpassantPosition); 00511 enpassantPosition = -1; 00512 return false; 00513 } 00514 int GG; 00515 u64 x; 00516 if (side) { 00517 x = (chessboard[side] << 7) & TABCAPTUREPAWN_LEFT & enemies; 00518 GG = -7; 00519 } else { 00520 x = (chessboard[side] >> 7) & TABCAPTUREPAWN_RIGHT & enemies; 00521 GG = 7; 00522 }; 00523 int o; 00524 while (x) { 00525 o = BITScanForward(x); 00526 if ( (side && o > 55) || (!side && o < 8)) {//PROMOTION 00527 if (pushmove<PROMOTION_MOVE_MASK>( o + GG, o, side, QUEEN_BLACK + side,side)) 00528 return true; //queen 00529 if( perftMode) { 00530 if (pushmove<PROMOTION_MOVE_MASK>( o + GG, o, side, KNIGHT_BLACK + side,side)) 00531 return true;//knight 00532 if (pushmove<PROMOTION_MOVE_MASK>( o + GG, o, side, ROOK_BLACK + side,side)) 00533 return true;//rock 00534 if (pushmove<PROMOTION_MOVE_MASK>( o + GG, o, side, BISHOP_BLACK + side,side)) 00535 return true;//bishop 00536 } 00537 } else if (pushmove<STANDARD_MOVE_MASK>( o + GG, o, side, NO_PROMOTION,side)) 00538 return true; 00539 x &= NOTPOW2[o]; 00540 }; 00541 if (side) { 00542 GG = -9; 00543 x= (chessboard[side] << 9)&TABCAPTUREPAWN_RIGHT & enemies; 00544 } else { 00545 GG = 9; 00546 x= (chessboard[side] >> 9)&TABCAPTUREPAWN_LEFT & enemies; 00547 }; 00548 while (x) { 00549 o = BITScanForward(x); 00550 if ( (side && o > 55) || (!side && o < 8)) {//PROMOTION 00551 if (pushmove<PROMOTION_MOVE_MASK>( o + GG, o, side, QUEEN_BLACK + side,side)) 00552 return true; //queen 00553 if( perftMode) { 00554 if (pushmove<PROMOTION_MOVE_MASK>( o + GG, o, side, KNIGHT_BLACK + side,side)) 00555 00556 return true; //knight 00557 if (pushmove<PROMOTION_MOVE_MASK>( o + GG, o, side, BISHOP_BLACK + side,side)) 00558 00559 return true;//bishop 00560 if (pushmove<PROMOTION_MOVE_MASK>( o + GG, o, side, ROOK_BLACK + side,side)) 00561 00562 return true;//rock 00563 } 00564 } else if (pushmove<STANDARD_MOVE_MASK>( o + GG, o, side, NO_PROMOTION,side)) 00565 return true; 00566 x &= NOTPOW2[o]; 00567 }; 00568 00569 //ENPASSANT 00570 if(enpassantPosition!=-1) { 00571 x = ENPASSANT_MASK[side ^ 1][enpassantPosition] & chessboard[side]; 00572 while (x) { 00573 o = BITScanForward(x); 00574 pushmove<ENPASSANT_MOVE_MASK>( o, (side?enpassantPosition + 8:enpassantPosition - 8), side, NO_PROMOTION,side); 00575 x &= NOTPOW2[o]; 00576 } 00577 updateZobristKey(key, 13, enpassantPosition); 00578 enpassantPosition = -1; 00579 } 00580 00581 return false; 00582 } 00583 00584 00585 u64 GenMoves::getKingAttackers(const int side) { 00586 int kingPosition=BITScanForward(chessboard[KING_BLACK + side]); 00587 int xside=side^1; 00588 u64 attackers=0; 00589 attackers|=KNIGHT_MASK[kingPosition] & chessboard[KNIGHT_BLACK + xside]; 00590 attackers|=NEAR_MASK1[kingPosition] & chessboard[KING_BLACK + xside]; 00591 attackers|=PAWN_CAPTURE_MASK[side][kingPosition] & chessboard[PAWN_BLACK + xside]; 00592 if (! 00593 ((RANK_FILE[kingPosition] & (chessboard[ROOK_BLACK + xside] | chessboard[QUEEN_BLACK + xside])) 00594 | (LEFT_RIGHT_DIAG[kingPosition] & (chessboard[QUEEN_BLACK + xside] | chessboard[BISHOP_BLACK + xside]))) 00595 ) { 00596 return attackers; 00597 } 00598 u64 allpieces =getBitBoard<WHITE>() | getBitBoard<BLACK>()|POW2[kingPosition]; 00599 00600 //right 00601 u64 qb=chessboard[QUEEN_BLACK + xside]|chessboard[BISHOP_BLACK + xside]; 00602 for(int n=kingPosition+9; n<=RIGHT_UPPER[kingPosition]; n+=9) { 00603 if(qb & POW2[n]) 00604 attackers|=POW2[n]; 00605 if(allpieces & POW2[n])break; 00606 } 00607 for(int n=kingPosition-9; n>=RIGHT_LOWER[kingPosition]; n-=9) { 00608 if(qb & POW2[n]) 00609 attackers|=POW2[n]; 00610 if(allpieces & POW2[n])break; 00611 } 00612 // left 00613 for(int n=kingPosition+7; n<=LEFT_UPPER[kingPosition]; n+=7) { 00614 if(qb & POW2[n]) 00615 attackers|=POW2[n]; 00616 if(allpieces & POW2[n])break; 00617 } 00618 for(int n=kingPosition-7; n>=LEFT_LOWER[kingPosition]; n-=7) { 00619 if(qb & POW2[n]) 00620 attackers|=POW2[n]; 00621 if(allpieces & POW2[n])break; 00622 } 00623 00624 //file 00625 u64 qr=chessboard[QUEEN_BLACK + xside]|chessboard[ROOK_BLACK + xside]; 00626 for(int n=kingPosition+8; n<=VERT_UPPER[kingPosition]; n+=8) { 00627 if(qr & POW2[n]) { 00628 attackers|=POW2[n]; 00629 } 00630 if(allpieces & POW2[n])break; 00631 } 00632 for(int n=kingPosition-8; n>=VERT_LOWER[kingPosition]; n-=8) { 00633 if(qr & POW2[n]) { 00634 attackers|=POW2[n]; 00635 } 00636 if(allpieces & POW2[n])break; 00637 00638 } 00639 //rank 00640 for(int n=kingPosition+1; n<=ORIZ_LEFT[kingPosition]; n++) { 00641 if(qr & POW2[n]) { 00642 attackers|=POW2[n]; 00643 } 00644 if(allpieces & POW2[n])break; 00645 } 00646 for(int n=kingPosition-1; n>=ORIZ_RIGHT[kingPosition]; n--) { 00647 if(qr & POW2[n]) { 00648 attackers|=POW2[n]; 00649 } 00650 if(allpieces & POW2[n])break; 00651 00652 } 00653 return attackers; 00654 } 00655 00656 template <int side> 00657 bool GenMoves::attackSquare(const uchar Position) { 00658 if (KNIGHT_MASK[Position] & chessboard[KNIGHT_BLACK + (side^1)]) { 00659 return true; 00660 } 00661 if (NEAR_MASK1[Position] & chessboard[KING_BLACK + (side^1)]) { 00662 return true; 00663 } 00664 //enpassant 00665 if (PAWN_CAPTURE_MASK[side][Position] & chessboard[PAWN_BLACK + (side^1)]) { 00666 return true; 00667 } 00668 ASSERT(Position < 64); 00669 if (! 00670 ((RANK_FILE[Position] & (chessboard[ROOK_BLACK + (side^1)] | chessboard[QUEEN_BLACK + (side^1)])) 00671 | (LEFT_RIGHT_DIAG[Position] & (chessboard[QUEEN_BLACK + (side^1)] | chessboard[BISHOP_BLACK + (side^1)]))) 00672 ) { 00673 return false; 00674 } 00675 u64 allpieces =getBitBoard<WHITE>() | getBitBoard<BLACK>()|POW2[Position]; 00676 00677 //right 00678 u64 qb=chessboard[QUEEN_BLACK + (side^1)]|chessboard[BISHOP_BLACK + (side^1)]; 00679 for(int n=Position+9; n<=RIGHT_UPPER[Position]; n+=9) { 00680 if(qb & POW2[n]) 00681 return true; 00682 if(allpieces & POW2[n])break; 00683 } 00684 for(int n=Position-9; n>=RIGHT_LOWER[Position]; n-=9) { 00685 if(qb & POW2[n]) 00686 return true; 00687 if(allpieces & POW2[n])break; 00688 } 00689 // left 00690 for(int n=Position+7; n<=LEFT_UPPER[Position]; n+=7) { 00691 if(qb & POW2[n]) 00692 return true; 00693 if(allpieces & POW2[n])break; 00694 } 00695 for(int n=Position-7; n>=LEFT_LOWER[Position]; n-=7) { 00696 if(qb & POW2[n]) 00697 return true; 00698 if(allpieces & POW2[n])break; 00699 } 00700 00701 //file 00702 u64 qr=chessboard[QUEEN_BLACK + (side^1)]|chessboard[ROOK_BLACK + (side^1)]; 00703 for(int n=Position+8; n<=VERT_UPPER[Position]; n+=8) { 00704 if(qr & POW2[n]) { 00705 return true; 00706 } 00707 if(allpieces & POW2[n])break; 00708 } 00709 for(int n=Position-8; n>=VERT_LOWER[Position]; n-=8) { 00710 if(qr & POW2[n]) { 00711 return true; 00712 } 00713 if(allpieces & POW2[n])break; 00714 00715 } 00716 //rank 00717 for(int n=Position+1; n<=ORIZ_LEFT[Position]; n++) { 00718 if(qr & POW2[n]) { 00719 return true; 00720 } 00721 if(allpieces & POW2[n])break; 00722 } 00723 for(int n=Position-1; n>=ORIZ_RIGHT[Position]; n--) { 00724 if(qr & POW2[n]) { 00725 return true; 00726 } 00727 if(allpieces & POW2[n])break; 00728 00729 } 00730 return false; 00731 } 00732 00733 void GenMoves::unPerformCastle(const int side, const uchar type) { 00734 if (side == WHITE) { 00735 if (type & KING_SIDE_CASTLE_MOVE_MASK) { 00736 ASSERT(getPieceAt (side, POW2_1) == KING_WHITE); 00737 ASSERT(getPieceAt (side, POW2_0) == 12); 00738 ASSERT(getPieceAt (side, POW2_3) == 12); 00739 ASSERT(getPieceAt (side, POW2_2) == ROOK_WHITE); 00740 chessboard[KING_WHITE] = (chessboard[KING_WHITE] | POW2_3) & NOTPOW2_1; 00741 chessboard[ROOK_WHITE] = (chessboard[ROOK_WHITE] | POW2_0) & NOTPOW2_2; 00742 } else { 00743 chessboard[KING_WHITE] = (chessboard[KING_WHITE] | POW2_3) & NOTPOW2_5; 00744 chessboard[ROOK_WHITE] = (chessboard[ROOK_WHITE] | POW2_7) & NOTPOW2_4; 00745 } 00746 } else { 00747 if (type & KING_SIDE_CASTLE_MOVE_MASK) { 00748 chessboard[KING_BLACK] = (chessboard[KING_BLACK] | POW2_59) & NOTPOW2_57; 00749 chessboard[ROOK_BLACK] = (chessboard[ROOK_BLACK] | POW2_56) & NOTPOW2_58; 00750 } else { 00751 chessboard[KING_BLACK] = (chessboard[KING_BLACK] | POW2_59) & NOTPOW2_61; 00752 chessboard[ROOK_BLACK] = (chessboard[ROOK_BLACK] | POW2_63) & NOTPOW2_60; 00753 } 00754 } 00755 } 00756 template <int side> 00757 bool GenMoves::inCheck(const int from, const int to, const uchar type, const int pieceFrom, const int pieceTo, int promotionPiece) { 00758 ASSERT(!(type & 0xC)); 00759 bool result = 0; 00760 if ((type & 0x3) == STANDARD_MOVE_MASK) { 00761 u64 from1, to1 = -1; 00762 ASSERT (pieceFrom != SQUARE_FREE); 00763 ASSERT (pieceTo != KING_BLACK); 00764 ASSERT (pieceTo != KING_WHITE); 00765 00766 from1 = chessboard[pieceFrom]; 00767 if (pieceTo != SQUARE_FREE) { 00768 to1 = chessboard[pieceTo]; 00769 chessboard[pieceTo] &= NOTPOW2[to]; 00770 }; 00771 chessboard[pieceFrom] &= NOTPOW2[from]; 00772 chessboard[pieceFrom] |= POW2[to]; 00773 00774 ASSERT (chessboard[KING_BLACK]); 00775 ASSERT (chessboard[KING_WHITE]); 00776 00777 result = attackSquare<side>(BITScanForward(chessboard[KING_BLACK + side])); 00778 chessboard[pieceFrom] = from1; 00779 if (pieceTo != SQUARE_FREE) 00780 chessboard[pieceTo] = to1; 00781 } else if ((type & 0x3) == PROMOTION_MOVE_MASK) { 00782 u64 to1 = 0; 00783 if (pieceTo != SQUARE_FREE) 00784 to1 = chessboard[pieceTo]; 00785 u64 from1 = chessboard[pieceFrom]; 00786 u64 p1 = chessboard[promotionPiece]; 00787 chessboard[pieceFrom] &= NOTPOW2[from]; 00788 if (pieceTo != SQUARE_FREE) 00789 chessboard[pieceTo] &= NOTPOW2[to]; 00790 chessboard[promotionPiece] = chessboard[promotionPiece] | POW2[to]; 00791 result = attackSquare<side>(BITScanForward(chessboard[KING_BLACK + side])); 00792 if (pieceTo != SQUARE_FREE) 00793 chessboard[pieceTo] = to1; 00794 chessboard[pieceFrom] = from1; 00795 chessboard[promotionPiece] = p1; 00796 } else if ((type & 0x3) == ENPASSANT_MOVE_MASK) { 00797 u64 to1 = chessboard[side ^ 1]; 00798 u64 from1 = chessboard[side]; 00799 chessboard[side] &= NOTPOW2[from]; 00800 chessboard[side] |= POW2[to]; 00801 if (side) 00802 chessboard[side ^ 1] &= NOTPOW2[to - 8]; 00803 else 00804 chessboard[side ^ 1] &= NOTPOW2[to + 8]; 00805 result = attackSquare<side>( BITScanForward(chessboard[KING_BLACK + side])); 00806 chessboard[side ^ 1] = to1; 00807 chessboard[side] = from1; 00808 } 00809 #ifdef DEBUG_MODE 00810 else 00811 ASSERT (0); 00812 #endif 00813 return result; 00814 } 00815 00816 void GenMoves::takeback(_Tmove * move, u64* key, const u64 oldkey,bool rep) { 00817 if(rep)popStackMove(); 00818 *key = oldkey; 00819 enpassantPosition = -1; 00820 int pieceFrom, posTo, posFrom, movecapture; 00821 RIGHT_CASTLE = move->type & 0b11110000; 00822 if ((move->type & 0b00000011) == STANDARD_MOVE_MASK || (move->type & 0b00000011) == ENPASSANT_MOVE_MASK) { 00823 posTo = move->to; 00824 posFrom = move->from; 00825 movecapture = move->capturedPiece; 00826 ASSERT(posFrom >= 0 && posFrom < 64); 00827 ASSERT(posTo >= 0 && posTo < 64); 00828 pieceFrom = move->pieceFrom; 00829 chessboard[pieceFrom] = (chessboard[pieceFrom] & NOTPOW2[posTo]) | POW2[posFrom]; 00830 if (movecapture != SQUARE_FREE) { 00831 if (((move->type & 0b00000011) != ENPASSANT_MOVE_MASK)) { 00832 chessboard[movecapture] |= POW2[posTo]; 00833 } else { 00834 ASSERT(movecapture == (move->side^1)); 00835 if (move->side) { 00836 chessboard[movecapture] |= POW2[posTo - 8]; 00837 } else { 00838 chessboard[movecapture] |= POW2[posTo + 8]; 00839 } 00840 } 00841 } 00842 00843 } else if ((move->type & 0b00000011) == PROMOTION_MOVE_MASK) { 00844 posTo = move->to; 00845 posFrom = move->from; 00846 movecapture = move->capturedPiece; 00847 ASSERT(posTo >= 0); 00848 chessboard[(uchar)move->side] |= POW2[posFrom]; 00849 chessboard[move->promotionPiece] &= NOTPOW2[posTo]; 00850 if (movecapture != SQUARE_FREE) { 00851 chessboard[movecapture] |= POW2[posTo]; 00852 } 00853 } else if (move->type & 0b00001100) { //castle 00854 unPerformCastle(move->side, move->type); 00855 } 00856 } 00857 template <uchar type> 00858 bool GenMoves::pushmove( const int from, const int to, const int side, int promotionPiece, int pieceFrom) { 00859 ASSERT(chessboard[KING_BLACK]); 00860 ASSERT(chessboard[KING_WHITE]); 00861 int piece_captured = SQUARE_FREE; 00862 bool res = false; 00863 if (((type & 0b00000011) != ENPASSANT_MOVE_MASK) && !(type & 0b00001100)) { 00864 piece_captured = side ^ 1? getPieceAt<WHITE>( POW2[to]):getPieceAt<BLACK>( POW2[to]); 00865 00866 if (piece_captured == KING_BLACK + (side ^ 1)) 00867 res = true; 00868 } else if (!(type & 0b00001100)) //no castle 00869 piece_captured = side ^ 1; 00870 00871 if (!(type & 0b00001100) && perftMode) { //no castle 00872 if (side==WHITE && inCheck<WHITE>(from, to, type, pieceFrom,piece_captured, promotionPiece)) 00873 return false; 00874 if (side==BLACK && inCheck<BLACK>(from, to, type, pieceFrom,piece_captured, promotionPiece)) 00875 return false; 00876 } 00877 _Tmove * mos; 00878 ASSERT (listId >= 0) ; 00879 ASSERT(listId < MAX_PLY); 00880 ASSERT(gen_list[listId].size < MAX_MOVE); 00881 mos = &gen_list[listId].moveList[gen_list[listId].size]; 00882 ++gen_list[listId].size; 00883 mos->type = RIGHT_CASTLE | type; 00884 mos->side = (char) side; 00885 00886 mos->capturedPiece = piece_captured; 00887 if (type & 0b00000011) { 00888 mos->from = (uchar) from; 00889 mos->to = (uchar) to; 00890 mos->pieceFrom= pieceFrom; 00891 mos->promotionPiece = (char) promotionPiece; 00892 if( !perftMode) { 00893 if (res == true) { 00894 mos->score = _INFINITE; 00895 } else { 00896 mos->score = 0; 00897 mos->score += killerHeuristic[from][to]; 00898 mos->score += 00899 (PIECES_VALUE[piece_captured] >= PIECES_VALUE[pieceFrom]) ? (PIECES_VALUE[piece_captured] - PIECES_VALUE[pieceFrom]) * 2 : 00900 PIECES_VALUE[piece_captured]; 00901 ASSERT (pieceFrom >= 0 && pieceFrom < 12 && to >= 0 && to < 64 && from >= 0 && from < 64); 00902 } 00903 } 00904 } 00905 00906 else if (type & 0b00001100) { //castle 00907 ASSERT(RIGHT_CASTLE); 00908 mos->score = 100; 00909 } 00910 mos->used=false; 00911 ASSERT(gen_list[listId].size < MAX_MOVE); 00912 return res; 00913 } 00914 00915 void GenMoves::makemove(_Tmove * move, u64* key,bool rep) { 00916 ASSERT(move); 00917 ASSERT(_bits::bitCount(chessboard[KING_WHITE])==1 && _bits::bitCount(chessboard[KING_BLACK])==1); 00918 int pieceFrom=SQUARE_FREE, posTo, posFrom, movecapture=SQUARE_FREE; 00919 uchar RIGHT_CASTLE_old=RIGHT_CASTLE; 00920 if (!(move->type & 0b00001100)) { //no castle 00921 posTo = move->to; 00922 posFrom = move->from; 00923 ASSERT(posTo >= 0); 00924 movecapture = move->capturedPiece; 00925 ASSERT(posFrom >= 0 && posFrom < 64); 00926 ASSERT(posTo >= 0 && posTo < 64); 00927 pieceFrom = move->pieceFrom; 00928 if ((move->type & 0b00000011) == PROMOTION_MOVE_MASK) { 00929 chessboard[pieceFrom] &= NOTPOW2[posFrom]; 00930 updateZobristKey(key, pieceFrom, posFrom); 00931 chessboard[move->promotionPiece] |= POW2[posTo]; 00932 updateZobristKey(key, move->promotionPiece, posTo); 00933 } else { 00934 chessboard[pieceFrom] = (chessboard[pieceFrom] | POW2[posTo]) & NOTPOW2[posFrom]; 00935 updateZobristKey(key, pieceFrom, posFrom); 00936 updateZobristKey(key, pieceFrom, posTo); 00937 } 00938 00939 if (movecapture != SQUARE_FREE) { 00940 if ((move->type & 0b00000011) != ENPASSANT_MOVE_MASK) { 00941 chessboard[movecapture] &= NOTPOW2[posTo]; 00942 updateZobristKey(key, movecapture, posTo); 00943 } else { 00944 ASSERT(movecapture == (move->side^1)); 00945 if (move->side) { 00946 chessboard[movecapture] &= NOTPOW2[posTo - 8]; 00947 updateZobristKey(key, movecapture, posTo - 8); 00948 } else { 00949 chessboard[movecapture] &= NOTPOW2[posTo + 8]; 00950 updateZobristKey(key, movecapture, posTo + 8); 00951 } 00952 } 00953 } 00954 00955 //lost castle right 00956 00957 switch (pieceFrom) { 00958 case KING_WHITE: { 00959 RIGHT_CASTLE &= 0b11001111; 00960 } 00961 break; 00962 case KING_BLACK: { 00963 RIGHT_CASTLE &= 0b00111111; 00964 } 00965 break; 00966 00967 case ROOK_WHITE: 00968 if (posFrom == 0) { 00969 RIGHT_CASTLE &= 0b11101111; 00970 } else if (posFrom == 7) { 00971 RIGHT_CASTLE &= 0b11011111; 00972 } 00973 break; 00974 case ROOK_BLACK: 00975 if (posFrom == 56) { 00976 RIGHT_CASTLE &= 0b10111111; 00977 } else if (posFrom == 63) { 00978 RIGHT_CASTLE &= 0b01111111; 00979 } 00980 break; 00981 //en passant 00982 case PAWN_WHITE: 00983 if ((RANK_1 & POW2[posFrom]) && (RANK_3 & POW2[posTo])) { 00984 enpassantPosition = posTo; 00985 updateZobristKey(key, 13, enpassantPosition); 00986 } 00987 break; 00988 00989 case PAWN_BLACK: 00990 if ((RANK_6 & POW2[posFrom]) && (RANK_4 & POW2[posTo])) { 00991 enpassantPosition = posTo; 00992 updateZobristKey(key, 13, enpassantPosition); 00993 } 00994 break; 00995 default: 00996 ; 00997 } 00998 } else if (move->type & 0b00001100) { //castle 00999 performCastle(move->side, move->type, key); 01000 if (move->side == WHITE) { 01001 RIGHT_CASTLE &= 0b11001111; 01002 } else { 01003 RIGHT_CASTLE &= 0b00111111; 01004 } 01005 } 01006 u64 x2=RIGHT_CASTLE_old^RIGHT_CASTLE; 01007 while (x2) { 01008 int position = BITScanForward(x2); 01009 updateZobristKey(key, 14, position); 01010 x2 &= NOTPOW2[position]; 01011 } 01012 01013 if(rep) { 01014 if (movecapture != SQUARE_FREE || pieceFrom==WHITE || pieceFrom==BLACK || move->type & 0b00001100) 01015 pushStackMove(0); 01016 pushStackMove(*key); 01017 } 01018 } 01019 01020 void GenMoves::init() { 01021 numMoves = numMovesq = 0; 01022 #ifdef DEBUG_MODE 01023 #ifndef NO_FP_MODE 01024 nCutFp = nCutRazor = 0; 01025 #endif 01026 betaEfficency = betaEfficencyCumulative = 0.0; 01027 nCutAB = 0; 01028 nNullMoveCut = 0; 01029 #endif 01030 listId = 0; 01031 } 01032 01033 u64 GenMoves::getTotMoves() { 01034 return numMoves + numMovesq; 01035 } 01036 void GenMoves::setRepetitionMapCount(int i) { 01037 repetitionMapCount=i; 01038 } 01039 01040 int GenMoves::loadFen() { 01041 return loadFen(""); 01042 } 01043 01044 int GenMoves::loadFen(string fen) { 01045 repetitionMapCount=0; 01046 int side= ChessBoard::loadFen(fen); 01047 return side; 01048 } 01049 01050 void GenMoves::makemove(_Tmove * move) { 01051 makemove(move,&zobristKey,true); 01052 } 01053 01054 int GenMoves::getMoveFromSan(const string fenStr,_Tmove* move) { 01055 enpassantPosition=-1; 01056 memset(move,0,sizeof(_Tmove)); 01057 static const string MATCH_QUEENSIDE = "O-O-O e1c1 e8c8"; 01058 static const string MATCH_QUEENSIDE_WHITE = "O-O-O e1c1"; 01059 static const string MATCH_KINGSIDE_WHITE = "O-O e1g1"; 01060 static const string MATCH_QUEENSIDE_BLACK = "O-O-O e8c8"; 01061 static const string MATCH_KINGSIDE_BLACK = "O-O e8g8"; 01062 01063 if ( 01064 ( (MATCH_QUEENSIDE_WHITE.find(fenStr)!=string::npos || MATCH_KINGSIDE_WHITE.find(fenStr)!=string::npos ) && getPieceAt<WHITE>( POW2[E1]) == KING_WHITE) 01065 || 01066 ((MATCH_QUEENSIDE_BLACK.find(fenStr)!=string::npos || MATCH_KINGSIDE_BLACK.find(fenStr)!=string::npos) 01067 && getPieceAt<BLACK>( POW2[E8]) == KING_BLACK) 01068 ) { 01069 if (MATCH_QUEENSIDE.find(fenStr)!=string::npos) { 01070 move->type = QUEEN_SIDE_CASTLE_MOVE_MASK; 01071 move->from = QUEEN_SIDE_CASTLE_MOVE_MASK; 01072 } else { 01073 move->from = KING_SIDE_CASTLE_MOVE_MASK; 01074 move->type = KING_SIDE_CASTLE_MOVE_MASK; 01075 } 01076 if(fenStr.find("1")!=string::npos) { 01077 move->side = WHITE; 01078 01079 } else if(fenStr.find("8")!=string::npos) { 01080 move->side = BLACK; 01081 01082 } else assert(0); 01083 move->from=-1; 01084 move->capturedPiece=SQUARE_FREE; 01085 return move->side; 01086 } 01087 01088 int from=-1; 01089 int to=-1; 01090 for (int i = 0; i < 64; i++) { 01091 if (!fenStr.compare(0,2,BOARD[i])) { 01092 from = i; 01093 break; 01094 } 01095 } 01096 if (from==-1) { 01097 cout << fenStr<<endl; 01098 assert(0); 01099 } 01100 01101 for (int i = 0; i < 64; i++) { 01102 if (!fenStr.compare(2,2,BOARD[i])) { 01103 to = i; 01104 break; 01105 } 01106 } 01107 if (to==-1) { 01108 cout << fenStr<<endl; 01109 assert(0); 01110 } 01111 01112 int pieceFrom; 01113 if ((pieceFrom = getPieceAt<WHITE>( POW2[from])) != 12) { 01114 move->side = WHITE; 01115 } else if ((pieceFrom = getPieceAt<BLACK>( POW2[from])) != 12) { 01116 move->side = BLACK; 01117 } else { 01118 display(); 01119 cout <<"fenStr: "<<fenStr<<" from: "<<from<<endl; 01120 assert(0); 01121 } 01122 move->from = from; 01123 move->to = to; 01124 if (fenStr.length() == 4) { 01125 move->type = STANDARD_MOVE_MASK; 01126 if (pieceFrom == PAWN_WHITE || pieceFrom == PAWN_BLACK) { 01127 if (FILE_AT[from] != FILE_AT[to] && (move->side ^ 1?getPieceAt<WHITE>( POW2[to]):getPieceAt<BLACK>( POW2[to])) == SQUARE_FREE) { 01128 move->type = ENPASSANT_MOVE_MASK; 01129 } 01130 } 01131 } else if (fenStr.length() == 5) { 01132 move->type = PROMOTION_MOVE_MASK; 01133 if (move->side == WHITE) 01134 move->promotionPiece = INV_FEN[toupper(fenStr.at(4))]; 01135 else 01136 move->promotionPiece = INV_FEN[(uchar)fenStr.at(4)]; 01137 ASSERT(move->promotionPiece != 0xFF); 01138 } 01139 if(move->side==WHITE) { 01140 move->capturedPiece=getPieceAt<BLACK>( POW2[move->to]); 01141 move->pieceFrom=getPieceAt<WHITE>( POW2[move->from]); 01142 } else { 01143 move->capturedPiece=getPieceAt<WHITE>( POW2[move->to]); 01144 move->pieceFrom=getPieceAt<BLACK>( POW2[move->from]); 01145 } 01146 return move->side; 01147 }