def make_move(self, mv): cl = self.color half, cast, enp = self.halfmove_clock, self.castle, self.enp self.color = not self.color opp_cl = self.color if cl == 0: self.move_num += 1 self.enp = 0L frsq = move.frsq(mv) tosq = move.tosq(mv) prom = move.promotion(mv) pc = self.clear_square(tosq) mvpc = move.piece(mv) if pc or mvpc == piece.PAWN: self.halfmove_clock = 0 else: self.halfmove_clock += 1 if prom and prom != piece.PAWN and prom != piece.KING: mvpc = prom self.set_square(tosq, mvpc, cl) self.clear_square(frsq) if tosq == self.ROOK_SQUARES[opp_cl][0]: self.castle &= ~castle.QUEEN[opp_cl] elif tosq == self.ROOK_SQUARES[opp_cl][1]: self.castle &= ~castle.KING[opp_cl] if mvpc == piece.KING: self.castle &= ~castle.QUEEN[cl] self.castle &= ~castle.KING[cl] if prom == piece.KING: rfrsq, rtosq = self.CASTLE_SQUARE_MAP[tosq] rook = self.clear_square(rfrsq) self.set_square(rtosq, rook, cl) elif mvpc == piece.ROOK: if frsq == self.ROOK_SQUARES[cl][0]: self.castle &= ~castle.QUEEN[cl] elif frsq == self.ROOK_SQUARES[cl][1]: self.castle &= ~castle.KING[cl] elif mvpc == piece.PAWN: back = square.n(tosq) if opp_cl == 1 else square.s(tosq) if prom == piece.PAWN: self.clear_square(back) else: diff = square.rank(frsq) - square.rank(tosq) if diff == 2 or diff == -2: self.enp = back self.moves.append((mv, pc, half, cast, enp)) return pc
def get_pawn_moves(pos, moves): pawns = pos.piece_bbs[piece.PAWN] & pos.color_bbs[pos.color] not_occ = ~(pos.occupied) enp = pos.enp opp_occ = pos.color_bbs[not pos.color] | enp if pos.color: # single pawn moves regular = pawns & ~square.BIT_RANKS[6] promoting = pawns & square.BIT_RANKS[6] single = bitboard.n(pawns) & not_occ for sq in bitboard.squares(single): moves.append(move.mv(piece.PAWN, square.s(sq), sq)) for sq in bitboard.squares(bitboard.n(promoting) & not_occ): _make_promotions(moves, sq, square.s(sq)) # east attacks for sq in bitboard.squares(bitboard.ne(regular) & opp_occ): prm = piece.PAWN if sq == enp else piece.NONE moves.append(move.mv(piece.PAWN, square.sw(sq), sq, prm)) for sq in bitboard.squares(bitboard.ne(promoting) & opp_occ): _make_promotions(moves, sq, square.sw(sq)) # west attacks for sq in bitboard.squares(bitboard.nw(regular) & opp_occ): prm = piece.PAWN if sq == enp else piece.NONE moves.append(move.mv(piece.PAWN, square.se(sq), sq, prm)) for sq in bitboard.squares(bitboard.nw(promoting) & opp_occ): _make_promotions(moves, sq, square.se(sq)) # double pawn moves doubles = bitboard.n(single & square.BIT_RANKS[2]) for sq in bitboard.squares(doubles & not_occ): moves.append(move.mv(piece.PAWN, square.ss(sq), sq)) else: # single pawn moves regular = pawns & ~square.BIT_RANKS[1] promoting = pawns & square.BIT_RANKS[1] single = bitboard.s(pawns) & not_occ for sq in bitboard.squares(single): moves.append(move.mv(piece.PAWN, square.n(sq), sq)) for sq in bitboard.squares(bitboard.s(promoting) & not_occ): _make_promotions(moves, sq, square.n(sq)) # east attacks for sq in bitboard.squares(bitboard.se(regular) & opp_occ): prm = piece.PAWN if sq == enp else piece.NONE moves.append(move.mv(piece.PAWN, square.nw(sq), sq, prm)) for sq in bitboard.squares(bitboard.se(promoting) & opp_occ): _make_promotions(moves, sq, square.nw(sq)) # west attacks for sq in bitboard.squares(bitboard.sw(regular) & opp_occ): prm = piece.PAWN if sq == enp else piece.NONE moves.append(move.mv(piece.PAWN, square.ne(sq), sq, prm)) for sq in bitboard.squares(bitboard.sw(promoting) & opp_occ): _make_promotions(moves, sq, square.ne(sq)) # double pawn moves doubles = bitboard.s(single & square.BIT_RANKS[5]) for sq in bitboard.squares(doubles & not_occ): moves.append(move.mv(piece.PAWN, square.nn(sq), sq))
def _king_moves(sq): return (square.n(sq) | square.s(sq) | square.e(sq) | square.w(sq) | square.ne(sq) | square.se(sq) | square.sw(sq) | square.nw(sq))