int GenerateWhiteCastle(const BOARD *board, MOVE *poss_moves, int nmoves) { if(board->wk_castle && board->squares[h1] == W_ROOK && board->squares[g1] == EMPTY && board->squares[f1] == EMPTY && !WhiteInCheck(board) && !IsAttacked(board, f1, BLACK)){ if(poss_moves) poss_moves[nmoves] = Move(0, g1, e1); nmoves++; } if(board->wq_castle && board->squares[a1] == W_ROOK &&board->squares[b1] == EMPTY && board->squares[c1] == EMPTY && board->squares[d1] == EMPTY && !WhiteInCheck(board) && !IsAttacked(board, d1, BLACK)){ if(poss_moves) poss_moves[nmoves] = Move(0, c1, e1); nmoves++; } return nmoves; }
int GenerateBlackCastle(const BOARD *board, MOVE *poss_moves, int nmoves) { if(board->bk_castle && board->squares[h8] == B_ROOK &&board->squares[g8] == EMPTY && board->squares[f8] == EMPTY && !BlackInCheck(board) && !IsAttacked(board, f8, WHITE)){ if(poss_moves) poss_moves[nmoves] = Move(0, g8, e8); nmoves++; } if(board->bq_castle && board->squares[a8] == B_ROOK &&board->squares[b8] == EMPTY && board->squares[c8] == EMPTY && board->squares[d8] == EMPTY && !BlackInCheck(board) && !IsAttacked(board, d8, WHITE)){ if(poss_moves) poss_moves[nmoves] = Move(0, c8, e8); nmoves++; } return nmoves; }
bool Position::MakeMove(Move mv) { Undo& undo = _undos[_undoSize++]; undo.m_castlings = m_castlings; undo.m_ep = m_ep; undo.m_fifty = m_fifty; undo.m_hash = m_hash; undo.m_mv = mv; FLD from = mv.From(); FLD to = mv.To(); PIECE piece = mv.Piece(); PIECE captured = mv.Captured(); PIECE promotion = mv.Promotion(); COLOR side = m_side; COLOR opp = side ^ 1; m_hash ^= s_hashSide[1]; ++m_fifty; if (captured) { m_fifty = 0; if (to == m_ep) Remove(to + 8 - 16 * side); else Remove(to); } Remove(from); Put(to, piece); m_ep = NF; switch (piece) { case PW: case PB: m_fifty = 0; if (to - from == -16 + 32 * side) m_ep = to + 8 - 16 * side; else if (promotion) { Remove(to); Put(to, promotion); } break; case KW: m_Kings[WHITE] = to; if (from == E1) { if (to == G1) { Remove(H1); Put(F1, RW); m_castlings ^= WHITE_DID_O_O; } else if (to == C1) { Remove(A1); Put(D1, RW); m_castlings ^= WHITE_DID_O_O_O; } } break; case KB: m_Kings[BLACK] = to; if (from == E8) { if (to == G8) { Remove(H8); Put(F8, RB); m_castlings ^= BLACK_DID_O_O; } else if (to == C8) { Remove(A8); Put(D8, RB); m_castlings ^= BLACK_DID_O_O_O; } } break; default: break; } static const U8 castlingDelta[64] = { 0xf7, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xfe }; m_castlings &= castlingDelta[from]; m_castlings &= castlingDelta[to]; ++m_ply; m_side ^= 1; if (IsAttacked(m_Kings[side], opp)) { UnmakeMove(); return false; } return true; }