From 987ff3b4b6254bc4696a579c15c8e6eeab3425c8 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 19 Oct 2008 08:27:24 +0100 Subject: [PATCH 01/18] Space inflate generate_evasions() Signed-off-by: Marco Costalba --- src/movegen.cpp | 415 +++++++++++++++++++++++++----------------------- 1 file changed, 216 insertions(+), 199 deletions(-) diff --git a/src/movegen.cpp b/src/movegen.cpp index cf938dad..aecf28f4 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -48,20 +48,19 @@ namespace { typedef Bitboard (*Shift_fn)(Bitboard b); Shift_fn forward, forward_left, forward_right; }; - const PawnOffsets WhitePawnOffsets = { Rank3BB, Rank8BB, DELTA_N, DELTA_NE, DELTA_NW, WHITE, - BLACK, &forward_white, forward_left_white, forward_right_white }; - const PawnOffsets BlackPawnOffsets = { Rank6BB, Rank1BB, DELTA_S, DELTA_SE, DELTA_SW, BLACK, - WHITE, &forward_black, &forward_left_black, &forward_right_black }; + const PawnOffsets WhitePawnOffsets = { Rank3BB, Rank8BB, DELTA_N, DELTA_NE, DELTA_NW, WHITE, BLACK, + &forward_white, forward_left_white, forward_right_white }; + + const PawnOffsets BlackPawnOffsets = { Rank6BB, Rank1BB, DELTA_S, DELTA_SE, DELTA_SW, BLACK, WHITE, + &forward_black, &forward_left_black, &forward_right_black }; int generate_pawn_captures(const PawnOffsets&, const Position&, MoveStack*); int generate_pawn_noncaptures(const PawnOffsets&, const Position&, MoveStack*); int generate_pawn_checks(const PawnOffsets&, const Position&, Bitboard dc, Square ksq, MoveStack*, int n); + int generate_piece_checks(PieceType pce, const Position& pos, Bitboard target, Bitboard dc, Square ksq, MoveStack* mlist, int n); int generate_piece_moves(PieceType, const Position&, MoveStack*, Color side, Bitboard t); int generate_castle_moves(const Position&, MoveStack*, Color us); - - int generate_piece_checks(PieceType pce, const Position& pos, Bitboard target, - Bitboard dc, Square ksq, MoveStack* mlist, int n); } @@ -182,235 +181,253 @@ int generate_checks(const Position& pos, MoveStack* mlist, Bitboard dc) { /// only legal moves. It returns the number of generated moves. This /// function is very ugly, and needs cleaning up some time later. FIXME -int generate_evasions(const Position &pos, MoveStack *mlist) { +int generate_evasions(const Position& pos, MoveStack* mlist) { assert(pos.is_ok()); assert(pos.is_check()); - Color us, them; - Bitboard checkers = pos.checkers(); - Bitboard pinned, b1, b2; - Square ksq, from, to; + Color us = pos.side_to_move(); + Color them = opposite_color(us); + Square ksq = pos.king_square(us); + Square from, to; int n = 0; - us = pos.side_to_move(); - them = opposite_color(us); - - ksq = pos.king_square(us); assert(pos.piece_on(ksq) == king_of_color(us)); - // Generate evasions for king: - b1 = pos.king_attacks(ksq) & ~pos.pieces_of_color(us); - b2 = pos.occupied_squares(); + // Generate evasions for king + Bitboard b1 = pos.king_attacks(ksq) & ~pos.pieces_of_color(us); + Bitboard b2 = pos.occupied_squares(); clear_bit(&b2, ksq); - while(b1) { - to = pop_1st_bit(&b1); - // Make sure to is not attacked by the other side. This is a bit ugly, - // because we can't use Position::square_is_attacked. Instead we use + while (b1) + { + Square to = pop_1st_bit(&b1); + + // Make sure to is not attacked by the other side. This is a bit ugly, + // because we can't use Position::square_is_attacked. Instead we use // the low-level bishop_attacks_bb and rook_attacks_bb with the bitboard // b2 (the occupied squares with the king removed) in order to test whether // the king will remain in check on the destination square. - if(((pos.pawn_attacks(us, to) & pos.pawns(them)) == EmptyBoardBB) && - ((pos.knight_attacks(to) & pos.knights(them)) == EmptyBoardBB) && - ((pos.king_attacks(to) & pos.kings(them)) == EmptyBoardBB) && - ((bishop_attacks_bb(to, b2) & pos.bishops_and_queens(them)) - == EmptyBoardBB) && - ((rook_attacks_bb(to, b2) & pos.rooks_and_queens(them)) == EmptyBoardBB)) - mlist[n++].move = make_move(ksq, to); + if (!( (bishop_attacks_bb(to, b2) & pos.bishops_and_queens(them)) + || (rook_attacks_bb(to, b2) & pos.rooks_and_queens(them)) + || (pos.knight_attacks(to) & pos.knights(them)) + || (pos.pawn_attacks(us, to) & pos.pawns(them)) + || (pos.king_attacks(to) & pos.kings(them)))) + + mlist[n++].move = make_move(ksq, to); } - - // Generate evasions for other pieces only if not double check. We use a + // Generate evasions for other pieces only if not double check. We use a // simple bit twiddling hack here rather than calling count_1s in order to // save some time (we know that pos.checkers() has at most two nonzero bits). - if(!(checkers & (checkers - 1))) { - Square checksq = first_1(checkers); - assert(pos.color_of_piece_on(checksq) == them); + Bitboard checkers = pos.checkers(); - // Find pinned pieces: - pinned = pos.pinned_pieces(us); + if (!(checkers & (checkers - 1))) // Only one bit set? + { + Square checksq = first_1(checkers); - // Generate captures of the checking piece: + assert(pos.color_of_piece_on(checksq) == them); - // Pawn captures: - b1 = pos.pawn_attacks(them, checksq) & pos.pawns(us) & ~pinned; - while(b1) { - from = pop_1st_bit(&b1); - if(relative_rank(us, checksq) == RANK_8) { - mlist[n++].move = make_promotion_move(from, checksq, QUEEN); - mlist[n++].move = make_promotion_move(from, checksq, ROOK); - mlist[n++].move = make_promotion_move(from, checksq, BISHOP); - mlist[n++].move = make_promotion_move(from, checksq, KNIGHT); + // Find pinned pieces + Bitboard not_pinned = ~pos.pinned_pieces(us); + + // Generate captures of the checking piece + + // Pawn captures + b1 = pos.pawn_attacks(them, checksq) & pos.pawns(us) & not_pinned; + while (b1) + { + from = pop_1st_bit(&b1); + if (relative_rank(us, checksq) == RANK_8) + { + mlist[n++].move = make_promotion_move(from, checksq, QUEEN); + mlist[n++].move = make_promotion_move(from, checksq, ROOK); + mlist[n++].move = make_promotion_move(from, checksq, BISHOP); + mlist[n++].move = make_promotion_move(from, checksq, KNIGHT); + } else + mlist[n++].move = make_move(from, checksq); } - else - mlist[n++].move = make_move(from, checksq); - } - // Knight captures: - b1 = pos.knight_attacks(checksq) & pos.knights(us) & ~pinned; - while(b1) { - from = pop_1st_bit(&b1); - mlist[n++].move = make_move(from, checksq); - } + // Pieces captures + b1 = pos.knight_attacks(checksq) & pos.knights(us) + & pos.bishop_attacks(checksq) & pos.bishops_and_queens(us) + & pos.rook_attacks(checksq) & pos.rooks_and_queens(us) + & not_pinned; - // Bishop and queen captures: - b1 = pos.bishop_attacks(checksq) & pos.bishops_and_queens(us) - & ~pinned; - while(b1) { - from = pop_1st_bit(&b1); - mlist[n++].move = make_move(from, checksq); - } + while (b1) + { + from = pop_1st_bit(&b1); + mlist[n++].move = make_move(from, checksq); + } - // Rook and queen captures: - b1 = pos.rook_attacks(checksq) & pos.rooks_and_queens(us) - & ~pinned; - while(b1) { - from = pop_1st_bit(&b1); - mlist[n++].move = make_move(from, checksq); - } + // Blocking check evasions are possible only if the checking piece is + // a slider + if (checkers & pos.sliders()) + { + Bitboard blockSquares = squares_between(checksq, ksq); - // Blocking check evasions are possible only if the checking piece is - // a slider: - if(checkers & pos.sliders()) { - Bitboard blockSquares = squares_between(checksq, ksq); - assert((pos.occupied_squares() & blockSquares) == EmptyBoardBB); + assert((pos.occupied_squares() & blockSquares) == EmptyBoardBB); - // Pawn moves. Because a blocking evasion can never be a capture, we - // only generate pawn pushes. As so often, the code for pawns is a bit - // ugly, and uses separate clauses for white and black pawns. :-( - if(us == WHITE) { - // Find non-pinned pawns: - b1 = pos.pawns(WHITE) & ~pinned; + // Pawn moves. Because a blocking evasion can never be a capture, we + // only generate pawn pushes. As so often, the code for pawns is a bit + // ugly, and uses separate clauses for white and black pawns. :-( + if (us == WHITE) + { + // Find non-pinned pawns + b1 = pos.pawns(WHITE) & not_pinned; - // Single pawn pushes. We don't have to AND with empty squares here, - // because the blocking squares will always be empty. - b2 = (b1 << 8) & blockSquares; - while(b2) { - to = pop_1st_bit(&b2); - assert(pos.piece_on(to) == EMPTY); - if(square_rank(to) == RANK_8) { - mlist[n++].move = make_promotion_move(to - DELTA_N, to, QUEEN); - mlist[n++].move = make_promotion_move(to - DELTA_N, to, ROOK); - mlist[n++].move = make_promotion_move(to - DELTA_N, to, BISHOP); - mlist[n++].move = make_promotion_move(to - DELTA_N, to, KNIGHT); + // Single pawn pushes. We don't have to AND with empty squares here, + // because the blocking squares will always be empty. + b2 = (b1 << 8) & blockSquares; + while(b2) + { + to = pop_1st_bit(&b2); + + assert(pos.piece_on(to) == EMPTY); + + if (square_rank(to) == RANK_8) + { + mlist[n++].move = make_promotion_move(to - DELTA_N, to, QUEEN); + mlist[n++].move = make_promotion_move(to - DELTA_N, to, ROOK); + mlist[n++].move = make_promotion_move(to - DELTA_N, to, BISHOP); + mlist[n++].move = make_promotion_move(to - DELTA_N, to, KNIGHT); + } else + mlist[n++].move = make_move(to - DELTA_N, to); + } + + // Double pawn pushes + b2 = (((b1 << 8) & pos.empty_squares() & Rank3BB) << 8) & blockSquares; + while (b2) + { + to = pop_1st_bit(&b2); + + assert(pos.piece_on(to) == EMPTY); + assert(square_rank(to) == RANK_4); + + mlist[n++].move = make_move(to - DELTA_N - DELTA_N, to); + } + } else { // (us == BLACK) + + // Find non-pinned pawns + b1 = pos.pawns(BLACK) & not_pinned; + + // Single pawn pushes. We don't have to AND with empty squares here, + // because the blocking squares will always be empty. + b2 = (b1 >> 8) & blockSquares; + while (b2) + { + to = pop_1st_bit(&b2); + + assert(pos.piece_on(to) == EMPTY); + + if (square_rank(to) == RANK_1) + { + mlist[n++].move = make_promotion_move(to - DELTA_S, to, QUEEN); + mlist[n++].move = make_promotion_move(to - DELTA_S, to, ROOK); + mlist[n++].move = make_promotion_move(to - DELTA_S, to, BISHOP); + mlist[n++].move = make_promotion_move(to - DELTA_S, to, KNIGHT); + } else + mlist[n++].move = make_move(to - DELTA_S, to); + } + + // Double pawn pushes + b2 = (((b1 >> 8) & pos.empty_squares() & Rank6BB) >> 8) & blockSquares; + while (b2) + { + to = pop_1st_bit(&b2); + + assert(pos.piece_on(to) == EMPTY); + assert(square_rank(to) == RANK_5); + + mlist[n++].move = make_move(to - DELTA_S - DELTA_S, to); + } } - else - mlist[n++].move = make_move(to - DELTA_N, to); - } - // Double pawn pushes. - b2 = (((b1 << 8) & pos.empty_squares() & Rank3BB) << 8) & blockSquares; - while(b2) { - to = pop_1st_bit(&b2); - assert(pos.piece_on(to) == EMPTY); - assert(square_rank(to) == RANK_4); - mlist[n++].move = make_move(to - DELTA_N - DELTA_N, to); - } - } - else { // (us == BLACK) - // Find non-pinned pawns: - b1 = pos.pawns(BLACK) & ~pinned; - // Single pawn pushes. We don't have to AND with empty squares here, - // because the blocking squares will always be empty. - b2 = (b1 >> 8) & blockSquares; - while(b2) { - to = pop_1st_bit(&b2); - assert(pos.piece_on(to) == EMPTY); - if(square_rank(to) == RANK_1) { - mlist[n++].move = make_promotion_move(to - DELTA_S, to, QUEEN); - mlist[n++].move = make_promotion_move(to - DELTA_S, to, ROOK); - mlist[n++].move = make_promotion_move(to - DELTA_S, to, BISHOP); - mlist[n++].move = make_promotion_move(to - DELTA_S, to, KNIGHT); + // Knight moves + b1 = pos.knights(us) & not_pinned; + while (b1) + { + from = pop_1st_bit(&b1); + b2 = pos.knight_attacks(from) & blockSquares; + while (b2) + { + to = pop_1st_bit(&b2); + mlist[n++].move = make_move(from, to); + } + } + + // Bishop moves + b1 = pos.bishops(us) & not_pinned; + while (b1) + { + from = pop_1st_bit(&b1); + b2 = pos.bishop_attacks(from) & blockSquares; + while (b2) + { + to = pop_1st_bit(&b2); + mlist[n++].move = make_move(from, to); + } + } + + // Rook moves + b1 = pos.rooks(us) & not_pinned; + while (b1) + { + from = pop_1st_bit(&b1); + b2 = pos.rook_attacks(from) & blockSquares; + while (b2) + { + to = pop_1st_bit(&b2); + mlist[n++].move = make_move(from, to); + } + } + + // Queen moves + b1 = pos.queens(us) & not_pinned; + while (b1) + { + from = pop_1st_bit(&b1); + b2 = pos.queen_attacks(from) & blockSquares; + while (b2) + { + to = pop_1st_bit(&b2); + mlist[n++].move = make_move(from, to); + } } - else - mlist[n++].move = make_move(to - DELTA_S, to); - } - // Double pawn pushes. - b2 = (((b1 >> 8) & pos.empty_squares() & Rank6BB) >> 8) & blockSquares; - while(b2) { - to = pop_1st_bit(&b2); - assert(pos.piece_on(to) == EMPTY); - assert(square_rank(to) == RANK_5); - mlist[n++].move = make_move(to - DELTA_S - DELTA_S, to); - } - } - - // Knight moves - b1 = pos.knights(us) & ~pinned; - while(b1) { - from = pop_1st_bit(&b1); - b2 = pos.knight_attacks(from) & blockSquares; - while(b2) { - to = pop_1st_bit(&b2); - mlist[n++].move = make_move(from, to); - } - } - - // Bishop moves - b1 = pos.bishops(us) & ~pinned; - while(b1) { - from = pop_1st_bit(&b1); - b2 = pos.bishop_attacks(from) & blockSquares; - while(b2) { - to = pop_1st_bit(&b2); - mlist[n++].move = make_move(from, to); - } - } - - // Rook moves - b1 = pos.rooks(us) & ~pinned; - while(b1) { - from = pop_1st_bit(&b1); - b2 = pos.rook_attacks(from) & blockSquares; - while(b2) { - to = pop_1st_bit(&b2); - mlist[n++].move = make_move(from, to); - } - } - - // Queen moves - b1 = pos.queens(us) & ~pinned; - while(b1) { - from = pop_1st_bit(&b1); - b2 = pos.queen_attacks(from) & blockSquares; - while(b2) { - to = pop_1st_bit(&b2); - mlist[n++].move = make_move(from, to); - } - } } - // Finally, the ugly special case of en passant captures. An en passant + // Finally, the ugly special case of en passant captures. An en passant // capture can only be a check evasion if the check is not a discovered - // check. If pos.ep_square() is set, the last move made must have been - // a double pawn push. If, furthermore, the checking piece is a pawn, + // check. If pos.ep_square() is set, the last move made must have been + // a double pawn push. If, furthermore, the checking piece is a pawn, // an en passant check evasion may be possible. - if(pos.ep_square() != SQ_NONE && (checkers & pos.pawns(them))) { - to = pos.ep_square(); - b1 = pos.pawn_attacks(them, to) & pos.pawns(us); - assert(b1 != EmptyBoardBB); - b1 &= ~pinned; - while(b1) { - from = pop_1st_bit(&b1); + if (pos.ep_square() != SQ_NONE && (checkers & pos.pawns(them))) + { + to = pos.ep_square(); + b1 = pos.pawn_attacks(them, to) & pos.pawns(us); - // Before generating the move, we have to make sure it is legal. - // This is somewhat tricky, because the two disappearing pawns may - // cause new "discovered checks". We test this by removing the - // two relevant bits from the occupied squares bitboard, and using - // the low-level bitboard functions for bishop and rook attacks. - b2 = pos.occupied_squares(); - clear_bit(&b2, from); - clear_bit(&b2, checksq); - if(((bishop_attacks_bb(ksq, b2) & pos.bishops_and_queens(them)) - == EmptyBoardBB) && - ((rook_attacks_bb(ksq, b2) & pos.rooks_and_queens(them)) - == EmptyBoardBB)) - mlist[n++].move = make_ep_move(from, to); - } + assert(b1 != EmptyBoardBB); + + b1 &= not_pinned; + while (b1) + { + from = pop_1st_bit(&b1); + + // Before generating the move, we have to make sure it is legal. + // This is somewhat tricky, because the two disappearing pawns may + // cause new "discovered checks". We test this by removing the + // two relevant bits from the occupied squares bitboard, and using + // the low-level bitboard functions for bishop and rook attacks. + b2 = pos.occupied_squares(); + clear_bit(&b2, from); + clear_bit(&b2, checksq); + if (!( (bishop_attacks_bb(ksq, b2) & pos.bishops_and_queens(them)) + ||(rook_attacks_bb(ksq, b2) & pos.rooks_and_queens(them)))) + + mlist[n++].move = make_ep_move(from, to); + } } } - return n; } From 84ce43498a1e4cc3a963950d5b5de3c6eaaefc1c Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 19 Oct 2008 08:49:26 +0100 Subject: [PATCH 02/18] Introduce generate_piece_blocking_evasions() Start to simplify generate_evasions Signed-off-by: Marco Costalba --- src/movegen.cpp | 87 +++++++++++++++++++++---------------------------- 1 file changed, 37 insertions(+), 50 deletions(-) diff --git a/src/movegen.cpp b/src/movegen.cpp index aecf28f4..63ac4029 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -57,10 +57,11 @@ namespace { int generate_pawn_captures(const PawnOffsets&, const Position&, MoveStack*); int generate_pawn_noncaptures(const PawnOffsets&, const Position&, MoveStack*); - int generate_pawn_checks(const PawnOffsets&, const Position&, Bitboard dc, Square ksq, MoveStack*, int n); - int generate_piece_checks(PieceType pce, const Position& pos, Bitboard target, Bitboard dc, Square ksq, MoveStack* mlist, int n); - int generate_piece_moves(PieceType, const Position&, MoveStack*, Color side, Bitboard t); - int generate_castle_moves(const Position&, MoveStack*, Color us); + int generate_pawn_checks(const PawnOffsets&, const Position&, Bitboard, Square, MoveStack*, int); + int generate_piece_checks(PieceType, const Position&, Bitboard, Bitboard, Square, MoveStack*, int); + int generate_piece_moves(PieceType, const Position&, MoveStack*, Color, Bitboard); + int generate_castle_moves(const Position&, MoveStack*, Color); + int generate_piece_blocking_evasions(PieceType, const Position&, Bitboard, Bitboard, MoveStack*, int); } @@ -249,9 +250,9 @@ int generate_evasions(const Position& pos, MoveStack* mlist) { } // Pieces captures - b1 = pos.knight_attacks(checksq) & pos.knights(us) - & pos.bishop_attacks(checksq) & pos.bishops_and_queens(us) - & pos.rook_attacks(checksq) & pos.rooks_and_queens(us) + b1 = (pos.knight_attacks(checksq) & pos.knights(us)) + | (pos.bishop_attacks(checksq) & pos.bishops_and_queens(us)) + | (pos.rook_attacks(checksq) & pos.rooks_and_queens(us)) & not_pinned; while (b1) @@ -343,57 +344,24 @@ int generate_evasions(const Position& pos, MoveStack* mlist) { } } - // Knight moves + // Pieces moves b1 = pos.knights(us) & not_pinned; - while (b1) - { - from = pop_1st_bit(&b1); - b2 = pos.knight_attacks(from) & blockSquares; - while (b2) - { - to = pop_1st_bit(&b2); - mlist[n++].move = make_move(from, to); - } - } - - // Bishop moves + if (b1) + n = generate_piece_blocking_evasions(KNIGHT, pos, b1, blockSquares, mlist, n); + b1 = pos.bishops(us) & not_pinned; - while (b1) - { - from = pop_1st_bit(&b1); - b2 = pos.bishop_attacks(from) & blockSquares; - while (b2) - { - to = pop_1st_bit(&b2); - mlist[n++].move = make_move(from, to); - } - } + if (b1) + n = generate_piece_blocking_evasions(BISHOP, pos, b1, blockSquares, mlist, n); // Rook moves b1 = pos.rooks(us) & not_pinned; - while (b1) - { - from = pop_1st_bit(&b1); - b2 = pos.rook_attacks(from) & blockSquares; - while (b2) - { - to = pop_1st_bit(&b2); - mlist[n++].move = make_move(from, to); - } - } + if (b1) + n = generate_piece_blocking_evasions(ROOK, pos, b1, blockSquares, mlist, n); // Queen moves b1 = pos.queens(us) & not_pinned; - while (b1) - { - from = pop_1st_bit(&b1); - b2 = pos.queen_attacks(from) & blockSquares; - while (b2) - { - to = pop_1st_bit(&b2); - mlist[n++].move = make_move(from, to); - } - } + if (b1) + n = generate_piece_blocking_evasions(QUEEN, pos, b1, blockSquares, mlist, n); } // Finally, the ugly special case of en passant captures. An en passant @@ -940,4 +908,23 @@ namespace { } return n; } + + + int generate_piece_blocking_evasions(PieceType pce, const Position& pos, Bitboard b, + Bitboard blockSquares, MoveStack* mlist, int n) { + + const Piece_attacks_fn mem_fn = piece_attacks_fn[pce]; + + while (b) + { + Square from = pop_1st_bit(&b); + Bitboard bb = (pos.*mem_fn)(from) & blockSquares; + while (bb) + { + Square to = pop_1st_bit(&bb); + mlist[n++].move = make_move(from, to); + } + } + return n; + } } From f2ead1004a4c16302139be7d5ccdf19eb1a3cd1c Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 19 Oct 2008 09:33:33 +0100 Subject: [PATCH 03/18] Final semplification of generate_evasions() Now it's readable! Signed-off-by: Marco Costalba --- src/movegen.cpp | 128 +++++++++++++++++++----------------------------- 1 file changed, 50 insertions(+), 78 deletions(-) diff --git a/src/movegen.cpp b/src/movegen.cpp index 63ac4029..d942d9c2 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -43,16 +43,17 @@ namespace { struct PawnOffsets { Bitboard Rank3BB, Rank8BB; + Rank RANK_8; SquareDelta DELTA_N, DELTA_NE, DELTA_NW; Color us, them; typedef Bitboard (*Shift_fn)(Bitboard b); Shift_fn forward, forward_left, forward_right; }; - const PawnOffsets WhitePawnOffsets = { Rank3BB, Rank8BB, DELTA_N, DELTA_NE, DELTA_NW, WHITE, BLACK, + const PawnOffsets WhitePawnOffsets = { Rank3BB, Rank8BB, RANK_8, DELTA_N, DELTA_NE, DELTA_NW, WHITE, BLACK, &forward_white, forward_left_white, forward_right_white }; - const PawnOffsets BlackPawnOffsets = { Rank6BB, Rank1BB, DELTA_S, DELTA_SE, DELTA_SW, BLACK, WHITE, + const PawnOffsets BlackPawnOffsets = { Rank6BB, Rank1BB, RANK_1, DELTA_S, DELTA_SE, DELTA_SW, BLACK, WHITE, &forward_black, &forward_left_black, &forward_right_black }; int generate_pawn_captures(const PawnOffsets&, const Position&, MoveStack*); @@ -62,6 +63,7 @@ namespace { int generate_piece_moves(PieceType, const Position&, MoveStack*, Color, Bitboard); int generate_castle_moves(const Position&, MoveStack*, Color); int generate_piece_blocking_evasions(PieceType, const Position&, Bitboard, Bitboard, MoveStack*, int); + int generate_pawn_blocking_evasions(const PawnOffsets&, const Position&, Bitboard, Bitboard, MoveStack*, int); } @@ -270,79 +272,11 @@ int generate_evasions(const Position& pos, MoveStack* mlist) { assert((pos.occupied_squares() & blockSquares) == EmptyBoardBB); // Pawn moves. Because a blocking evasion can never be a capture, we - // only generate pawn pushes. As so often, the code for pawns is a bit - // ugly, and uses separate clauses for white and black pawns. :-( + // only generate pawn pushes. if (us == WHITE) - { - // Find non-pinned pawns - b1 = pos.pawns(WHITE) & not_pinned; - - // Single pawn pushes. We don't have to AND with empty squares here, - // because the blocking squares will always be empty. - b2 = (b1 << 8) & blockSquares; - while(b2) - { - to = pop_1st_bit(&b2); - - assert(pos.piece_on(to) == EMPTY); - - if (square_rank(to) == RANK_8) - { - mlist[n++].move = make_promotion_move(to - DELTA_N, to, QUEEN); - mlist[n++].move = make_promotion_move(to - DELTA_N, to, ROOK); - mlist[n++].move = make_promotion_move(to - DELTA_N, to, BISHOP); - mlist[n++].move = make_promotion_move(to - DELTA_N, to, KNIGHT); - } else - mlist[n++].move = make_move(to - DELTA_N, to); - } - - // Double pawn pushes - b2 = (((b1 << 8) & pos.empty_squares() & Rank3BB) << 8) & blockSquares; - while (b2) - { - to = pop_1st_bit(&b2); - - assert(pos.piece_on(to) == EMPTY); - assert(square_rank(to) == RANK_4); - - mlist[n++].move = make_move(to - DELTA_N - DELTA_N, to); - } - } else { // (us == BLACK) - - // Find non-pinned pawns - b1 = pos.pawns(BLACK) & not_pinned; - - // Single pawn pushes. We don't have to AND with empty squares here, - // because the blocking squares will always be empty. - b2 = (b1 >> 8) & blockSquares; - while (b2) - { - to = pop_1st_bit(&b2); - - assert(pos.piece_on(to) == EMPTY); - - if (square_rank(to) == RANK_1) - { - mlist[n++].move = make_promotion_move(to - DELTA_S, to, QUEEN); - mlist[n++].move = make_promotion_move(to - DELTA_S, to, ROOK); - mlist[n++].move = make_promotion_move(to - DELTA_S, to, BISHOP); - mlist[n++].move = make_promotion_move(to - DELTA_S, to, KNIGHT); - } else - mlist[n++].move = make_move(to - DELTA_S, to); - } - - // Double pawn pushes - b2 = (((b1 >> 8) & pos.empty_squares() & Rank6BB) >> 8) & blockSquares; - while (b2) - { - to = pop_1st_bit(&b2); - - assert(pos.piece_on(to) == EMPTY); - assert(square_rank(to) == RANK_5); - - mlist[n++].move = make_move(to - DELTA_S - DELTA_S, to); - } - } + n = generate_pawn_blocking_evasions(WhitePawnOffsets, pos, not_pinned, blockSquares, mlist, n); + else + n = generate_pawn_blocking_evasions(BlackPawnOffsets, pos, not_pinned, blockSquares, mlist, n); // Pieces moves b1 = pos.knights(us) & not_pinned; @@ -352,13 +286,11 @@ int generate_evasions(const Position& pos, MoveStack* mlist) { b1 = pos.bishops(us) & not_pinned; if (b1) n = generate_piece_blocking_evasions(BISHOP, pos, b1, blockSquares, mlist, n); - - // Rook moves + b1 = pos.rooks(us) & not_pinned; if (b1) n = generate_piece_blocking_evasions(ROOK, pos, b1, blockSquares, mlist, n); - - // Queen moves + b1 = pos.queens(us) & not_pinned; if (b1) n = generate_piece_blocking_evasions(QUEEN, pos, b1, blockSquares, mlist, n); @@ -927,4 +859,44 @@ namespace { } return n; } + + + int generate_pawn_blocking_evasions(const PawnOffsets& ofs, const Position& pos, Bitboard not_pinned, + Bitboard blockSquares, MoveStack* mlist, int n) { + // Find non-pinned pawns + Bitboard b1 = pos.pawns(ofs.us) & not_pinned; + + // Single pawn pushes. We don't have to AND with empty squares here, + // because the blocking squares will always be empty. + Bitboard b2 = (ofs.forward)(b1) & blockSquares; + while (b2) + { + Square to = pop_1st_bit(&b2); + + assert(pos.piece_on(to) == EMPTY); + + if (square_rank(to) == ofs.RANK_8) + { + mlist[n++].move = make_promotion_move(to - ofs.DELTA_N, to, QUEEN); + mlist[n++].move = make_promotion_move(to - ofs.DELTA_N, to, ROOK); + mlist[n++].move = make_promotion_move(to - ofs.DELTA_N, to, BISHOP); + mlist[n++].move = make_promotion_move(to - ofs.DELTA_N, to, KNIGHT); + } else + mlist[n++].move = make_move(to - ofs.DELTA_N, to); + } + + // Double pawn pushes + b2 = (ofs.forward)((ofs.forward)(b1) & pos.empty_squares() & ofs.Rank3BB) & blockSquares; + while (b2) + { + Square to = pop_1st_bit(&b2); + + assert(pos.piece_on(to) == EMPTY); + assert(ofs.us != WHITE || square_rank(to) == RANK_4); + assert(ofs.us != BLACK || square_rank(to) == RANK_5); + + mlist[n++].move = make_move(to - ofs.DELTA_N - ofs.DELTA_N, to); + } + return n; + } } From 00bcc6478737caae740dbf511d3587b9332ad2e6 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 19 Oct 2008 10:17:17 +0100 Subject: [PATCH 04/18] Fix an assert due to a missing parentesis Bitwise operators precedence issue here, was causing an assert. This is a fallout from recent patches. Signed-off-by: Marco Costalba --- src/movegen.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/movegen.cpp b/src/movegen.cpp index d942d9c2..0646c230 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -252,10 +252,9 @@ int generate_evasions(const Position& pos, MoveStack* mlist) { } // Pieces captures - b1 = (pos.knight_attacks(checksq) & pos.knights(us)) - | (pos.bishop_attacks(checksq) & pos.bishops_and_queens(us)) - | (pos.rook_attacks(checksq) & pos.rooks_and_queens(us)) - & not_pinned; + b1 = ( (pos.knight_attacks(checksq) & pos.knights(us)) + | (pos.bishop_attacks(checksq) & pos.bishops_and_queens(us)) + | (pos.rook_attacks(checksq) & pos.rooks_and_queens(us)) ) & not_pinned; while (b1) { From 11910d44e0b45ac3036cfd5396cddf864dd753a0 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 19 Oct 2008 10:41:24 +0100 Subject: [PATCH 05/18] Position::is_ok()give more info on failed test Signed-off-by: Marco Costalba --- src/position.cpp | 22 ++++++++++++++++++++-- src/position.h | 2 +- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/position.cpp b/src/position.cpp index 6de3f08c..ba57657e 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -2116,7 +2116,7 @@ void Position::flipped_copy(const Position &pos) { /// Position::is_ok() performs some consitency checks for the position object. /// This is meant to be helpful when debugging. -bool Position::is_ok() const { +bool Position::is_ok(int* failedStep) const { // What features of the position should be verified? static const bool debugBitboards = false; @@ -2131,23 +2131,30 @@ bool Position::is_ok() const { static const bool debugPieceCounts = false; static const bool debugPieceList = false; + if (failedStep) *failedStep = 1; + // Side to move OK? if(!color_is_ok(side_to_move())) return false; // Are the king squares in the position correct? + if (failedStep) (*failedStep)++; if(piece_on(king_square(WHITE)) != WK) return false; + + if (failedStep) (*failedStep)++; if(piece_on(king_square(BLACK)) != BK) return false; // Castle files OK? + if (failedStep) (*failedStep)++; if(!file_is_ok(initialKRFile)) return false; if(!file_is_ok(initialQRFile)) return false; // Do both sides have exactly one king? + if (failedStep) (*failedStep)++; if(debugKingCount) { int kingCount[2] = {0, 0}; for(Square s = SQ_A1; s <= SQ_H8; s++) @@ -2158,6 +2165,7 @@ bool Position::is_ok() const { } // Can the side to move capture the opponent's king? + if (failedStep) (*failedStep)++; if(debugKingCapture) { Color us = side_to_move(); Color them = opposite_color(us); @@ -2167,10 +2175,12 @@ bool Position::is_ok() const { } // Is there more than 2 checkers? + if (failedStep) (*failedStep)++; if(debugCheckerCount && count_1s(checkersBB) > 2) return false; // Bitboards OK? + if (failedStep) (*failedStep)++; if(debugBitboards) { // The intersection of the white and black pieces must be empty: if((pieces_of_color(WHITE) & pieces_of_color(BLACK)) @@ -2191,6 +2201,7 @@ bool Position::is_ok() const { } // En passant square OK? + if (failedStep) (*failedStep)++; if(ep_square() != SQ_NONE) { // The en passant square must be on rank 6, from the point of view of the // side to move. @@ -2199,18 +2210,22 @@ bool Position::is_ok() const { } // Hash key OK? + if (failedStep) (*failedStep)++; if(debugKey && key != compute_key()) return false; // Pawn hash key OK? + if (failedStep) (*failedStep)++; if(debugPawnKey && pawnKey != compute_pawn_key()) return false; // Material hash key OK? + if (failedStep) (*failedStep)++; if(debugMaterialKey && materialKey != compute_material_key()) return false; // Incremental eval OK? + if (failedStep) (*failedStep)++; if(debugIncrementalEval) { if(mgValue != compute_mg_value()) return false; @@ -2219,6 +2234,7 @@ bool Position::is_ok() const { } // Non-pawn material OK? + if (failedStep) (*failedStep)++; if(debugNonPawnMaterial) { if(npMaterial[WHITE] != compute_non_pawn_material(WHITE)) return false; @@ -2227,12 +2243,14 @@ bool Position::is_ok() const { } // Piece counts OK? + if (failedStep) (*failedStep)++; if(debugPieceCounts) for(Color c = WHITE; c <= BLACK; c++) for(PieceType pt = PAWN; pt <= KING; pt++) if(pieceCount[c][pt] != count_1s(pieces_of_color_and_type(c, pt))) return false; + if (failedStep) (*failedStep)++; if(debugPieceList) { for(Color c = WHITE; c <= BLACK; c++) for(PieceType pt = PAWN; pt <= KING; pt++) @@ -2244,6 +2262,6 @@ bool Position::is_ok() const { return false; } } - + if (failedStep) *failedStep = 0; return true; } diff --git a/src/position.h b/src/position.h index 5285c8f9..ca233aa3 100644 --- a/src/position.h +++ b/src/position.h @@ -298,7 +298,7 @@ public: void reset_game_ply(); // Position consistency check, for debugging - bool is_ok() const; + bool is_ok(int* failedStep = NULL) const; // Static member functions: static void init_zobrist(); From 832a8a271907c044fc11f981cf6f923a2a704882 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 19 Oct 2008 11:55:53 +0100 Subject: [PATCH 06/18] Fix a missing comma in BenchmarkPositions[] An old bug introduced in 3e0dc9ee8477 almost one month ago. Signed-off-by: Marco Costalba --- src/benchmark.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/benchmark.cpp b/src/benchmark.cpp index d922c048..9e63b1c9 100644 --- a/src/benchmark.cpp +++ b/src/benchmark.cpp @@ -34,8 +34,8 @@ //// Variables //// -const std::string BenchmarkPositions[16] = { - "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" +const std::string BenchmarkPositions[] = { + "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", "r4rk1/1b2qppp/p1n1p3/1p6/1b1PN3/3BRN2/PP3PPP/R2Q2K1 b - - 7 16", "4r1k1/ppq3pp/3b4/2pP4/2Q1p3/4B1P1/PP5P/R5K1 b - - 0 20", "4rrk1/pp1n3p/3q2pQ/2p1pb2/2PP4/2P3N1/P2B2PP/4RRK1 b - - 7 19", @@ -125,7 +125,7 @@ void benchmark(const std::string& commandLine) { { Move moves[1] = {MOVE_NONE}; int dummy[2] = {0, 0}; - Position pos(*it); + Position pos(*it); think(pos, true, false, 0, dummy, dummy, 0, 0, 0, secsPerPos * 1000, moves); } } From f036239521fe4f6afb7e8cbc51d860ffa476f6bd Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 19 Oct 2008 12:43:09 +0100 Subject: [PATCH 07/18] Prefer template to name decoration This also allows faster code although bigger. Signed-off-by: Marco Costalba --- src/endgame.cpp | 4 +-- src/evaluate.cpp | 18 +++++----- src/movegen.cpp | 88 ++++++++++++++++++++++++++---------------------- src/position.cpp | 67 +++++++++++++++++------------------- src/position.h | 45 ++++++++++++------------- 5 files changed, 111 insertions(+), 111 deletions(-) diff --git a/src/endgame.cpp b/src/endgame.cpp index 7a47a3e1..366a02d1 100644 --- a/src/endgame.cpp +++ b/src/endgame.cpp @@ -489,7 +489,7 @@ ScaleFactor KQKRPScalingFunction::apply(const Position &pos) { relative_rank(weakerSide, pos.king_square(strongerSide)) >= RANK_4 && (pos.rooks(weakerSide) & relative_rank_bb(weakerSide, RANK_3)) && (pos.pawns(weakerSide) & relative_rank_bb(weakerSide, RANK_2)) && - (pos.king_attacks(kingSq) & pos.pawns(weakerSide))) { + (pos.piece_attacks(kingSq) & pos.pawns(weakerSide))) { Square rsq = pos.rook_list(weakerSide, 0); if(pos.pawn_attacks(strongerSide, rsq) & pos.pawns(weakerSide)) return ScaleFactor(0); @@ -732,7 +732,7 @@ ScaleFactor KBPKBScalingFunction::apply(const Position &pos) { ray_bb(pawnSq, (strongerSide == WHITE)? SIGNED_DIR_N : SIGNED_DIR_S); if(ray & pos.kings(weakerSide)) return ScaleFactor(0); - if((pos.bishop_attacks(weakerBishopSq) & ray) + if((pos.piece_attacks(weakerBishopSq) & ray) && square_distance(weakerBishopSq, pawnSq) >= 3) return ScaleFactor(0); } diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 864af221..4bda8466 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -322,8 +322,8 @@ Value evaluate(const Position &pos, EvalInfo &ei, int threadID) { ei.egValue += apply_weight(ei.pi->eg_value(), WeightPawnStructureEndgame); // Initialize king attack bitboards and king attack zones for both sides - ei.attackedBy[WHITE][KING] = pos.king_attacks(pos.king_square(WHITE)); - ei.attackedBy[BLACK][KING] = pos.king_attacks(pos.king_square(BLACK)); + ei.attackedBy[WHITE][KING] = pos.piece_attacks(pos.king_square(WHITE)); + ei.attackedBy[BLACK][KING] = pos.piece_attacks(pos.king_square(BLACK)); ei.kingZone[WHITE] = ei.attackedBy[BLACK][KING] | (ei.attackedBy[BLACK][KING] >> 8); ei.kingZone[BLACK] = ei.attackedBy[WHITE][KING] | (ei.attackedBy[WHITE][KING] << 8); @@ -584,7 +584,7 @@ namespace { void evaluate_knight(const Position &p, Square s, Color us, EvalInfo &ei) { - Bitboard b = p.knight_attacks(s); + Bitboard b = p.piece_attacks(s); ei.attackedBy[us][KNIGHT] |= b; // King attack, mobility and outposts @@ -679,7 +679,7 @@ namespace { void evaluate_queen(const Position &p, Square s, Color us, EvalInfo &ei) { - Bitboard b = p.queen_attacks(s); + Bitboard b = p.piece_attacks(s); ei.attackedBy[us][QUEEN] |= b; // King attack and mobility @@ -772,7 +772,7 @@ namespace { if (QueenContactMates && !p.is_check()) { Bitboard escapeSquares = - p.king_attacks(s) & ~p.pieces_of_color(us) & ~attackedByOthers; + p.piece_attacks(s) & ~p.pieces_of_color(us) & ~attackedByOthers; while (b) { @@ -784,7 +784,7 @@ namespace { for (int i = 0; i < p.queen_count(them); i++) { from = p.queen_list(them, i); - if ( bit_is_set(p.queen_attacks(from), to) + if ( bit_is_set(p.piece_attacks(from), to) && !bit_is_set(p.pinned_pieces(them), from) && !(rook_attacks_bb(to, occ & clear_mask_bb(from)) & p.rooks_and_queens(us)) && !(rook_attacks_bb(to, occ & clear_mask_bb(from)) & p.rooks_and_queens(us))) @@ -817,7 +817,7 @@ namespace { // Analyse safe distance checks: if (QueenCheckBonus > 0 || RookCheckBonus > 0) { - b = p.rook_attacks(s) & ~p.pieces_of_color(them) & ~ei.attacked_by(us); + b = p.piece_attacks(s) & ~p.pieces_of_color(them) & ~ei.attacked_by(us); // Queen checks b2 = b & ei.attacked_by(them, QUEEN); @@ -831,7 +831,7 @@ namespace { } if (QueenCheckBonus > 0 || BishopCheckBonus > 0) { - b = p.bishop_attacks(s) & ~p.pieces_of_color(them) & ~ei.attacked_by(us); + b = p.piece_attacks(s) & ~p.pieces_of_color(them) & ~ei.attacked_by(us); // Queen checks b2 = b & ei.attacked_by(them, QUEEN); @@ -845,7 +845,7 @@ namespace { } if (KnightCheckBonus > 0) { - b = p.knight_attacks(s) & ~p.pieces_of_color(them) & ~ei.attacked_by(us); + b = p.piece_attacks(s) & ~p.pieces_of_color(them) & ~ei.attacked_by(us); // Knight checks b2 = b & ei.attacked_by(them, KNIGHT); diff --git a/src/movegen.cpp b/src/movegen.cpp index 0646c230..259d276b 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -59,11 +59,17 @@ namespace { int generate_pawn_captures(const PawnOffsets&, const Position&, MoveStack*); int generate_pawn_noncaptures(const PawnOffsets&, const Position&, MoveStack*); int generate_pawn_checks(const PawnOffsets&, const Position&, Bitboard, Square, MoveStack*, int); - int generate_piece_checks(PieceType, const Position&, Bitboard, Bitboard, Square, MoveStack*, int); - int generate_piece_moves(PieceType, const Position&, MoveStack*, Color, Bitboard); int generate_castle_moves(const Position&, MoveStack*, Color); - int generate_piece_blocking_evasions(PieceType, const Position&, Bitboard, Bitboard, MoveStack*, int); int generate_pawn_blocking_evasions(const PawnOffsets&, const Position&, Bitboard, Bitboard, MoveStack*, int); + + template + int generate_piece_moves(const Position&, MoveStack*, Color, Bitboard); + + template + int generate_piece_checks(const Position&, Bitboard, Bitboard, Square, MoveStack*, int); + + template + int generate_piece_blocking_evasions(const Position&, Bitboard, Bitboard, MoveStack*, int); } @@ -89,9 +95,11 @@ int generate_captures(const Position& pos, MoveStack* mlist) { else n = generate_pawn_captures(BlackPawnOffsets, pos, mlist); - for (PieceType pce = KNIGHT; pce <= KING; pce++) - n += generate_piece_moves(pce, pos, mlist+n, us, target); - + n += generate_piece_moves(pos, mlist+n, us, target); + n += generate_piece_moves(pos, mlist+n, us, target); + n += generate_piece_moves(pos, mlist+n, us, target); + n += generate_piece_moves(pos, mlist+n, us, target); + n += generate_piece_moves(pos, mlist+n, us, target); return n; } @@ -113,8 +121,11 @@ int generate_noncaptures(const Position& pos, MoveStack *mlist) { else n = generate_pawn_noncaptures(BlackPawnOffsets, pos, mlist); - for (PieceType pce = KNIGHT; pce <= KING; pce++) - n += generate_piece_moves(pce, pos, mlist+n, us, target); + n += generate_piece_moves(pos, mlist+n, us, target); + n += generate_piece_moves(pos, mlist+n, us, target); + n += generate_piece_moves(pos, mlist+n, us, target); + n += generate_piece_moves(pos, mlist+n, us, target); + n += generate_piece_moves(pos, mlist+n, us, target); n += generate_castle_moves(pos, mlist+n, us); return n; @@ -147,25 +158,25 @@ int generate_checks(const Position& pos, MoveStack* mlist, Bitboard dc) { // Pieces moves Bitboard b = pos.knights(us); if (b) - n = generate_piece_checks(KNIGHT, pos, b, dc, ksq, mlist, n); + n = generate_piece_checks(pos, b, dc, ksq, mlist, n); b = pos.bishops(us); if (b) - n = generate_piece_checks(BISHOP, pos, b, dc, ksq, mlist, n); + n = generate_piece_checks(pos, b, dc, ksq, mlist, n); b = pos.rooks(us); if (b) - n = generate_piece_checks(ROOK, pos, b, dc, ksq, mlist, n); + n = generate_piece_checks(pos, b, dc, ksq, mlist, n); b = pos.queens(us); if (b) - n = generate_piece_checks(QUEEN, pos, b, dc, ksq, mlist, n); + n = generate_piece_checks(pos, b, dc, ksq, mlist, n); // King moves Square from = pos.king_square(us); if (bit_is_set(dc, from)) { - b = pos.king_attacks(from) & pos.empty_squares() & ~QueenPseudoAttacks[ksq]; + b = pos.piece_attacks(from) & pos.empty_squares() & ~QueenPseudoAttacks[ksq]; while (b) { Square to = pop_1st_bit(&b); @@ -198,7 +209,7 @@ int generate_evasions(const Position& pos, MoveStack* mlist) { assert(pos.piece_on(ksq) == king_of_color(us)); // Generate evasions for king - Bitboard b1 = pos.king_attacks(ksq) & ~pos.pieces_of_color(us); + Bitboard b1 = pos.piece_attacks(ksq) & ~pos.pieces_of_color(us); Bitboard b2 = pos.occupied_squares(); clear_bit(&b2, ksq); @@ -213,9 +224,9 @@ int generate_evasions(const Position& pos, MoveStack* mlist) { // the king will remain in check on the destination square. if (!( (bishop_attacks_bb(to, b2) & pos.bishops_and_queens(them)) || (rook_attacks_bb(to, b2) & pos.rooks_and_queens(them)) - || (pos.knight_attacks(to) & pos.knights(them)) + || (pos.piece_attacks(to) & pos.knights(them)) || (pos.pawn_attacks(us, to) & pos.pawns(them)) - || (pos.king_attacks(to) & pos.kings(them)))) + || (pos.piece_attacks(to) & pos.kings(them)))) mlist[n++].move = make_move(ksq, to); } @@ -252,9 +263,9 @@ int generate_evasions(const Position& pos, MoveStack* mlist) { } // Pieces captures - b1 = ( (pos.knight_attacks(checksq) & pos.knights(us)) - | (pos.bishop_attacks(checksq) & pos.bishops_and_queens(us)) - | (pos.rook_attacks(checksq) & pos.rooks_and_queens(us)) ) & not_pinned; + b1 = ( (pos.piece_attacks(checksq) & pos.knights(us)) + | (pos.piece_attacks(checksq) & pos.bishops_and_queens(us)) + | (pos.piece_attacks(checksq) & pos.rooks_and_queens(us)) ) & not_pinned; while (b1) { @@ -280,19 +291,19 @@ int generate_evasions(const Position& pos, MoveStack* mlist) { // Pieces moves b1 = pos.knights(us) & not_pinned; if (b1) - n = generate_piece_blocking_evasions(KNIGHT, pos, b1, blockSquares, mlist, n); + n = generate_piece_blocking_evasions(pos, b1, blockSquares, mlist, n); b1 = pos.bishops(us) & not_pinned; if (b1) - n = generate_piece_blocking_evasions(BISHOP, pos, b1, blockSquares, mlist, n); + n = generate_piece_blocking_evasions(pos, b1, blockSquares, mlist, n); b1 = pos.rooks(us) & not_pinned; if (b1) - n = generate_piece_blocking_evasions(ROOK, pos, b1, blockSquares, mlist, n); + n = generate_piece_blocking_evasions(pos, b1, blockSquares, mlist, n); b1 = pos.queens(us) & not_pinned; if (b1) - n = generate_piece_blocking_evasions(QUEEN, pos, b1, blockSquares, mlist, n); + n = generate_piece_blocking_evasions(pos, b1, blockSquares, mlist, n); } // Finally, the ugly special case of en passant captures. An en passant @@ -669,18 +680,18 @@ namespace { } - int generate_piece_moves(PieceType piece, const Position &pos, MoveStack *mlist, + template + int generate_piece_moves(const Position &pos, MoveStack *mlist, Color side, Bitboard target) { - const Piece_attacks_fn mem_fn = piece_attacks_fn[piece]; Square from, to; Bitboard b; int n = 0; - for (int i = 0; i < pos.piece_count(side, piece); i++) + for (int i = 0; i < pos.piece_count(side, Piece); i++) { - from = pos.piece_list(side, piece, i); - b = (pos.*mem_fn)(from) & target; + from = pos.piece_list(side, Piece, i); + b = pos.piece_attacks(from) & target; while (b) { to = pop_1st_bit(&b); @@ -756,17 +767,16 @@ namespace { return n; } - int generate_piece_checks(PieceType pce, const Position& pos, Bitboard target, - Bitboard dc, Square ksq, MoveStack* mlist, int n) { - - const Piece_attacks_fn mem_fn = piece_attacks_fn[pce]; + template + int generate_piece_checks(const Position& pos, Bitboard target, Bitboard dc, + Square ksq, MoveStack* mlist, int n) { // Discovered checks Bitboard b = target & dc; while (b) { Square from = pop_1st_bit(&b); - Bitboard bb = (pos.*mem_fn)(from) & pos.empty_squares(); + Bitboard bb = pos.piece_attacks(from) & pos.empty_squares(); while (bb) { Square to = pop_1st_bit(&bb); @@ -776,11 +786,11 @@ namespace { // Direct checks b = target & ~dc; - Bitboard checkSqs = (pos.*mem_fn)(ksq) & pos.empty_squares(); + Bitboard checkSqs = pos.piece_attacks(ksq) & pos.empty_squares(); while (b) { Square from = pop_1st_bit(&b); - Bitboard bb = (pos.*mem_fn)(from) & checkSqs; + Bitboard bb = pos.piece_attacks(from) & checkSqs; while (bb) { Square to = pop_1st_bit(&bb); @@ -841,15 +851,13 @@ namespace { } - int generate_piece_blocking_evasions(PieceType pce, const Position& pos, Bitboard b, + template + int generate_piece_blocking_evasions(const Position& pos, Bitboard b, Bitboard blockSquares, MoveStack* mlist, int n) { - - const Piece_attacks_fn mem_fn = piece_attacks_fn[pce]; - while (b) { Square from = pop_1st_bit(&b); - Bitboard bb = (pos.*mem_fn)(from) & blockSquares; + Bitboard bb = pos.piece_attacks(from) & blockSquares; while (bb) { Square to = pop_1st_bit(&bb); diff --git a/src/position.cpp b/src/position.cpp index ba57657e..e32f8f49 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -48,13 +48,6 @@ Key Position::zobSideToMove; Value Position::MgPieceSquareTable[16][64]; Value Position::EgPieceSquareTable[16][64]; -const Piece_attacks_fn piece_attacks_fn[] = - { 0, 0, - &Position::knight_attacks, - &Position::bishop_attacks, - &Position::rook_attacks, - &Position::queen_attacks, - &Position::king_attacks }; //// //// Functions @@ -315,7 +308,7 @@ Bitboard Position::pinned_pieces(Color c) const { sliders = rooks_and_queens(them) & ~checkers(); if(sliders & RookPseudoAttacks[ksq]) { - b2 = rook_attacks(ksq) & pieces_of_color(c); + b2 = piece_attacks(ksq) & pieces_of_color(c); pinners = rook_attacks_bb(ksq, b1 ^ b2) & sliders; while(pinners) { s = pop_1st_bit(&pinners); @@ -325,7 +318,7 @@ Bitboard Position::pinned_pieces(Color c) const { sliders = bishops_and_queens(them) & ~checkers(); if(sliders & BishopPseudoAttacks[ksq]) { - b2 = bishop_attacks(ksq) & pieces_of_color(c); + b2 = piece_attacks(ksq) & pieces_of_color(c); pinners = bishop_attacks_bb(ksq, b1 ^ b2) & sliders; while(pinners) { s = pop_1st_bit(&pinners); @@ -350,7 +343,7 @@ Bitboard Position::discovered_check_candidates(Color c) const { sliders = rooks_and_queens(c); if(sliders & RookPseudoAttacks[ksq]) { - b2 = rook_attacks(ksq) & pieces_of_color(c); + b2 = piece_attacks(ksq) & pieces_of_color(c); checkers = rook_attacks_bb(ksq, b1 ^ b2) & sliders; while(checkers) { s = pop_1st_bit(&checkers); @@ -360,7 +353,7 @@ Bitboard Position::discovered_check_candidates(Color c) const { sliders = bishops_and_queens(c); if(sliders & BishopPseudoAttacks[ksq]) { - b2 = bishop_attacks(ksq) & pieces_of_color(c); + b2 = piece_attacks(ksq) & pieces_of_color(c); checkers = bishop_attacks_bb(ksq, b1 ^ b2) & sliders; while(checkers) { s = pop_1st_bit(&checkers); @@ -378,10 +371,10 @@ Bitboard Position::discovered_check_candidates(Color c) const { bool Position::square_is_attacked(Square s, Color c) const { return (pawn_attacks(opposite_color(c), s) & pawns(c)) || - (knight_attacks(s) & knights(c)) || - (king_attacks(s) & kings(c)) || - (rook_attacks(s) & rooks_and_queens(c)) || - (bishop_attacks(s) & bishops_and_queens(c)); + (piece_attacks(s) & knights(c)) || + (piece_attacks(s) & kings(c)) || + (piece_attacks(s) & rooks_and_queens(c)) || + (piece_attacks(s) & bishops_and_queens(c)); } @@ -394,10 +387,10 @@ Bitboard Position::attacks_to(Square s) const { return (black_pawn_attacks(s) & pawns(WHITE)) | (white_pawn_attacks(s) & pawns(BLACK)) | - (knight_attacks(s) & pieces_of_type(KNIGHT)) | - (rook_attacks(s) & rooks_and_queens()) | - (bishop_attacks(s) & bishops_and_queens()) | - (king_attacks(s) & pieces_of_type(KING)); + (piece_attacks(s) & pieces_of_type(KNIGHT)) | + (piece_attacks(s) & rooks_and_queens()) | + (piece_attacks(s) & bishops_and_queens()) | + (piece_attacks(s) & pieces_of_type(KING)); } Bitboard Position::attacks_to(Square s, Color c) const { @@ -588,7 +581,7 @@ bool Position::move_is_check(Move m, Bitboard dcCandidates) const { return true; // Normal check? else - return bit_is_set(knight_attacks(ksq), to); + return bit_is_set(piece_attacks(ksq), to); case BISHOP: // Discovered check? @@ -596,7 +589,7 @@ bool Position::move_is_check(Move m, Bitboard dcCandidates) const { return true; // Normal check? else - return bit_is_set(bishop_attacks(ksq), to); + return bit_is_set(piece_attacks(ksq), to); case ROOK: // Discovered check? @@ -604,13 +597,13 @@ bool Position::move_is_check(Move m, Bitboard dcCandidates) const { return true; // Normal check? else - return bit_is_set(rook_attacks(ksq), to); + return bit_is_set(piece_attacks(ksq), to); case QUEEN: // Discovered checks are impossible! assert(!bit_is_set(dcCandidates, from)); // Normal check? - return bit_is_set(queen_attacks(ksq), to); + return bit_is_set(piece_attacks(ksq), to); case KING: // Discovered check? @@ -889,45 +882,45 @@ void Position::do_move(Move m, UndoInfo &u, Bitboard dcCandidates) { set_bit(&checkersBB, to); if(bit_is_set(dcCandidates, from)) checkersBB |= - ((rook_attacks(ksq) & rooks_and_queens(us)) | - (bishop_attacks(ksq) & bishops_and_queens(us))); + ((piece_attacks(ksq) & rooks_and_queens(us)) | + (piece_attacks(ksq) & bishops_and_queens(us))); break; case KNIGHT: - if(bit_is_set(knight_attacks(ksq), to)) + if(bit_is_set(piece_attacks(ksq), to)) set_bit(&checkersBB, to); if(bit_is_set(dcCandidates, from)) checkersBB |= - ((rook_attacks(ksq) & rooks_and_queens(us)) | - (bishop_attacks(ksq) & bishops_and_queens(us))); + ((piece_attacks(ksq) & rooks_and_queens(us)) | + (piece_attacks(ksq) & bishops_and_queens(us))); break; case BISHOP: - if(bit_is_set(bishop_attacks(ksq), to)) + if(bit_is_set(piece_attacks(ksq), to)) set_bit(&checkersBB, to); if(bit_is_set(dcCandidates, from)) checkersBB |= - (rook_attacks(ksq) & rooks_and_queens(us)); + (piece_attacks(ksq) & rooks_and_queens(us)); break; case ROOK: - if(bit_is_set(rook_attacks(ksq), to)) + if(bit_is_set(piece_attacks(ksq), to)) set_bit(&checkersBB, to); if(bit_is_set(dcCandidates, from)) checkersBB |= - (bishop_attacks(ksq) & bishops_and_queens(us)); + (piece_attacks(ksq) & bishops_and_queens(us)); break; case QUEEN: - if(bit_is_set(queen_attacks(ksq), to)) + if(bit_is_set(piece_attacks(ksq), to)) set_bit(&checkersBB, to); break; case KING: if(bit_is_set(dcCandidates, from)) checkersBB |= - ((rook_attacks(ksq) & rooks_and_queens(us)) | - (bishop_attacks(ksq) & bishops_and_queens(us))); + ((piece_attacks(ksq) & rooks_and_queens(us)) | + (piece_attacks(ksq) & bishops_and_queens(us))); break; default: @@ -1637,8 +1630,8 @@ int Position::see(Square from, Square to) const { attackers = (rook_attacks_bb(to, occ) & rooks_and_queens()) | (bishop_attacks_bb(to, occ) & bishops_and_queens()) | - (knight_attacks(to) & knights()) | - (king_attacks(to) & kings()) | + (piece_attacks(to) & knights()) | + (piece_attacks(to) & kings()) | (white_pawn_attacks(to) & pawns(BLACK)) | (black_pawn_attacks(to) & pawns(WHITE)); attackers &= occ; diff --git a/src/position.h b/src/position.h index ca233aa3..7e5aa866 100644 --- a/src/position.h +++ b/src/position.h @@ -196,11 +196,9 @@ public: Bitboard pawn_attacks(Color c, Square s) const; Bitboard white_pawn_attacks(Square s) const; Bitboard black_pawn_attacks(Square s) const; - Bitboard knight_attacks(Square s) const; - Bitboard bishop_attacks(Square s) const; - Bitboard rook_attacks(Square s) const; - Bitboard queen_attacks(Square s) const; - Bitboard king_attacks(Square s) const; + + template + Bitboard piece_attacks(Square s) const; // Bitboards for pinned pieces and discovered check candidates Bitboard discovered_check_candidates(Color c) const; @@ -370,10 +368,6 @@ private: }; -/// An array of member functions to dispatch attacks_square -typedef Bitboard (Position::* Piece_attacks_fn)(Square s) const; -extern const Piece_attacks_fn piece_attacks_fn[]; - //// //// Inline functions //// @@ -590,23 +584,28 @@ inline Bitboard Position::black_pawn_attacks(Square s) const { return pawn_attacks(BLACK, s); } -inline Bitboard Position::knight_attacks(Square s) const { +template<> +inline Bitboard Position::piece_attacks(Square s) const { return StepAttackBB[KNIGHT][s]; } -inline Bitboard Position::rook_attacks(Square s) const { - return rook_attacks_bb(s, occupied_squares()); -} - -inline Bitboard Position::bishop_attacks(Square s) const { +template<> +inline Bitboard Position::piece_attacks(Square s) const { return bishop_attacks_bb(s, occupied_squares()); } -inline Bitboard Position::queen_attacks(Square s) const { - return rook_attacks(s) | bishop_attacks(s); +template<> +inline Bitboard Position::piece_attacks(Square s) const { + return rook_attacks_bb(s, occupied_squares()); } -inline Bitboard Position::king_attacks(Square s) const { +template<> +inline Bitboard Position::piece_attacks(Square s) const { + return piece_attacks(s) | piece_attacks(s); +} + +template<> +inline Bitboard Position::piece_attacks(Square s) const { return StepAttackBB[KING][s]; } @@ -627,23 +626,23 @@ inline bool Position::black_pawn_attacks_square(Square f, Square t) const { } inline bool Position::knight_attacks_square(Square f, Square t) const { - return bit_is_set(knight_attacks(f), t); + return bit_is_set(piece_attacks(f), t); } inline bool Position::bishop_attacks_square(Square f, Square t) const { - return bit_is_set(bishop_attacks(f), t); + return bit_is_set(piece_attacks(f), t); } inline bool Position::rook_attacks_square(Square f, Square t) const { - return bit_is_set(rook_attacks(f), t); + return bit_is_set(piece_attacks(f), t); } inline bool Position::queen_attacks_square(Square f, Square t) const { - return bit_is_set(queen_attacks(f), t); + return bit_is_set(piece_attacks(f), t); } inline bool Position::king_attacks_square(Square f, Square t) const { - return bit_is_set(king_attacks(f), t); + return bit_is_set(piece_attacks(f), t); } inline bool Position::pawn_is_passed(Color c, Square s) const { From 2bea93975e84f6b8e4d5675c86bbb3f32b17efc4 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 19 Oct 2008 12:53:51 +0100 Subject: [PATCH 08/18] Remove white/black_pawn_attacks() Unuseful syntactic sugar, obfuscates the real code. Signed-off-by: Marco Costalba --- src/position.cpp | 12 ++++++------ src/position.h | 14 ++------------ 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/position.cpp b/src/position.cpp index e32f8f49..200416c7 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -385,8 +385,8 @@ bool Position::square_is_attacked(Square s, Color c) const { Bitboard Position::attacks_to(Square s) const { return - (black_pawn_attacks(s) & pawns(WHITE)) | - (white_pawn_attacks(s) & pawns(BLACK)) | + (pawn_attacks(BLACK, s) & pawns(WHITE)) | + (pawn_attacks(WHITE, s) & pawns(BLACK)) | (piece_attacks(s) & pieces_of_type(KNIGHT)) | (piece_attacks(s) & rooks_and_queens()) | (piece_attacks(s) & bishops_and_queens()) | @@ -847,9 +847,9 @@ void Position::do_move(Move m, UndoInfo &u, Bitboard dcCandidates) { } if(piece == PAWN) { if(abs(int(to) - int(from)) == 16) { - if((us == WHITE && (white_pawn_attacks(from + DELTA_N) & + if((us == WHITE && (pawn_attacks(WHITE, from + DELTA_N) & pawns(BLACK))) || - (us == BLACK && (black_pawn_attacks(from + DELTA_S) & + (us == BLACK && (pawn_attacks(BLACK, from + DELTA_S) & pawns(WHITE)))) { epSquare = Square((int(from) + int(to)) / 2); key ^= zobEp[epSquare]; @@ -1632,8 +1632,8 @@ int Position::see(Square from, Square to) const { (bishop_attacks_bb(to, occ) & bishops_and_queens()) | (piece_attacks(to) & knights()) | (piece_attacks(to) & kings()) | - (white_pawn_attacks(to) & pawns(BLACK)) | - (black_pawn_attacks(to) & pawns(WHITE)); + (pawn_attacks(WHITE, to) & pawns(BLACK)) | + (pawn_attacks(BLACK, to) & pawns(WHITE)); attackers &= occ; // If the opponent has no attackers, we are finished: diff --git a/src/position.h b/src/position.h index 7e5aa866..91e0a5b6 100644 --- a/src/position.h +++ b/src/position.h @@ -194,8 +194,6 @@ public: Bitboard sliding_attacks(Square s, Direction d) const; Bitboard ray_attacks(Square s, SignedDirection d) const; Bitboard pawn_attacks(Color c, Square s) const; - Bitboard white_pawn_attacks(Square s) const; - Bitboard black_pawn_attacks(Square s) const; template Bitboard piece_attacks(Square s) const; @@ -576,14 +574,6 @@ inline Bitboard Position::pawn_attacks(Color c, Square s) const { return StepAttackBB[pawn_of_color(c)][s]; } -inline Bitboard Position::white_pawn_attacks(Square s) const { - return pawn_attacks(WHITE, s); -} - -inline Bitboard Position::black_pawn_attacks(Square s) const { - return pawn_attacks(BLACK, s); -} - template<> inline Bitboard Position::piece_attacks(Square s) const { return StepAttackBB[KNIGHT][s]; @@ -618,11 +608,11 @@ inline bool Position::is_check() const { } inline bool Position::white_pawn_attacks_square(Square f, Square t) const { - return bit_is_set(white_pawn_attacks(f), t); + return bit_is_set(pawn_attacks(WHITE, f), t); } inline bool Position::black_pawn_attacks_square(Square f, Square t) const { - return bit_is_set(black_pawn_attacks(f), t); + return bit_is_set(pawn_attacks(BLACK, f), t); } inline bool Position::knight_attacks_square(Square f, Square t) const { From 305b711ca82344e879a0b8bd135540652cf9a26d Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 19 Oct 2008 13:22:03 +0100 Subject: [PATCH 09/18] Add a generate_piece_checks() specialization for the king Also reshuffle the code a bit. Signed-off-by: Marco Costalba --- src/movegen.cpp | 171 +++++++++++++++++++++++++----------------------- 1 file changed, 89 insertions(+), 82 deletions(-) diff --git a/src/movegen.cpp b/src/movegen.cpp index 259d276b..d8ea0626 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -70,6 +70,93 @@ namespace { template int generate_piece_blocking_evasions(const Position&, Bitboard, Bitboard, MoveStack*, int); + + + /// Templates are defined here to avoid lookup issues with specializations + + template + int generate_piece_moves(const Position &pos, MoveStack *mlist, + Color side, Bitboard target) { + int n = 0; + for (int i = 0; i < pos.piece_count(side, Piece); i++) + { + Square from = pos.piece_list(side, Piece, i); + Bitboard b = pos.piece_attacks(from) & target; + while (b) + { + Square to = pop_1st_bit(&b); + mlist[n++].move = make_move(from, to); + } + } + return n; + } + + + template + int generate_piece_checks(const Position& pos, Bitboard target, Bitboard dc, + Square ksq, MoveStack* mlist, int n) { + // Discovered checks + Bitboard b = target & dc; + while (b) + { + Square from = pop_1st_bit(&b); + Bitboard bb = pos.piece_attacks(from) & pos.empty_squares(); + while (bb) + { + Square to = pop_1st_bit(&bb); + mlist[n++].move = make_move(from, to); + } + } + // Direct checks + b = target & ~dc; + Bitboard checkSqs = pos.piece_attacks(ksq) & pos.empty_squares(); + while (b) + { + Square from = pop_1st_bit(&b); + Bitboard bb = pos.piece_attacks(from) & checkSqs; + while (bb) + { + Square to = pop_1st_bit(&bb); + mlist[n++].move = make_move(from, to); + } + } + return n; + } + + + template<> // Special case the King + int generate_piece_checks(const Position& pos, Bitboard, Bitboard dc, + Square ksq, MoveStack* mlist, int n) { + if (bit_is_set(dc, ksq)) + { + Bitboard bb = pos.piece_attacks(ksq) + & pos.empty_squares() + & ~QueenPseudoAttacks[ksq]; + while (bb) + { + Square to = pop_1st_bit(&bb); + mlist[n++].move = make_move(ksq, to); + } + } + return n; + } + + + template + int generate_piece_blocking_evasions(const Position& pos, Bitboard b, + Bitboard blockSquares, MoveStack* mlist, int n) { + while (b) + { + Square from = pop_1st_bit(&b); + Bitboard bb = pos.piece_attacks(from) & blockSquares; + while (bb) + { + Square to = pop_1st_bit(&bb); + mlist[n++].move = make_move(from, to); + } + } + return n; + } } @@ -172,17 +259,8 @@ int generate_checks(const Position& pos, MoveStack* mlist, Bitboard dc) { if (b) n = generate_piece_checks(pos, b, dc, ksq, mlist, n); - // King moves - Square from = pos.king_square(us); - if (bit_is_set(dc, from)) - { - b = pos.piece_attacks(from) & pos.empty_squares() & ~QueenPseudoAttacks[ksq]; - while (b) - { - Square to = pop_1st_bit(&b); - mlist[n++].move = make_move(from, to); - } - } + // Hopefully we always have a king ;-) + n = generate_piece_checks(pos, b, dc, pos.king_square(us), mlist, n); // TODO: Castling moves! @@ -680,28 +758,6 @@ namespace { } - template - int generate_piece_moves(const Position &pos, MoveStack *mlist, - Color side, Bitboard target) { - - Square from, to; - Bitboard b; - int n = 0; - - for (int i = 0; i < pos.piece_count(side, Piece); i++) - { - from = pos.piece_list(side, Piece, i); - b = pos.piece_attacks(from) & target; - while (b) - { - to = pop_1st_bit(&b); - mlist[n++].move = make_move(from, to); - } - } - return n; - } - - int generate_castle_moves(const Position &pos, MoveStack *mlist, Color us) { int n = 0; @@ -767,38 +823,6 @@ namespace { return n; } - template - int generate_piece_checks(const Position& pos, Bitboard target, Bitboard dc, - Square ksq, MoveStack* mlist, int n) { - - // Discovered checks - Bitboard b = target & dc; - while (b) - { - Square from = pop_1st_bit(&b); - Bitboard bb = pos.piece_attacks(from) & pos.empty_squares(); - while (bb) - { - Square to = pop_1st_bit(&bb); - mlist[n++].move = make_move(from, to); - } - } - - // Direct checks - b = target & ~dc; - Bitboard checkSqs = pos.piece_attacks(ksq) & pos.empty_squares(); - while (b) - { - Square from = pop_1st_bit(&b); - Bitboard bb = pos.piece_attacks(from) & checkSqs; - while (bb) - { - Square to = pop_1st_bit(&bb); - mlist[n++].move = make_move(from, to); - } - } - return n; - } int generate_pawn_checks(const PawnOffsets& ofs, const Position& pos, Bitboard dc, Square ksq, MoveStack* mlist, int n) { @@ -851,23 +875,6 @@ namespace { } - template - int generate_piece_blocking_evasions(const Position& pos, Bitboard b, - Bitboard blockSquares, MoveStack* mlist, int n) { - while (b) - { - Square from = pop_1st_bit(&b); - Bitboard bb = pos.piece_attacks(from) & blockSquares; - while (bb) - { - Square to = pop_1st_bit(&bb); - mlist[n++].move = make_move(from, to); - } - } - return n; - } - - int generate_pawn_blocking_evasions(const PawnOffsets& ofs, const Position& pos, Bitboard not_pinned, Bitboard blockSquares, MoveStack* mlist, int n) { // Find non-pinned pawns From 1eae58523f4fbf77b64d12e9e81a67612708f2f5 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 19 Oct 2008 13:44:25 +0100 Subject: [PATCH 10/18] Remove Position::xxx_list() functions No useful, only obfuscating. Signed-off-by: Marco Costalba --- src/endgame.cpp | 44 ++++++++++++++++++++++---------------------- src/evaluate.cpp | 10 +++++----- src/position.h | 31 +++---------------------------- 3 files changed, 30 insertions(+), 55 deletions(-) diff --git a/src/endgame.cpp b/src/endgame.cpp index 366a02d1..ee8b9179 100644 --- a/src/endgame.cpp +++ b/src/endgame.cpp @@ -247,7 +247,7 @@ Value KBNKEvaluationFunction::apply(const Position &pos) { Square winnerKSq = pos.king_square(strongerSide); Square loserKSq = pos.king_square(weakerSide); - Square bishopSquare = pos.bishop_list(strongerSide, 0); + Square bishopSquare = pos.piece_list(strongerSide, BISHOP, 0); if(square_color(bishopSquare) == BLACK) { winnerKSq = flop_square(winnerKSq); @@ -277,13 +277,13 @@ Value KPKEvaluationFunction::apply(const Position &pos) { if(strongerSide == WHITE) { wksq = pos.king_square(WHITE); bksq = pos.king_square(BLACK); - wpsq = pos.pawn_list(WHITE, 0); + wpsq = pos.piece_list(WHITE, PAWN, 0); stm = pos.side_to_move(); } else { wksq = flip_square(pos.king_square(BLACK)); bksq = flip_square(pos.king_square(WHITE)); - wpsq = flip_square(pos.pawn_list(BLACK, 0)); + wpsq = flip_square(pos.piece_list(BLACK, PAWN, 0)); stm = opposite_color(pos.side_to_move()); } @@ -319,9 +319,9 @@ Value KRKPEvaluationFunction::apply(const Position &pos) { int tempo = (pos.side_to_move() == strongerSide); wksq = pos.king_square(strongerSide); - wrsq = pos.rook_list(strongerSide, 0); + wrsq = pos.piece_list(strongerSide, ROOK, 0); bksq = pos.king_square(weakerSide); - bpsq = pos.pawn_list(weakerSide, 0); + bpsq = pos.piece_list(weakerSide, PAWN, 0); if(strongerSide == BLACK) { wksq = flip_square(wksq); @@ -388,7 +388,7 @@ Value KRKNEvaluationFunction::apply(const Position &pos) { assert(pos.knight_count(weakerSide) == 1); Square defendingKSq = pos.king_square(weakerSide); - Square nSq = pos.knight_list(weakerSide, 0); + Square nSq = pos.piece_list(weakerSide, KNIGHT, 0); Value result = Value(10) + mate_table(defendingKSq) + krkn_king_knight_distance_penalty(square_distance(defendingKSq, nSq)); @@ -434,13 +434,13 @@ ScaleFactor KBPKScalingFunction::apply(const Position &pos) { // be detected even when the weaker side has some pawns. Bitboard pawns = pos.pawns(strongerSide); - File pawnFile = square_file(pos.pawn_list(strongerSide, 0)); + File pawnFile = square_file(pos.piece_list(strongerSide, PAWN, 0)); if((pawnFile == FILE_A || pawnFile == FILE_H) && (pawns & ~file_bb(pawnFile)) == EmptyBoardBB) { // All pawns are on a single rook file. - Square bishopSq = pos.bishop_list(strongerSide, 0); + Square bishopSq = pos.piece_list(strongerSide, BISHOP, 0); Square queeningSq = relative_square(strongerSide, make_square(pawnFile, RANK_8)); Square kingSq = pos.king_square(weakerSide); @@ -490,7 +490,7 @@ ScaleFactor KQKRPScalingFunction::apply(const Position &pos) { (pos.rooks(weakerSide) & relative_rank_bb(weakerSide, RANK_3)) && (pos.pawns(weakerSide) & relative_rank_bb(weakerSide, RANK_2)) && (pos.piece_attacks(kingSq) & pos.pawns(weakerSide))) { - Square rsq = pos.rook_list(weakerSide, 0); + Square rsq = pos.piece_list(weakerSide, ROOK, 0); if(pos.pawn_attacks(strongerSide, rsq) & pos.pawns(weakerSide)) return ScaleFactor(0); } @@ -513,10 +513,10 @@ ScaleFactor KRPKRScalingFunction::apply(const Position &pos) { assert(pos.pawn_count(weakerSide) == 0); Square wksq = pos.king_square(strongerSide); - Square wrsq = pos.rook_list(strongerSide, 0); - Square wpsq = pos.pawn_list(strongerSide, 0); + Square wrsq = pos.piece_list(strongerSide, ROOK, 0); + Square wpsq = pos.piece_list(strongerSide, PAWN, 0); Square bksq = pos.king_square(weakerSide); - Square brsq = pos.rook_list(weakerSide, 0); + Square brsq = pos.piece_list(weakerSide, ROOK, 0); // Orient the board in such a way that the stronger side is white, and the // pawn is on the left half of the board: @@ -617,8 +617,8 @@ ScaleFactor KRPPKRPScalingFunction::apply(const Position &pos) { assert(pos.non_pawn_material(weakerSide) == RookValueMidgame); assert(pos.pawn_count(weakerSide) == 1); - Square wpsq1 = pos.pawn_list(strongerSide, 0); - Square wpsq2 = pos.pawn_list(strongerSide, 1); + Square wpsq1 = pos.piece_list(strongerSide, PAWN, 0); + Square wpsq2 = pos.piece_list(strongerSide, PAWN, 1); Square bksq = pos.king_square(weakerSide); // Does the stronger side have a passed pawn? @@ -700,9 +700,9 @@ ScaleFactor KBPKBScalingFunction::apply(const Position &pos) { assert(pos.bishop_count(weakerSide) == 1); assert(pos.pawn_count(weakerSide) == 0); - Square pawnSq = pos.pawn_list(strongerSide, 0); - Square strongerBishopSq = pos.bishop_list(strongerSide, 0); - Square weakerBishopSq = pos.bishop_list(weakerSide, 0); + Square pawnSq = pos.piece_list(strongerSide, PAWN, 0); + Square strongerBishopSq = pos.piece_list(strongerSide, BISHOP, 0); + Square weakerBishopSq = pos.piece_list(weakerSide, BISHOP, 0); Square weakerKingSq = pos.king_square(weakerSide); // Case 1: Defending king blocks the pawn, and cannot be driven away. @@ -754,8 +754,8 @@ ScaleFactor KBPKNScalingFunction::apply(const Position &pos) { assert(pos.knight_count(weakerSide) == 1); assert(pos.pawn_count(weakerSide) == 0); - Square pawnSq = pos.pawn_list(strongerSide, 0); - Square strongerBishopSq = pos.bishop_list(strongerSide, 0); + Square pawnSq = pos.piece_list(strongerSide, PAWN, 0); + Square strongerBishopSq = pos.piece_list(strongerSide, BISHOP, 0); Square weakerKingSq = pos.king_square(weakerSide); if(square_file(weakerKingSq) == square_file(pawnSq) @@ -779,7 +779,7 @@ ScaleFactor KNPKScalingFunction::apply(const Position &pos) { assert(pos.non_pawn_material(weakerSide) == Value(0)); assert(pos.pawn_count(weakerSide) == 0); - Square pawnSq = pos.pawn_list(strongerSide, 0); + Square pawnSq = pos.piece_list(strongerSide, PAWN, 0); Square weakerKingSq = pos.king_square(weakerSide); if(pawnSq == relative_square(strongerSide, SQ_A7) && @@ -813,13 +813,13 @@ ScaleFactor KPKPScalingFunction::apply(const Position &pos) { if(strongerSide == WHITE) { wksq = pos.king_square(WHITE); bksq = pos.king_square(BLACK); - wpsq = pos.pawn_list(WHITE, 0); + wpsq = pos.piece_list(WHITE, PAWN, 0); stm = pos.side_to_move(); } else { wksq = flip_square(pos.king_square(BLACK)); bksq = flip_square(pos.king_square(WHITE)); - wpsq = flip_square(pos.pawn_list(BLACK, 0)); + wpsq = flip_square(pos.piece_list(BLACK, PAWN, 0)); stm = opposite_color(pos.side_to_move()); } diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 4bda8466..1b333b39 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -338,19 +338,19 @@ Value evaluate(const Position &pos, EvalInfo &ei, int threadID) { { // Knights for (int i = 0; i < pos.knight_count(c); i++) - evaluate_knight(pos, pos.knight_list(c, i), c, ei); + evaluate_knight(pos, pos.piece_list(c, KNIGHT, i), c, ei); // Bishops for (int i = 0; i < pos.bishop_count(c); i++) - evaluate_bishop(pos, pos.bishop_list(c, i), c, ei); + evaluate_bishop(pos, pos.piece_list(c, BISHOP, i), c, ei); // Rooks for (int i = 0; i < pos.rook_count(c); i++) - evaluate_rook(pos, pos.rook_list(c, i), c, ei); + evaluate_rook(pos, pos.piece_list(c, ROOK, i), c, ei); // Queens for(int i = 0; i < pos.queen_count(c); i++) - evaluate_queen(pos, pos.queen_list(c, i), c, ei); + evaluate_queen(pos, pos.piece_list(c, QUEEN, i), c, ei); // Special pattern: trapped bishops on a7/h7/a2/h2 Bitboard b = pos.bishops(c) & MaskA7H7[c]; @@ -783,7 +783,7 @@ namespace { // is an X-ray attack through the queen. for (int i = 0; i < p.queen_count(them); i++) { - from = p.queen_list(them, i); + from = p.piece_list(them, QUEEN, i); if ( bit_is_set(p.piece_attacks(from), to) && !bit_is_set(p.pinned_pieces(them), from) && !(rook_attacks_bb(to, occ & clear_mask_bb(from)) & p.rooks_and_queens(us)) diff --git a/src/position.h b/src/position.h index 91e0a5b6..bf9bba3d 100644 --- a/src/position.h +++ b/src/position.h @@ -205,13 +205,8 @@ public: // Checking pieces Bitboard checkers() const; - // Piece lists: + // Piece lists Square piece_list(Color c, PieceType pt, int index) const; - Square pawn_list(Color c, int index) const; - Square knight_list(Color c, int index) const; - Square bishop_list(Color c, int index) const; - Square rook_list(Color c, int index) const; - Square queen_list(Color c, int index) const; // Attack information for a given square bool square_is_attacked(Square s, Color c) const; @@ -522,26 +517,6 @@ inline Square Position::piece_list(Color c, PieceType pt, int index) const { return pieceList[c][pt][index]; } -inline Square Position::pawn_list(Color c, int index) const { - return piece_list(c, PAWN, index); -} - -inline Square Position::knight_list(Color c, int index) const { - return piece_list(c, KNIGHT, index); -} - -inline Square Position::bishop_list(Color c, int index) const { - return piece_list(c, BISHOP, index); -} - -inline Square Position::rook_list(Color c, int index) const { - return piece_list(c, ROOK, index); -} - -inline Square Position::queen_list(Color c, int index) const { - return piece_list(c, QUEEN, index); -} - inline Square Position::ep_square() const { return epSquare; } @@ -754,8 +729,8 @@ inline int Position::rule_50_counter() const { inline bool Position::opposite_colored_bishops() const { return bishop_count(WHITE) == 1 - && bishop_count(BLACK) == 1 - && square_color(bishop_list(WHITE, 0)) != square_color(bishop_list(BLACK, 0)); + && bishop_count(BLACK) == 1 + && square_color(piece_list(WHITE, BISHOP, 0)) != square_color(piece_list(BLACK, BISHOP, 0)); } inline bool Position::has_pawn_on_7th(Color c) const { From 8b5519a009914b07ad73a71f86dc0e9ff52b99da Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 19 Oct 2008 13:56:57 +0100 Subject: [PATCH 11/18] Templetize Position::xxx_attacks_square() Signed-off-by: Marco Costalba --- src/position.cpp | 22 +++++++++++----------- src/position.h | 32 ++++++++------------------------ 2 files changed, 19 insertions(+), 35 deletions(-) diff --git a/src/position.cpp b/src/position.cpp index 200416c7..e1d05f61 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -408,11 +408,11 @@ bool Position::piece_attacks_square(Square f, Square t) const { switch(piece_on(f)) { case WP: return white_pawn_attacks_square(f, t); case BP: return black_pawn_attacks_square(f, t); - case WN: case BN: return knight_attacks_square(f, t); - case WB: case BB: return bishop_attacks_square(f, t); - case WR: case BR: return rook_attacks_square(f, t); - case WQ: case BQ: return queen_attacks_square(f, t); - case WK: case BK: return king_attacks_square(f, t); + case WN: case BN: return piece_attacks_square(f, t); + case WB: case BB: return piece_attacks_square(f, t); + case WR: case BR: return piece_attacks_square(f, t); + case WQ: case BQ: return piece_attacks_square(f, t); + case WK: case BK: return piece_attacks_square(f, t); default: return false; } @@ -549,7 +549,7 @@ bool Position::move_is_check(Move m, Bitboard dcCandidates) const { switch(move_promotion(m)) { case KNIGHT: - return knight_attacks_square(to, ksq); + return piece_attacks_square(to, ksq); case BISHOP: return bit_is_set(bishop_attacks_bb(to, b), ksq); case ROOK: @@ -670,11 +670,11 @@ bool Position::move_attacks_square(Move m, Square s) const { switch(piece_on(f)) { case WP: return white_pawn_attacks_square(t, s); case BP: return black_pawn_attacks_square(t, s); - case WN: case BN: return knight_attacks_square(t, s); - case WB: case BB: return bishop_attacks_square(t, s); - case WR: case BR: return rook_attacks_square(t, s); - case WQ: case BQ: return queen_attacks_square(t, s); - case WK: case BK: return king_attacks_square(t, s); + case WN: case BN: return piece_attacks_square(t, s); + case WB: case BB: return piece_attacks_square(t, s); + case WR: case BR: return piece_attacks_square(t, s); + case WQ: case BQ: return piece_attacks_square(t, s); + case WK: case BK: return piece_attacks_square(t, s); default: assert(false); } diff --git a/src/position.h b/src/position.h index bf9bba3d..4dcbbf76 100644 --- a/src/position.h +++ b/src/position.h @@ -213,14 +213,13 @@ public: Bitboard attacks_to(Square s) const; Bitboard attacks_to(Square s, Color c) const; bool is_check() const; - bool piece_attacks_square(Square f, Square t) const; bool white_pawn_attacks_square(Square f, Square t) const; bool black_pawn_attacks_square(Square f, Square t) const; - bool knight_attacks_square(Square f, Square t) const; - bool bishop_attacks_square(Square f, Square t) const; - bool rook_attacks_square(Square f, Square t) const; - bool queen_attacks_square(Square f, Square t) const; - bool king_attacks_square(Square f, Square t) const; + + template + Bitboard piece_attacks_square(Square f, Square t) const; // Dispatch at compile-time + + bool piece_attacks_square(Square f, Square t) const; // Dispatch at run-time // Properties of moves bool move_is_legal(Move m) const; @@ -590,24 +589,9 @@ inline bool Position::black_pawn_attacks_square(Square f, Square t) const { return bit_is_set(pawn_attacks(BLACK, f), t); } -inline bool Position::knight_attacks_square(Square f, Square t) const { - return bit_is_set(piece_attacks(f), t); -} - -inline bool Position::bishop_attacks_square(Square f, Square t) const { - return bit_is_set(piece_attacks(f), t); -} - -inline bool Position::rook_attacks_square(Square f, Square t) const { - return bit_is_set(piece_attacks(f), t); -} - -inline bool Position::queen_attacks_square(Square f, Square t) const { - return bit_is_set(piece_attacks(f), t); -} - -inline bool Position::king_attacks_square(Square f, Square t) const { - return bit_is_set(piece_attacks(f), t); +template +Bitboard Position::piece_attacks_square(Square f, Square t) const { + return bit_is_set(piece_attacks(f), t); } inline bool Position::pawn_is_passed(Color c, Square s) const { From 0d194377033c52ff41ff990ddf31950b576ff543 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 19 Oct 2008 14:06:06 +0100 Subject: [PATCH 12/18] Remove white/black_pawn_attacks_square() Signed-off-by: Marco Costalba --- src/position.cpp | 8 ++++---- src/position.h | 11 +++-------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/position.cpp b/src/position.cpp index e1d05f61..99ff223b 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -406,8 +406,8 @@ bool Position::piece_attacks_square(Square f, Square t) const { assert(square_is_ok(t)); switch(piece_on(f)) { - case WP: return white_pawn_attacks_square(f, t); - case BP: return black_pawn_attacks_square(f, t); + case WP: return pawn_attacks_square(WHITE, f, t); + case BP: return pawn_attacks_square(BLACK, f, t); case WN: case BN: return piece_attacks_square(f, t); case WB: case BB: return piece_attacks_square(f, t); case WR: case BR: return piece_attacks_square(f, t); @@ -668,8 +668,8 @@ bool Position::move_attacks_square(Move m, Square s) const { assert(square_is_occupied(f)); switch(piece_on(f)) { - case WP: return white_pawn_attacks_square(t, s); - case BP: return black_pawn_attacks_square(t, s); + case WP: return pawn_attacks_square(WHITE, t, s); + case BP: return pawn_attacks_square(BLACK, t, s); case WN: case BN: return piece_attacks_square(t, s); case WB: case BB: return piece_attacks_square(t, s); case WR: case BR: return piece_attacks_square(t, s); diff --git a/src/position.h b/src/position.h index 4dcbbf76..0099ccd2 100644 --- a/src/position.h +++ b/src/position.h @@ -213,8 +213,7 @@ public: Bitboard attacks_to(Square s) const; Bitboard attacks_to(Square s, Color c) const; bool is_check() const; - bool white_pawn_attacks_square(Square f, Square t) const; - bool black_pawn_attacks_square(Square f, Square t) const; + bool pawn_attacks_square(Color c, Square f, Square t) const; template Bitboard piece_attacks_square(Square f, Square t) const; // Dispatch at compile-time @@ -581,12 +580,8 @@ inline bool Position::is_check() const { return checkers() != EmptyBoardBB; } -inline bool Position::white_pawn_attacks_square(Square f, Square t) const { - return bit_is_set(pawn_attacks(WHITE, f), t); -} - -inline bool Position::black_pawn_attacks_square(Square f, Square t) const { - return bit_is_set(pawn_attacks(BLACK, f), t); +inline bool Position::pawn_attacks_square(Color c, Square f, Square t) const { + return bit_is_set(pawn_attacks(c, f), t); } template From d0e51bc0f0c77f93323aaa86c9c2485c41d38271 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 19 Oct 2008 14:39:29 +0100 Subject: [PATCH 13/18] Remove Positions::xxx_count() functions Signed-off-by: Marco Costalba --- src/endgame.cpp | 90 ++++++++++++++++++++++++------------------------ src/evaluate.cpp | 18 +++++----- src/material.cpp | 44 +++++++++++------------ src/position.h | 29 ++-------------- 4 files changed, 78 insertions(+), 103 deletions(-) diff --git a/src/endgame.cpp b/src/endgame.cpp index ee8b9179..76fb597a 100644 --- a/src/endgame.cpp +++ b/src/endgame.cpp @@ -212,19 +212,19 @@ KPKPScalingFunction::KPKPScalingFunction(Color c) : ScalingFunction(c) { } Value KXKEvaluationFunction::apply(const Position &pos) { assert(pos.non_pawn_material(weakerSide) == Value(0)); - assert(pos.pawn_count(weakerSide) == Value(0)); + assert(pos.piece_count(weakerSide, PAWN) == Value(0)); Square winnerKSq = pos.king_square(strongerSide); Square loserKSq = pos.king_square(weakerSide); Value result = pos.non_pawn_material(strongerSide) + - pos.pawn_count(strongerSide) * PawnValueEndgame + + pos.piece_count(strongerSide, PAWN) * PawnValueEndgame + mate_table(loserKSq) + distance_bonus(square_distance(winnerKSq, loserKSq)); - if(pos.queen_count(strongerSide) > 0 || pos.rook_count(strongerSide) > 0 || - pos.bishop_count(strongerSide) > 1) + if(pos.piece_count(strongerSide, QUEEN) > 0 || pos.piece_count(strongerSide, ROOK) > 0 || + pos.piece_count(strongerSide, BISHOP) > 1) // TODO: check for two equal-colored bishops! result += VALUE_KNOWN_WIN; @@ -238,12 +238,12 @@ Value KXKEvaluationFunction::apply(const Position &pos) { Value KBNKEvaluationFunction::apply(const Position &pos) { assert(pos.non_pawn_material(weakerSide) == Value(0)); - assert(pos.pawn_count(weakerSide) == Value(0)); + assert(pos.piece_count(weakerSide, PAWN) == Value(0)); assert(pos.non_pawn_material(strongerSide) == KnightValueMidgame + BishopValueMidgame); - assert(pos.bishop_count(strongerSide) == 1); - assert(pos.knight_count(strongerSide) == 1); - assert(pos.pawn_count(strongerSide) == 0); + assert(pos.piece_count(strongerSide, BISHOP) == 1); + assert(pos.piece_count(strongerSide, KNIGHT) == 1); + assert(pos.piece_count(strongerSide, PAWN) == 0); Square winnerKSq = pos.king_square(strongerSide); Square loserKSq = pos.king_square(weakerSide); @@ -268,8 +268,8 @@ Value KPKEvaluationFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == Value(0)); assert(pos.non_pawn_material(weakerSide) == Value(0)); - assert(pos.pawn_count(strongerSide) == 1); - assert(pos.pawn_count(weakerSide) == 0); + assert(pos.piece_count(strongerSide, PAWN) == 1); + assert(pos.piece_count(weakerSide, PAWN) == 0); Square wksq, bksq, wpsq; Color stm; @@ -311,9 +311,9 @@ Value KPKEvaluationFunction::apply(const Position &pos) { Value KRKPEvaluationFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == RookValueMidgame); - assert(pos.pawn_count(strongerSide) == 0); + assert(pos.piece_count(strongerSide, PAWN) == 0); assert(pos.non_pawn_material(weakerSide) == 0); - assert(pos.pawn_count(weakerSide) == 1); + assert(pos.piece_count(weakerSide, PAWN) == 1); Square wksq, wrsq, bksq, bpsq; int tempo = (pos.side_to_move() == strongerSide); @@ -366,10 +366,10 @@ Value KRKPEvaluationFunction::apply(const Position &pos) { Value KRKBEvaluationFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == RookValueMidgame); - assert(pos.pawn_count(strongerSide) == 0); + assert(pos.piece_count(strongerSide, PAWN) == 0); assert(pos.non_pawn_material(weakerSide) == BishopValueMidgame); - assert(pos.pawn_count(weakerSide) == 0); - assert(pos.bishop_count(weakerSide) == 1); + assert(pos.piece_count(weakerSide, PAWN) == 0); + assert(pos.piece_count(weakerSide, BISHOP) == 1); Value result = mate_table(pos.king_square(weakerSide)); return (pos.side_to_move() == strongerSide)? result : -result; @@ -382,10 +382,10 @@ Value KRKBEvaluationFunction::apply(const Position &pos) { Value KRKNEvaluationFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == RookValueMidgame); - assert(pos.pawn_count(strongerSide) == 0); + assert(pos.piece_count(strongerSide, PAWN) == 0); assert(pos.non_pawn_material(weakerSide) == KnightValueMidgame); - assert(pos.pawn_count(weakerSide) == 0); - assert(pos.knight_count(weakerSide) == 1); + assert(pos.piece_count(weakerSide, PAWN) == 0); + assert(pos.piece_count(weakerSide, KNIGHT) == 1); Square defendingKSq = pos.king_square(weakerSide); Square nSq = pos.piece_list(weakerSide, KNIGHT, 0); @@ -405,9 +405,9 @@ Value KRKNEvaluationFunction::apply(const Position &pos) { Value KQKREvaluationFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == QueenValueMidgame); - assert(pos.pawn_count(strongerSide) == 0); + assert(pos.piece_count(strongerSide, PAWN) == 0); assert(pos.non_pawn_material(weakerSide) == RookValueMidgame); - assert(pos.pawn_count(weakerSide) == 0); + assert(pos.piece_count(weakerSide, PAWN) == 0); Square winnerKSq = pos.king_square(strongerSide); Square loserKSq = pos.king_square(weakerSide); @@ -427,8 +427,8 @@ Value KQKREvaluationFunction::apply(const Position &pos) { ScaleFactor KBPKScalingFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame); - assert(pos.bishop_count(strongerSide) == 1); - assert(pos.pawn_count(strongerSide) >= 1); + assert(pos.piece_count(strongerSide, BISHOP) == 1); + assert(pos.piece_count(strongerSide, PAWN) >= 1); // No assertions about the material of weakerSide, because we want draws to // be detected even when the weaker side has some pawns. @@ -479,10 +479,10 @@ ScaleFactor KBPKScalingFunction::apply(const Position &pos) { ScaleFactor KQKRPScalingFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == QueenValueMidgame); - assert(pos.queen_count(strongerSide) == 1); - assert(pos.pawn_count(strongerSide) == 0); - assert(pos.rook_count(weakerSide) == 1); - assert(pos.pawn_count(weakerSide) >= 1); + assert(pos.piece_count(strongerSide, QUEEN) == 1); + assert(pos.piece_count(strongerSide, PAWN) == 0); + assert(pos.piece_count(weakerSide, ROOK) == 1); + assert(pos.piece_count(weakerSide, PAWN) >= 1); Square kingSq = pos.king_square(weakerSide); if(relative_rank(weakerSide, kingSq) <= RANK_2 && @@ -508,9 +508,9 @@ ScaleFactor KQKRPScalingFunction::apply(const Position &pos) { ScaleFactor KRPKRScalingFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == RookValueMidgame); - assert(pos.pawn_count(strongerSide) == 1); + assert(pos.piece_count(strongerSide, PAWN) == 1); assert(pos.non_pawn_material(weakerSide) == RookValueMidgame); - assert(pos.pawn_count(weakerSide) == 0); + assert(pos.piece_count(weakerSide, PAWN) == 0); Square wksq = pos.king_square(strongerSide); Square wrsq = pos.piece_list(strongerSide, ROOK, 0); @@ -613,9 +613,9 @@ ScaleFactor KRPKRScalingFunction::apply(const Position &pos) { ScaleFactor KRPPKRPScalingFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == RookValueMidgame); - assert(pos.pawn_count(strongerSide) == 2); + assert(pos.piece_count(strongerSide, PAWN) == 2); assert(pos.non_pawn_material(weakerSide) == RookValueMidgame); - assert(pos.pawn_count(weakerSide) == 1); + assert(pos.piece_count(weakerSide, PAWN) == 1); Square wpsq1 = pos.piece_list(strongerSide, PAWN, 0); Square wpsq2 = pos.piece_list(strongerSide, PAWN, 1); @@ -651,9 +651,9 @@ ScaleFactor KRPPKRPScalingFunction::apply(const Position &pos) { ScaleFactor KPsKScalingFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == Value(0)); - assert(pos.pawn_count(strongerSide) >= 2); + assert(pos.piece_count(strongerSide, PAWN) >= 2); assert(pos.non_pawn_material(weakerSide) == Value(0)); - assert(pos.pawn_count(weakerSide) == 0); + assert(pos.piece_count(weakerSide, PAWN) == 0); Bitboard pawns = pos.pawns(strongerSide); @@ -694,11 +694,11 @@ ScaleFactor KPsKScalingFunction::apply(const Position &pos) { ScaleFactor KBPKBScalingFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame); - assert(pos.bishop_count(strongerSide) == 1); - assert(pos.pawn_count(strongerSide) == 1); + assert(pos.piece_count(strongerSide, BISHOP) == 1); + assert(pos.piece_count(strongerSide, PAWN) == 1); assert(pos.non_pawn_material(weakerSide) == BishopValueMidgame); - assert(pos.bishop_count(weakerSide) == 1); - assert(pos.pawn_count(weakerSide) == 0); + assert(pos.piece_count(weakerSide, BISHOP) == 1); + assert(pos.piece_count(weakerSide, PAWN) == 0); Square pawnSq = pos.piece_list(strongerSide, PAWN, 0); Square strongerBishopSq = pos.piece_list(strongerSide, BISHOP, 0); @@ -748,11 +748,11 @@ ScaleFactor KBPKBScalingFunction::apply(const Position &pos) { ScaleFactor KBPKNScalingFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame); - assert(pos.bishop_count(strongerSide) == 1); - assert(pos.pawn_count(strongerSide) == 1); + assert(pos.piece_count(strongerSide, BISHOP) == 1); + assert(pos.piece_count(strongerSide, PAWN) == 1); assert(pos.non_pawn_material(weakerSide) == KnightValueMidgame); - assert(pos.knight_count(weakerSide) == 1); - assert(pos.pawn_count(weakerSide) == 0); + assert(pos.piece_count(weakerSide, KNIGHT) == 1); + assert(pos.piece_count(weakerSide, PAWN) == 0); Square pawnSq = pos.piece_list(strongerSide, PAWN, 0); Square strongerBishopSq = pos.piece_list(strongerSide, BISHOP, 0); @@ -774,10 +774,10 @@ ScaleFactor KBPKNScalingFunction::apply(const Position &pos) { ScaleFactor KNPKScalingFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == KnightValueMidgame); - assert(pos.knight_count(strongerSide) == 1); - assert(pos.pawn_count(strongerSide) == 1); + assert(pos.piece_count(strongerSide, KNIGHT) == 1); + assert(pos.piece_count(strongerSide, PAWN) == 1); assert(pos.non_pawn_material(weakerSide) == Value(0)); - assert(pos.pawn_count(weakerSide) == 0); + assert(pos.piece_count(weakerSide, PAWN) == 0); Square pawnSq = pos.piece_list(strongerSide, PAWN, 0); Square weakerKingSq = pos.king_square(weakerSide); @@ -804,8 +804,8 @@ ScaleFactor KNPKScalingFunction::apply(const Position &pos) { ScaleFactor KPKPScalingFunction::apply(const Position &pos) { assert(pos.non_pawn_material(strongerSide) == Value(0)); assert(pos.non_pawn_material(weakerSide) == Value(0)); - assert(pos.pawn_count(WHITE) == 1); - assert(pos.pawn_count(BLACK) == 1); + assert(pos.piece_count(WHITE, PAWN) == 1); + assert(pos.piece_count(BLACK, PAWN) == 1); Square wksq, bksq, wpsq; Color stm; diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 1b333b39..30ed0879 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -337,19 +337,19 @@ Value evaluate(const Position &pos, EvalInfo &ei, int threadID) { for (Color c = WHITE; c <= BLACK; c++) { // Knights - for (int i = 0; i < pos.knight_count(c); i++) + for (int i = 0; i < pos.piece_count(c, KNIGHT); i++) evaluate_knight(pos, pos.piece_list(c, KNIGHT, i), c, ei); // Bishops - for (int i = 0; i < pos.bishop_count(c); i++) + for (int i = 0; i < pos.piece_count(c, BISHOP); i++) evaluate_bishop(pos, pos.piece_list(c, BISHOP, i), c, ei); // Rooks - for (int i = 0; i < pos.rook_count(c); i++) + for (int i = 0; i < pos.piece_count(c, ROOK); i++) evaluate_rook(pos, pos.piece_list(c, ROOK, i), c, ei); // Queens - for(int i = 0; i < pos.queen_count(c); i++) + for(int i = 0; i < pos.piece_count(c, QUEEN); i++) evaluate_queen(pos, pos.piece_list(c, QUEEN, i), c, ei); // Special pattern: trapped bishops on a7/h7/a2/h2 @@ -427,7 +427,7 @@ Value evaluate(const Position &pos, EvalInfo &ei, int threadID) { { // Check for KBP vs KB with only a single pawn that is almost // certainly a draw or at least two pawns. - bool one_pawn = (pos.pawn_count(WHITE) + pos.pawn_count(BLACK) == 1); + bool one_pawn = (pos.piece_count(WHITE, PAWN) + pos.piece_count(BLACK, PAWN) == 1); sf = one_pawn ? ScaleFactor(8) : ScaleFactor(32); } else @@ -569,7 +569,7 @@ namespace { if (v && (p.pawn_attacks(them, s) & p.pawns(us))) { bonus += v / 2; - if ( p.knight_count(them) == 0 + if ( p.piece_count(them, KNIGHT) == 0 && (SquaresByColorBB[square_color(s)] & p.bishops(them)) == EmptyBoardBB) bonus += v; } @@ -724,7 +724,7 @@ namespace { // from optimally tuned. Color them = opposite_color(us); - if ( p.queen_count(them) >= 1 + if ( p.piece_count(them, QUEEN) >= 1 && ei.kingAttackersCount[them] >= 2 && p.non_pawn_material(them) >= QueenValueMidgame + RookValueMidgame && ei.kingAdjacentZoneAttacksCount[them]) @@ -781,7 +781,7 @@ namespace { { // We have a mate, unless the queen is pinned or there // is an X-ray attack through the queen. - for (int i = 0; i < p.queen_count(them); i++) + for (int i = 0; i < p.piece_count(them, QUEEN); i++) { from = p.piece_list(them, QUEEN, i); if ( bit_is_set(p.piece_attacks(from), to) @@ -994,7 +994,7 @@ namespace { // value if the other side has a rook or queen. if(square_file(s) == FILE_A || square_file(s) == FILE_H) { if(pos.non_pawn_material(them) == KnightValueMidgame - && pos.knight_count(them) == 1) + && pos.piece_count(them, KNIGHT) == 1) ebonus += ebonus / 4; else if(pos.rooks_and_queens(them)) ebonus -= ebonus / 4; diff --git a/src/material.cpp b/src/material.cpp index 63033d80..2718300d 100644 --- a/src/material.cpp +++ b/src/material.cpp @@ -255,13 +255,13 @@ MaterialInfo *MaterialInfoTable::get_material_info(const Position &pos) { return mi; } else if(pos.non_pawn_material(BLACK) == Value(0) && - pos.pawn_count(BLACK) == 0 && + pos.piece_count(BLACK, PAWN) == 0 && pos.non_pawn_material(WHITE) >= RookValueEndgame) { mi->evaluationFunction = &EvaluateKXK; return mi; } else if(pos.non_pawn_material(WHITE) == Value(0) && - pos.pawn_count(WHITE) == 0 && + pos.piece_count(WHITE, PAWN) == 0 && pos.non_pawn_material(BLACK) >= RookValueEndgame) { mi->evaluationFunction = &EvaluateKKX; return mi; @@ -317,33 +317,33 @@ MaterialInfo *MaterialInfoTable::get_material_info(const Position &pos) { } if(pos.non_pawn_material(WHITE) == BishopValueMidgame && - pos.bishop_count(WHITE) == 1 && pos.pawn_count(WHITE) >= 1) + pos.piece_count(WHITE, BISHOP) == 1 && pos.piece_count(WHITE, PAWN) >= 1) mi->scalingFunction[WHITE] = &ScaleKBPK; if(pos.non_pawn_material(BLACK) == BishopValueMidgame && - pos.bishop_count(BLACK) == 1 && pos.pawn_count(BLACK) >= 1) + pos.piece_count(BLACK, BISHOP) == 1 && pos.piece_count(BLACK, PAWN) >= 1) mi->scalingFunction[BLACK] = &ScaleKKBP; - if(pos.pawn_count(WHITE) == 0 && + if(pos.piece_count(WHITE, PAWN) == 0 && pos.non_pawn_material(WHITE) == QueenValueMidgame && - pos.queen_count(WHITE) == 1 && - pos.rook_count(BLACK) == 1 && pos.pawn_count(BLACK) >= 1) + pos.piece_count(WHITE, QUEEN) == 1 && + pos.piece_count(BLACK, ROOK) == 1 && pos.piece_count(BLACK, PAWN) >= 1) mi->scalingFunction[WHITE] = &ScaleKQKRP; - else if(pos.pawn_count(BLACK) == 0 && + else if(pos.piece_count(BLACK, PAWN) == 0 && pos.non_pawn_material(BLACK) == QueenValueMidgame && - pos.queen_count(BLACK) == 1 && - pos.rook_count(WHITE) == 1 && pos.pawn_count(WHITE) >= 1) + pos.piece_count(BLACK, QUEEN) == 1 && + pos.piece_count(WHITE, ROOK) == 1 && pos.piece_count(WHITE, PAWN) >= 1) mi->scalingFunction[BLACK] = &ScaleKRPKQ; if(pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) == Value(0)) { - if(pos.pawn_count(BLACK) == 0) { - assert(pos.pawn_count(WHITE) >= 2); + if(pos.piece_count(BLACK, PAWN) == 0) { + assert(pos.piece_count(WHITE, PAWN) >= 2); mi->scalingFunction[WHITE] = &ScaleKPsK; } - else if(pos.pawn_count(WHITE) == 0) { - assert(pos.pawn_count(BLACK) >= 2); + else if(pos.piece_count(WHITE, PAWN) == 0) { + assert(pos.piece_count(BLACK, PAWN) >= 2); mi->scalingFunction[BLACK] = &ScaleKKPs; } - else if(pos.pawn_count(WHITE) == 1 && pos.pawn_count(BLACK) == 1) { + else if(pos.piece_count(WHITE, PAWN) == 1 && pos.piece_count(BLACK, PAWN) == 1) { mi->scalingFunction[WHITE] = &ScaleKPKPw; mi->scalingFunction[BLACK] = &ScaleKPKPb; } @@ -358,7 +358,7 @@ MaterialInfo *MaterialInfoTable::get_material_info(const Position &pos) { for(c = WHITE, sign = 1; c <= BLACK; c++, sign = -sign) { // No pawns makes it difficult to win, even with a material advantage: - if(pos.pawn_count(c) == 0 && + if(pos.piece_count(c, PAWN) == 0 && pos.non_pawn_material(c) - pos.non_pawn_material(opposite_color(c)) <= BishopValueMidgame) { if(pos.non_pawn_material(c) == pos.non_pawn_material(opposite_color(c))) @@ -366,7 +366,7 @@ MaterialInfo *MaterialInfoTable::get_material_info(const Position &pos) { else if(pos.non_pawn_material(c) < RookValueMidgame) mi->factor[c] = 0; else { - switch(pos.bishop_count(c)) { + switch(pos.piece_count(c, BISHOP)) { case 2: mi->factor[c] = 32; break; case 1: @@ -378,7 +378,7 @@ MaterialInfo *MaterialInfoTable::get_material_info(const Position &pos) { } // Bishop pair: - if(pos.bishop_count(c) >= 2) { + if(pos.piece_count(c, BISHOP) >= 2) { mgValue += sign * BishopPairMidgameBonus; egValue += sign * BishopPairEndgameBonus; } @@ -387,12 +387,12 @@ MaterialInfo *MaterialInfoTable::get_material_info(const Position &pos) { // formula is taken from Larry Kaufman's paper "The Evaluation of Material // Imbalances in Chess": // http://mywebpages.comcast.net/danheisman/Articles/evaluation_of_material_imbalance.htm - mgValue += sign * Value(pos.knight_count(c)*(pos.pawn_count(c)-5)*16); - egValue += sign * Value(pos.knight_count(c)*(pos.pawn_count(c)-5)*16); + mgValue += sign * Value(pos.piece_count(c, KNIGHT)*(pos.piece_count(c, PAWN)-5)*16); + egValue += sign * Value(pos.piece_count(c, KNIGHT)*(pos.piece_count(c, PAWN)-5)*16); // Redundancy of major pieces, again based on Kaufman's paper: - if(pos.rook_count(c) >= 1) { - Value v = Value((pos.rook_count(c) - 1) * 32 + pos.queen_count(c) * 16); + if(pos.piece_count(c, ROOK) >= 1) { + Value v = Value((pos.piece_count(c, ROOK) - 1) * 32 + pos.piece_count(c, QUEEN) * 16); mgValue -= sign * v; egValue -= sign * v; } diff --git a/src/position.h b/src/position.h index 0099ccd2..af1ba775 100644 --- a/src/position.h +++ b/src/position.h @@ -171,11 +171,6 @@ public: // Number of pieces of each color and type int piece_count(Color c, PieceType pt) const; - int pawn_count(Color c) const; - int knight_count(Color c) const; - int bishop_count(Color c) const; - int rook_count(Color c) const; - int queen_count(Color c) const; // The en passant square: Square ep_square() const; @@ -491,26 +486,6 @@ inline int Position::piece_count(Color c, PieceType pt) const { return pieceCount[c][pt]; } -inline int Position::pawn_count(Color c) const { - return piece_count(c, PAWN); -} - -inline int Position::knight_count(Color c) const { - return piece_count(c, KNIGHT); -} - -inline int Position::bishop_count(Color c) const { - return piece_count(c, BISHOP); -} - -inline int Position::rook_count(Color c) const { - return piece_count(c, ROOK); -} - -inline int Position::queen_count(Color c) const { - return piece_count(c, QUEEN); -} - inline Square Position::piece_list(Color c, PieceType pt, int index) const { return pieceList[c][pt][index]; } @@ -707,8 +682,8 @@ inline int Position::rule_50_counter() const { inline bool Position::opposite_colored_bishops() const { - return bishop_count(WHITE) == 1 - && bishop_count(BLACK) == 1 + return piece_count(WHITE, BISHOP) == 1 + && piece_count(BLACK, BISHOP) == 1 && square_color(piece_list(WHITE, BISHOP, 0)) != square_color(piece_list(BLACK, BISHOP, 0)); } From 1bd1f5a29374f1f4b20e88c38f40b18604eb70d3 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 19 Oct 2008 16:20:21 +0100 Subject: [PATCH 14/18] Start to templetize pawn move generators Still very soft, we will see if compiler is enough or we need more aggressive templetization. Signed-off-by: Marco Costalba --- src/movegen.cpp | 54 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/src/movegen.cpp b/src/movegen.cpp index d8ea0626..3dfd8f6a 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -56,11 +56,19 @@ namespace { const PawnOffsets BlackPawnOffsets = { Rank6BB, Rank1BB, RANK_1, DELTA_S, DELTA_SE, DELTA_SW, BLACK, WHITE, &forward_black, &forward_left_black, &forward_right_black }; - int generate_pawn_captures(const PawnOffsets&, const Position&, MoveStack*); - int generate_pawn_noncaptures(const PawnOffsets&, const Position&, MoveStack*); - int generate_pawn_checks(const PawnOffsets&, const Position&, Bitboard, Square, MoveStack*, int); int generate_castle_moves(const Position&, MoveStack*, Color); - int generate_pawn_blocking_evasions(const PawnOffsets&, const Position&, Bitboard, Bitboard, MoveStack*, int); + + template + int generate_pawn_captures(const Position&, MoveStack*); + + template + int generate_pawn_noncaptures(const Position&, MoveStack*); + + template + int generate_pawn_checks(const Position&, Bitboard, Square, MoveStack*, int); + + template + int generate_pawn_blocking_evasions(const Position&, Bitboard, Bitboard, MoveStack*, int); template int generate_piece_moves(const Position&, MoveStack*, Color, Bitboard); @@ -178,9 +186,9 @@ int generate_captures(const Position& pos, MoveStack* mlist) { int n; if (us == WHITE) - n = generate_pawn_captures(WhitePawnOffsets, pos, mlist); + n = generate_pawn_captures(pos, mlist); else - n = generate_pawn_captures(BlackPawnOffsets, pos, mlist); + n = generate_pawn_captures(pos, mlist); n += generate_piece_moves(pos, mlist+n, us, target); n += generate_piece_moves(pos, mlist+n, us, target); @@ -204,9 +212,9 @@ int generate_noncaptures(const Position& pos, MoveStack *mlist) { int n; if (us == WHITE) - n = generate_pawn_noncaptures(WhitePawnOffsets, pos, mlist); + n = generate_pawn_noncaptures(pos, mlist); else - n = generate_pawn_noncaptures(BlackPawnOffsets, pos, mlist); + n = generate_pawn_noncaptures(pos, mlist); n += generate_piece_moves(pos, mlist+n, us, target); n += generate_piece_moves(pos, mlist+n, us, target); @@ -238,9 +246,9 @@ int generate_checks(const Position& pos, MoveStack* mlist, Bitboard dc) { // Pawn moves if (us == WHITE) - n = generate_pawn_checks(WhitePawnOffsets, pos, dc, ksq, mlist, 0); + n = generate_pawn_checks(pos, dc, ksq, mlist, 0); else - n = generate_pawn_checks(BlackPawnOffsets, pos, dc, ksq, mlist, 0); + n = generate_pawn_checks(pos, dc, ksq, mlist, 0); // Pieces moves Bitboard b = pos.knights(us); @@ -362,9 +370,9 @@ int generate_evasions(const Position& pos, MoveStack* mlist) { // Pawn moves. Because a blocking evasion can never be a capture, we // only generate pawn pushes. if (us == WHITE) - n = generate_pawn_blocking_evasions(WhitePawnOffsets, pos, not_pinned, blockSquares, mlist, n); + n = generate_pawn_blocking_evasions(pos, not_pinned, blockSquares, mlist, n); else - n = generate_pawn_blocking_evasions(BlackPawnOffsets, pos, not_pinned, blockSquares, mlist, n); + n = generate_pawn_blocking_evasions(pos, not_pinned, blockSquares, mlist, n); // Pieces moves b1 = pos.knights(us) & not_pinned; @@ -629,7 +637,10 @@ Move generate_move_if_legal(const Position &pos, Move m, Bitboard pinned) { namespace { - int generate_pawn_captures(const PawnOffsets& ofs, const Position& pos, MoveStack* mlist) { + template + int generate_pawn_captures(const Position& pos, MoveStack* mlist) { + + static const PawnOffsets ofs = (C == WHITE ? WhitePawnOffsets : BlackPawnOffsets); Bitboard pawns = pos.pawns(ofs.us); Bitboard enemyPieces = pos.pieces_of_color(ofs.them); @@ -701,7 +712,10 @@ namespace { } - int generate_pawn_noncaptures(const PawnOffsets& ofs, const Position& pos, MoveStack* mlist) { + template + int generate_pawn_noncaptures(const Position& pos, MoveStack* mlist) { + + static const PawnOffsets ofs = (C == WHITE ? WhitePawnOffsets : BlackPawnOffsets); Bitboard pawns = pos.pawns(ofs.us); Bitboard enemyPieces = pos.pieces_of_color(ofs.them); @@ -824,8 +838,11 @@ namespace { } - int generate_pawn_checks(const PawnOffsets& ofs, const Position& pos, Bitboard dc, Square ksq, MoveStack* mlist, int n) + template + int generate_pawn_checks(const Position& pos, Bitboard dc, Square ksq, MoveStack* mlist, int n) { + static const PawnOffsets ofs = (C == WHITE ? WhitePawnOffsets : BlackPawnOffsets); + // Pawn moves which give discovered check. This is possible only if the // pawn is not on the same file as the enemy king, because we don't // generate captures. @@ -874,9 +891,12 @@ namespace { return n; } - - int generate_pawn_blocking_evasions(const PawnOffsets& ofs, const Position& pos, Bitboard not_pinned, + template + int generate_pawn_blocking_evasions(const Position& pos, Bitboard not_pinned, Bitboard blockSquares, MoveStack* mlist, int n) { + + static const PawnOffsets ofs = (C == WHITE ? WhitePawnOffsets : BlackPawnOffsets); + // Find non-pinned pawns Bitboard b1 = pos.pawns(ofs.us) & not_pinned; From 68c78400c8eb1b9946caa93d6013eff1d985e577 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 19 Oct 2008 17:54:18 +0200 Subject: [PATCH 15/18] Pawn move generator: dispatch at compile time Instead of function pointers use templates to dispatch shift operations. It is more clear and possibly also faster because branches are removed at compile time. Signed-off-by: Marco Costalba --- src/movegen.cpp | 230 +++++++++++++++++++++++------------------------- 1 file changed, 110 insertions(+), 120 deletions(-) diff --git a/src/movegen.cpp b/src/movegen.cpp index 3dfd8f6a..da8d08c3 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -32,29 +32,15 @@ namespace { - inline Bitboard forward_white(Bitboard b) { return b << 8; } - inline Bitboard forward_right_white(Bitboard b) { return b << 9; } - inline Bitboard forward_left_white(Bitboard b) { return b << 7; } - - inline Bitboard forward_black(Bitboard b) { return b >> 8; } - inline Bitboard forward_right_black(Bitboard b) { return b >> 7; } - inline Bitboard forward_left_black(Bitboard b) { return b >> 9; } - struct PawnOffsets { Bitboard Rank3BB, Rank8BB; Rank RANK_8; SquareDelta DELTA_N, DELTA_NE, DELTA_NW; Color us, them; - typedef Bitboard (*Shift_fn)(Bitboard b); - Shift_fn forward, forward_left, forward_right; }; - - const PawnOffsets WhitePawnOffsets = { Rank3BB, Rank8BB, RANK_8, DELTA_N, DELTA_NE, DELTA_NW, WHITE, BLACK, - &forward_white, forward_left_white, forward_right_white }; - - const PawnOffsets BlackPawnOffsets = { Rank6BB, Rank1BB, RANK_1, DELTA_S, DELTA_SE, DELTA_SW, BLACK, WHITE, - &forward_black, &forward_left_black, &forward_right_black }; + const PawnOffsets WhitePawnOffsets = { Rank3BB, Rank8BB, RANK_8, DELTA_N, DELTA_NE, DELTA_NW, WHITE, BLACK }; + const PawnOffsets BlackPawnOffsets = { Rank6BB, Rank1BB, RANK_1, DELTA_S, DELTA_SE, DELTA_SW, BLACK, WHITE }; int generate_castle_moves(const Position&, MoveStack*, Color); @@ -648,7 +634,7 @@ namespace { int n = 0; // Captures in the a1-h8 (a8-h1 for black) direction - Bitboard b1 = (ofs.forward_right)(pawns) & ~FileABB & enemyPieces; + Bitboard b1 = (C == WHITE ? pawns << 9 : pawns >> 7) & ~FileABB & enemyPieces; // Capturing promotions Bitboard b2 = b1 & ofs.Rank8BB; @@ -667,7 +653,7 @@ namespace { } // Captures in the h1-a8 (h8-a1 for black) direction - b1 = (ofs.forward_left)(pawns) & ~FileHBB & enemyPieces; + b1 = (C == WHITE ? pawns << 7 : pawns >> 9) & ~FileHBB & enemyPieces; // Capturing promotions b2 = b1 & ofs.Rank8BB; @@ -686,7 +672,7 @@ namespace { } // Non-capturing promotions - b1 = (ofs.forward)(pawns) & pos.empty_squares() & Rank8BB; + b1 = (C == WHITE ? pawns << 8 : pawns >> 8) & pos.empty_squares() & Rank8BB; while (b1) { sq = pop_1st_bit(&b1); @@ -725,7 +711,7 @@ namespace { int n = 0; // Underpromotion captures in the a1-h8 (a8-h1 for black) direction - b1 = ofs.forward_right(pawns) & ~FileABB & enemyPieces & ofs.Rank8BB; + b1 = (C == WHITE ? pawns << 9 : pawns >> 7) & ~FileABB & enemyPieces & ofs.Rank8BB; while (b1) { sq = pop_1st_bit(&b1); @@ -735,7 +721,7 @@ namespace { } // Underpromotion captures in the h1-a8 (h8-a1 for black) direction - b1 = ofs.forward_left(pawns) & ~FileHBB & enemyPieces & ofs.Rank8BB; + b1 = (C == WHITE ? pawns << 7 : pawns >> 9) & ~FileHBB & enemyPieces & ofs.Rank8BB; while (b1) { sq = pop_1st_bit(&b1); @@ -745,7 +731,7 @@ namespace { } // Single pawn pushes - b1 = ofs.forward(pawns) & emptySquares; + b1 = (C == WHITE ? pawns << 8 : pawns >> 8) & emptySquares; b2 = b1 & ofs.Rank8BB; while (b2) { @@ -762,7 +748,7 @@ namespace { } // Double pawn pushes - b2 = (ofs.forward(b1 & ofs.Rank3BB)) & emptySquares; + b2 = (C == WHITE ? (b1 & ofs.Rank3BB) << 8 : (b1 & ofs.Rank3BB) >> 8) & emptySquares; while (b2) { sq = pop_1st_bit(&b2); @@ -772,6 +758,107 @@ namespace { } + template + int generate_pawn_checks(const Position& pos, Bitboard dc, Square ksq, MoveStack* mlist, int n) + { + static const PawnOffsets ofs = (C == WHITE ? WhitePawnOffsets : BlackPawnOffsets); + + // Pawn moves which give discovered check. This is possible only if the + // pawn is not on the same file as the enemy king, because we don't + // generate captures. + Bitboard empty = pos.empty_squares(); + + // Find all friendly pawns not on the enemy king's file + Bitboard b1 = pos.pawns(pos.side_to_move()) & ~file_bb(ksq), b2, b3; + + // Discovered checks, single pawn pushes + b2 = b3 = (C == WHITE ? (b1 & dc) << 8 : (b1 & dc) >> 8) & ~ofs.Rank8BB & empty; + while (b3) + { + Square to = pop_1st_bit(&b3); + mlist[n++].move = make_move(to - ofs.DELTA_N, to); + } + + // Discovered checks, double pawn pushes + b3 = (C == WHITE ? (b2 & ofs.Rank3BB) << 8 : (b2 & ofs.Rank3BB) >> 8) & empty; + while (b3) + { + Square to = pop_1st_bit(&b3); + mlist[n++].move = make_move(to - ofs.DELTA_N - ofs.DELTA_N, to); + } + + // Direct checks. These are possible only for pawns on neighboring files + // of the enemy king + + b1 &= (~dc & neighboring_files_bb(ksq)); // FIXME why ~dc ?? + + // Direct checks, single pawn pushes + b2 = (C == WHITE ? b1 << 8 : b1 >> 8) & empty; + b3 = b2 & pos.pawn_attacks(ofs.them, ksq); + while (b3) + { + Square to = pop_1st_bit(&b3); + mlist[n++].move = make_move(to - ofs.DELTA_N, to); + } + + // Direct checks, double pawn pushes + b3 = (C == WHITE ? (b2 & ofs.Rank3BB) << 8 : (b2 & ofs.Rank3BB) >> 8) + & empty + & pos.pawn_attacks(ofs.them, ksq); + + while (b3) + { + Square to = pop_1st_bit(&b3); + mlist[n++].move = make_move(to - ofs.DELTA_N - ofs.DELTA_N, to); + } + return n; + } + + template + int generate_pawn_blocking_evasions(const Position& pos, Bitboard not_pinned, + Bitboard blockSquares, MoveStack* mlist, int n) { + + static const PawnOffsets ofs = (C == WHITE ? WhitePawnOffsets : BlackPawnOffsets); + + // Find non-pinned pawns + Bitboard b1 = pos.pawns(ofs.us) & not_pinned; + + // Single pawn pushes. We don't have to AND with empty squares here, + // because the blocking squares will always be empty. + Bitboard b2 = (C == WHITE ? b1 << 8 : b1 >> 8) & blockSquares; + while (b2) + { + Square to = pop_1st_bit(&b2); + + assert(pos.piece_on(to) == EMPTY); + + if (square_rank(to) == ofs.RANK_8) + { + mlist[n++].move = make_promotion_move(to - ofs.DELTA_N, to, QUEEN); + mlist[n++].move = make_promotion_move(to - ofs.DELTA_N, to, ROOK); + mlist[n++].move = make_promotion_move(to - ofs.DELTA_N, to, BISHOP); + mlist[n++].move = make_promotion_move(to - ofs.DELTA_N, to, KNIGHT); + } else + mlist[n++].move = make_move(to - ofs.DELTA_N, to); + } + + // Double pawn pushes + b2 = (C == WHITE ? b1 << 8 : b1 >> 8) & pos.empty_squares() & ofs.Rank3BB; + b2 = (C == WHITE ? b2 << 8 : b2 >> 8) & blockSquares;; + while (b2) + { + Square to = pop_1st_bit(&b2); + + assert(pos.piece_on(to) == EMPTY); + assert(ofs.us != WHITE || square_rank(to) == RANK_4); + assert(ofs.us != BLACK || square_rank(to) == RANK_5); + + mlist[n++].move = make_move(to - ofs.DELTA_N - ofs.DELTA_N, to); + } + return n; + } + + int generate_castle_moves(const Position &pos, MoveStack *mlist, Color us) { int n = 0; @@ -836,101 +923,4 @@ namespace { } return n; } - - - template - int generate_pawn_checks(const Position& pos, Bitboard dc, Square ksq, MoveStack* mlist, int n) - { - static const PawnOffsets ofs = (C == WHITE ? WhitePawnOffsets : BlackPawnOffsets); - - // Pawn moves which give discovered check. This is possible only if the - // pawn is not on the same file as the enemy king, because we don't - // generate captures. - Bitboard empty = pos.empty_squares(); - - // Find all friendly pawns not on the enemy king's file - Bitboard b1 = pos.pawns(pos.side_to_move()) & ~file_bb(ksq), b2, b3; - - // Discovered checks, single pawn pushes - b2 = b3 = (ofs.forward)(b1 & dc) & ~ofs.Rank8BB & empty; - while (b3) - { - Square to = pop_1st_bit(&b3); - mlist[n++].move = make_move(to - ofs.DELTA_N, to); - } - - // Discovered checks, double pawn pushes - b3 = (ofs.forward)(b2 & ofs.Rank3BB) & empty; - while (b3) - { - Square to = pop_1st_bit(&b3); - mlist[n++].move = make_move(to - ofs.DELTA_N - ofs.DELTA_N, to); - } - - // Direct checks. These are possible only for pawns on neighboring files - // of the enemy king - - b1 &= (~dc & neighboring_files_bb(ksq)); // FIXME why ~dc ?? - - // Direct checks, single pawn pushes - b2 = (ofs.forward)(b1) & empty; - b3 = b2 & pos.pawn_attacks(ofs.them, ksq); - while (b3) - { - Square to = pop_1st_bit(&b3); - mlist[n++].move = make_move(to - ofs.DELTA_N, to); - } - - // Direct checks, double pawn pushes - b3 = (ofs.forward)(b2 & ofs.Rank3BB) & empty & pos.pawn_attacks(ofs.them, ksq); - while (b3) - { - Square to = pop_1st_bit(&b3); - mlist[n++].move = make_move(to - ofs.DELTA_N - ofs.DELTA_N, to); - } - return n; - } - - template - int generate_pawn_blocking_evasions(const Position& pos, Bitboard not_pinned, - Bitboard blockSquares, MoveStack* mlist, int n) { - - static const PawnOffsets ofs = (C == WHITE ? WhitePawnOffsets : BlackPawnOffsets); - - // Find non-pinned pawns - Bitboard b1 = pos.pawns(ofs.us) & not_pinned; - - // Single pawn pushes. We don't have to AND with empty squares here, - // because the blocking squares will always be empty. - Bitboard b2 = (ofs.forward)(b1) & blockSquares; - while (b2) - { - Square to = pop_1st_bit(&b2); - - assert(pos.piece_on(to) == EMPTY); - - if (square_rank(to) == ofs.RANK_8) - { - mlist[n++].move = make_promotion_move(to - ofs.DELTA_N, to, QUEEN); - mlist[n++].move = make_promotion_move(to - ofs.DELTA_N, to, ROOK); - mlist[n++].move = make_promotion_move(to - ofs.DELTA_N, to, BISHOP); - mlist[n++].move = make_promotion_move(to - ofs.DELTA_N, to, KNIGHT); - } else - mlist[n++].move = make_move(to - ofs.DELTA_N, to); - } - - // Double pawn pushes - b2 = (ofs.forward)((ofs.forward)(b1) & pos.empty_squares() & ofs.Rank3BB) & blockSquares; - while (b2) - { - Square to = pop_1st_bit(&b2); - - assert(pos.piece_on(to) == EMPTY); - assert(ofs.us != WHITE || square_rank(to) == RANK_4); - assert(ofs.us != BLACK || square_rank(to) == RANK_5); - - mlist[n++].move = make_move(to - ofs.DELTA_N - ofs.DELTA_N, to); - } - return n; - } } From b3974267850098f6b350eab3d934617c5877dd3c Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 19 Oct 2008 18:01:01 +0200 Subject: [PATCH 16/18] Rename PawnOffsets in PawnParams Signed-off-by: Marco Costalba --- src/movegen.cpp | 118 ++++++++++++++++++++++++------------------------ 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/src/movegen.cpp b/src/movegen.cpp index da8d08c3..742a91f7 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -32,15 +32,15 @@ namespace { - struct PawnOffsets { + struct PawnParams { Bitboard Rank3BB, Rank8BB; Rank RANK_8; SquareDelta DELTA_N, DELTA_NE, DELTA_NW; Color us, them; }; - const PawnOffsets WhitePawnOffsets = { Rank3BB, Rank8BB, RANK_8, DELTA_N, DELTA_NE, DELTA_NW, WHITE, BLACK }; - const PawnOffsets BlackPawnOffsets = { Rank6BB, Rank1BB, RANK_1, DELTA_S, DELTA_SE, DELTA_SW, BLACK, WHITE }; + const PawnParams WhitePawnParams = { Rank3BB, Rank8BB, RANK_8, DELTA_N, DELTA_NE, DELTA_NW, WHITE, BLACK }; + const PawnParams BlackPawnParams = { Rank6BB, Rank1BB, RANK_1, DELTA_S, DELTA_SE, DELTA_SW, BLACK, WHITE }; int generate_castle_moves(const Position&, MoveStack*, Color); @@ -626,10 +626,10 @@ namespace { template int generate_pawn_captures(const Position& pos, MoveStack* mlist) { - static const PawnOffsets ofs = (C == WHITE ? WhitePawnOffsets : BlackPawnOffsets); + static const PawnParams PP = (C == WHITE ? WhitePawnParams : BlackPawnParams); - Bitboard pawns = pos.pawns(ofs.us); - Bitboard enemyPieces = pos.pieces_of_color(ofs.them); + Bitboard pawns = pos.pawns(PP.us); + Bitboard enemyPieces = pos.pieces_of_color(PP.them); Square sq; int n = 0; @@ -637,38 +637,38 @@ namespace { Bitboard b1 = (C == WHITE ? pawns << 9 : pawns >> 7) & ~FileABB & enemyPieces; // Capturing promotions - Bitboard b2 = b1 & ofs.Rank8BB; + Bitboard b2 = b1 & PP.Rank8BB; while (b2) { sq = pop_1st_bit(&b2); - mlist[n++].move = make_promotion_move(sq - ofs.DELTA_NE, sq, QUEEN); + mlist[n++].move = make_promotion_move(sq - PP.DELTA_NE, sq, QUEEN); } // Capturing non-promotions - b2 = b1 & ~ofs.Rank8BB; + b2 = b1 & ~PP.Rank8BB; while (b2) { sq = pop_1st_bit(&b2); - mlist[n++].move = make_move(sq - ofs.DELTA_NE, sq); + mlist[n++].move = make_move(sq - PP.DELTA_NE, sq); } // Captures in the h1-a8 (h8-a1 for black) direction b1 = (C == WHITE ? pawns << 7 : pawns >> 9) & ~FileHBB & enemyPieces; // Capturing promotions - b2 = b1 & ofs.Rank8BB; + b2 = b1 & PP.Rank8BB; while (b2) { sq = pop_1st_bit(&b2); - mlist[n++].move = make_promotion_move(sq - ofs.DELTA_NW, sq, QUEEN); + mlist[n++].move = make_promotion_move(sq - PP.DELTA_NW, sq, QUEEN); } // Capturing non-promotions - b2 = b1 & ~ofs.Rank8BB; + b2 = b1 & ~PP.Rank8BB; while (b2) { sq = pop_1st_bit(&b2); - mlist[n++].move = make_move(sq - ofs.DELTA_NW, sq); + mlist[n++].move = make_move(sq - PP.DELTA_NW, sq); } // Non-capturing promotions @@ -676,16 +676,16 @@ namespace { while (b1) { sq = pop_1st_bit(&b1); - mlist[n++].move = make_promotion_move(sq - ofs.DELTA_N, sq, QUEEN); + mlist[n++].move = make_promotion_move(sq - PP.DELTA_N, sq, QUEEN); } // En passant captures if (pos.ep_square() != SQ_NONE) { - assert(ofs.us != WHITE || square_rank(pos.ep_square()) == RANK_6); - assert(ofs.us != BLACK || square_rank(pos.ep_square()) == RANK_3); + assert(PP.us != WHITE || square_rank(pos.ep_square()) == RANK_6); + assert(PP.us != BLACK || square_rank(pos.ep_square()) == RANK_3); - b1 = pawns & pos.pawn_attacks(ofs.them, pos.ep_square()); + b1 = pawns & pos.pawn_attacks(PP.them, pos.ep_square()); assert(b1 != EmptyBoardBB); while (b1) @@ -701,58 +701,58 @@ namespace { template int generate_pawn_noncaptures(const Position& pos, MoveStack* mlist) { - static const PawnOffsets ofs = (C == WHITE ? WhitePawnOffsets : BlackPawnOffsets); + static const PawnParams PP = (C == WHITE ? WhitePawnParams : BlackPawnParams); - Bitboard pawns = pos.pawns(ofs.us); - Bitboard enemyPieces = pos.pieces_of_color(ofs.them); + Bitboard pawns = pos.pawns(PP.us); + Bitboard enemyPieces = pos.pieces_of_color(PP.them); Bitboard emptySquares = pos.empty_squares(); Bitboard b1, b2; Square sq; int n = 0; // Underpromotion captures in the a1-h8 (a8-h1 for black) direction - b1 = (C == WHITE ? pawns << 9 : pawns >> 7) & ~FileABB & enemyPieces & ofs.Rank8BB; + b1 = (C == WHITE ? pawns << 9 : pawns >> 7) & ~FileABB & enemyPieces & PP.Rank8BB; while (b1) { sq = pop_1st_bit(&b1); - mlist[n++].move = make_promotion_move(sq - ofs.DELTA_NE, sq, ROOK); - mlist[n++].move = make_promotion_move(sq - ofs.DELTA_NE, sq, BISHOP); - mlist[n++].move = make_promotion_move(sq - ofs.DELTA_NE, sq, KNIGHT); + mlist[n++].move = make_promotion_move(sq - PP.DELTA_NE, sq, ROOK); + mlist[n++].move = make_promotion_move(sq - PP.DELTA_NE, sq, BISHOP); + mlist[n++].move = make_promotion_move(sq - PP.DELTA_NE, sq, KNIGHT); } // Underpromotion captures in the h1-a8 (h8-a1 for black) direction - b1 = (C == WHITE ? pawns << 7 : pawns >> 9) & ~FileHBB & enemyPieces & ofs.Rank8BB; + b1 = (C == WHITE ? pawns << 7 : pawns >> 9) & ~FileHBB & enemyPieces & PP.Rank8BB; while (b1) { sq = pop_1st_bit(&b1); - mlist[n++].move = make_promotion_move(sq - ofs.DELTA_NW, sq, ROOK); - mlist[n++].move = make_promotion_move(sq - ofs.DELTA_NW, sq, BISHOP); - mlist[n++].move = make_promotion_move(sq - ofs.DELTA_NW, sq, KNIGHT); + mlist[n++].move = make_promotion_move(sq - PP.DELTA_NW, sq, ROOK); + mlist[n++].move = make_promotion_move(sq - PP.DELTA_NW, sq, BISHOP); + mlist[n++].move = make_promotion_move(sq - PP.DELTA_NW, sq, KNIGHT); } // Single pawn pushes b1 = (C == WHITE ? pawns << 8 : pawns >> 8) & emptySquares; - b2 = b1 & ofs.Rank8BB; + b2 = b1 & PP.Rank8BB; while (b2) { sq = pop_1st_bit(&b2); - mlist[n++].move = make_promotion_move(sq - ofs.DELTA_N, sq, ROOK); - mlist[n++].move = make_promotion_move(sq - ofs.DELTA_N, sq, BISHOP); - mlist[n++].move = make_promotion_move(sq - ofs.DELTA_N, sq, KNIGHT); + mlist[n++].move = make_promotion_move(sq - PP.DELTA_N, sq, ROOK); + mlist[n++].move = make_promotion_move(sq - PP.DELTA_N, sq, BISHOP); + mlist[n++].move = make_promotion_move(sq - PP.DELTA_N, sq, KNIGHT); } - b2 = b1 & ~ofs.Rank8BB; + b2 = b1 & ~PP.Rank8BB; while (b2) { sq = pop_1st_bit(&b2); - mlist[n++].move = make_move(sq - ofs.DELTA_N, sq); + mlist[n++].move = make_move(sq - PP.DELTA_N, sq); } // Double pawn pushes - b2 = (C == WHITE ? (b1 & ofs.Rank3BB) << 8 : (b1 & ofs.Rank3BB) >> 8) & emptySquares; + b2 = (C == WHITE ? (b1 & PP.Rank3BB) << 8 : (b1 & PP.Rank3BB) >> 8) & emptySquares; while (b2) { sq = pop_1st_bit(&b2); - mlist[n++].move = make_move(sq - ofs.DELTA_N - ofs.DELTA_N, sq); + mlist[n++].move = make_move(sq - PP.DELTA_N - PP.DELTA_N, sq); } return n; } @@ -761,7 +761,7 @@ namespace { template int generate_pawn_checks(const Position& pos, Bitboard dc, Square ksq, MoveStack* mlist, int n) { - static const PawnOffsets ofs = (C == WHITE ? WhitePawnOffsets : BlackPawnOffsets); + static const PawnParams PP = (C == WHITE ? WhitePawnParams : BlackPawnParams); // Pawn moves which give discovered check. This is possible only if the // pawn is not on the same file as the enemy king, because we don't @@ -772,19 +772,19 @@ namespace { Bitboard b1 = pos.pawns(pos.side_to_move()) & ~file_bb(ksq), b2, b3; // Discovered checks, single pawn pushes - b2 = b3 = (C == WHITE ? (b1 & dc) << 8 : (b1 & dc) >> 8) & ~ofs.Rank8BB & empty; + b2 = b3 = (C == WHITE ? (b1 & dc) << 8 : (b1 & dc) >> 8) & ~PP.Rank8BB & empty; while (b3) { Square to = pop_1st_bit(&b3); - mlist[n++].move = make_move(to - ofs.DELTA_N, to); + mlist[n++].move = make_move(to - PP.DELTA_N, to); } // Discovered checks, double pawn pushes - b3 = (C == WHITE ? (b2 & ofs.Rank3BB) << 8 : (b2 & ofs.Rank3BB) >> 8) & empty; + b3 = (C == WHITE ? (b2 & PP.Rank3BB) << 8 : (b2 & PP.Rank3BB) >> 8) & empty; while (b3) { Square to = pop_1st_bit(&b3); - mlist[n++].move = make_move(to - ofs.DELTA_N - ofs.DELTA_N, to); + mlist[n++].move = make_move(to - PP.DELTA_N - PP.DELTA_N, to); } // Direct checks. These are possible only for pawns on neighboring files @@ -794,22 +794,22 @@ namespace { // Direct checks, single pawn pushes b2 = (C == WHITE ? b1 << 8 : b1 >> 8) & empty; - b3 = b2 & pos.pawn_attacks(ofs.them, ksq); + b3 = b2 & pos.pawn_attacks(PP.them, ksq); while (b3) { Square to = pop_1st_bit(&b3); - mlist[n++].move = make_move(to - ofs.DELTA_N, to); + mlist[n++].move = make_move(to - PP.DELTA_N, to); } // Direct checks, double pawn pushes - b3 = (C == WHITE ? (b2 & ofs.Rank3BB) << 8 : (b2 & ofs.Rank3BB) >> 8) + b3 = (C == WHITE ? (b2 & PP.Rank3BB) << 8 : (b2 & PP.Rank3BB) >> 8) & empty - & pos.pawn_attacks(ofs.them, ksq); + & pos.pawn_attacks(PP.them, ksq); while (b3) { Square to = pop_1st_bit(&b3); - mlist[n++].move = make_move(to - ofs.DELTA_N - ofs.DELTA_N, to); + mlist[n++].move = make_move(to - PP.DELTA_N - PP.DELTA_N, to); } return n; } @@ -818,10 +818,10 @@ namespace { int generate_pawn_blocking_evasions(const Position& pos, Bitboard not_pinned, Bitboard blockSquares, MoveStack* mlist, int n) { - static const PawnOffsets ofs = (C == WHITE ? WhitePawnOffsets : BlackPawnOffsets); + static const PawnParams PP = (C == WHITE ? WhitePawnParams : BlackPawnParams); // Find non-pinned pawns - Bitboard b1 = pos.pawns(ofs.us) & not_pinned; + Bitboard b1 = pos.pawns(PP.us) & not_pinned; // Single pawn pushes. We don't have to AND with empty squares here, // because the blocking squares will always be empty. @@ -832,28 +832,28 @@ namespace { assert(pos.piece_on(to) == EMPTY); - if (square_rank(to) == ofs.RANK_8) + if (square_rank(to) == PP.RANK_8) { - mlist[n++].move = make_promotion_move(to - ofs.DELTA_N, to, QUEEN); - mlist[n++].move = make_promotion_move(to - ofs.DELTA_N, to, ROOK); - mlist[n++].move = make_promotion_move(to - ofs.DELTA_N, to, BISHOP); - mlist[n++].move = make_promotion_move(to - ofs.DELTA_N, to, KNIGHT); + mlist[n++].move = make_promotion_move(to - PP.DELTA_N, to, QUEEN); + mlist[n++].move = make_promotion_move(to - PP.DELTA_N, to, ROOK); + mlist[n++].move = make_promotion_move(to - PP.DELTA_N, to, BISHOP); + mlist[n++].move = make_promotion_move(to - PP.DELTA_N, to, KNIGHT); } else - mlist[n++].move = make_move(to - ofs.DELTA_N, to); + mlist[n++].move = make_move(to - PP.DELTA_N, to); } // Double pawn pushes - b2 = (C == WHITE ? b1 << 8 : b1 >> 8) & pos.empty_squares() & ofs.Rank3BB; + b2 = (C == WHITE ? b1 << 8 : b1 >> 8) & pos.empty_squares() & PP.Rank3BB; b2 = (C == WHITE ? b2 << 8 : b2 >> 8) & blockSquares;; while (b2) { Square to = pop_1st_bit(&b2); assert(pos.piece_on(to) == EMPTY); - assert(ofs.us != WHITE || square_rank(to) == RANK_4); - assert(ofs.us != BLACK || square_rank(to) == RANK_5); + assert(PP.us != WHITE || square_rank(to) == RANK_4); + assert(PP.us != BLACK || square_rank(to) == RANK_5); - mlist[n++].move = make_move(to - ofs.DELTA_N - ofs.DELTA_N, to); + mlist[n++].move = make_move(to - PP.DELTA_N - PP.DELTA_N, to); } return n; } From f664ca41ed0f7a20b048fe60877ad29919027a40 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 19 Oct 2008 18:19:16 +0200 Subject: [PATCH 17/18] Last little touches to movegen No functional change. Signed-off-by: Marco Costalba --- src/movegen.cpp | 74 ++++++++++++++++++++++++------------------------- src/movegen.h | 3 +- 2 files changed, 38 insertions(+), 39 deletions(-) diff --git a/src/movegen.cpp b/src/movegen.cpp index 742a91f7..afe561f5 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -33,7 +33,6 @@ namespace { struct PawnParams { - Bitboard Rank3BB, Rank8BB; Rank RANK_8; SquareDelta DELTA_N, DELTA_NE, DELTA_NW; @@ -66,25 +65,7 @@ namespace { int generate_piece_blocking_evasions(const Position&, Bitboard, Bitboard, MoveStack*, int); - /// Templates are defined here to avoid lookup issues with specializations - - template - int generate_piece_moves(const Position &pos, MoveStack *mlist, - Color side, Bitboard target) { - int n = 0; - for (int i = 0; i < pos.piece_count(side, Piece); i++) - { - Square from = pos.piece_list(side, Piece, i); - Bitboard b = pos.piece_attacks(from) & target; - while (b) - { - Square to = pop_1st_bit(&b); - mlist[n++].move = make_move(from, to); - } - } - return n; - } - + /// Templates with specializations are defined here to avoid lookup issues template int generate_piece_checks(const Position& pos, Bitboard target, Bitboard dc, @@ -134,23 +115,6 @@ namespace { } return n; } - - - template - int generate_piece_blocking_evasions(const Position& pos, Bitboard b, - Bitboard blockSquares, MoveStack* mlist, int n) { - while (b) - { - Square from = pop_1st_bit(&b); - Bitboard bb = pos.piece_attacks(from) & blockSquares; - while (bb) - { - Square to = pop_1st_bit(&bb); - mlist[n++].move = make_move(from, to); - } - } - return n; - } } @@ -623,6 +587,41 @@ Move generate_move_if_legal(const Position &pos, Move m, Bitboard pinned) { namespace { + template + int generate_piece_moves(const Position &pos, MoveStack *mlist, + Color side, Bitboard target) { + int n = 0; + for (int i = 0; i < pos.piece_count(side, Piece); i++) + { + Square from = pos.piece_list(side, Piece, i); + Bitboard b = pos.piece_attacks(from) & target; + while (b) + { + Square to = pop_1st_bit(&b); + mlist[n++].move = make_move(from, to); + } + } + return n; + } + + + template + int generate_piece_blocking_evasions(const Position& pos, Bitboard b, + Bitboard blockSquares, MoveStack* mlist, int n) { + while (b) + { + Square from = pop_1st_bit(&b); + Bitboard bb = pos.piece_attacks(from) & blockSquares; + while (bb) + { + Square to = pop_1st_bit(&bb); + mlist[n++].move = make_move(from, to); + } + } + return n; + } + + template int generate_pawn_captures(const Position& pos, MoveStack* mlist) { @@ -814,6 +813,7 @@ namespace { return n; } + template int generate_pawn_blocking_evasions(const Position& pos, Bitboard not_pinned, Bitboard blockSquares, MoveStack* mlist, int n) { diff --git a/src/movegen.h b/src/movegen.h index 93c1c4ab..16923dcc 100644 --- a/src/movegen.h +++ b/src/movegen.h @@ -36,7 +36,6 @@ extern int generate_noncaptures(const Position &pos, MoveStack *mlist); extern int generate_checks(const Position &pos, MoveStack *mlist, Bitboard dc); extern int generate_evasions(const Position &pos, MoveStack *mlist); extern int generate_legal_moves(const Position &pos, MoveStack *mlist); -extern Move generate_move_if_legal(const Position &pos, Move m, - Bitboard pinned); +extern Move generate_move_if_legal(const Position &pos, Move m, Bitboard pinned); #endif // !defined(MOVEGEN_H_INCLUDED) From d3600c39a745179ed6b094b305d0645e83a1ee86 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 19 Oct 2008 18:56:28 +0200 Subject: [PATCH 18/18] Update copyright info Signed-off-by: Marco Costalba --- src/benchmark.cpp | 11 ++++++----- src/benchmark.h | 9 +++++---- src/bitbase.cpp | 9 +++++---- src/bitbase.h | 9 +++++---- src/bitboard.cpp | 9 +++++---- src/bitboard.h | 9 +++++---- src/book.cpp | 9 +++++---- src/book.h | 9 +++++---- src/color.cpp | 9 +++++---- src/color.h | 9 +++++---- src/depth.h | 9 +++++---- src/direction.cpp | 9 +++++---- src/direction.h | 9 +++++---- src/endgame.cpp | 9 +++++---- src/endgame.h | 9 +++++---- src/evaluate.cpp | 9 +++++---- src/evaluate.h | 9 +++++---- src/history.cpp | 9 +++++---- src/history.h | 9 +++++---- src/lock.h | 9 +++++---- src/main.cpp | 13 +++++++------ src/material.cpp | 9 +++++---- src/material.h | 9 +++++---- src/mersenne.h | 9 +++++---- src/misc.cpp | 9 +++++---- src/misc.h | 9 +++++---- src/move.cpp | 9 +++++---- src/move.h | 9 +++++---- src/movegen.cpp | 8 ++++---- src/movegen.h | 9 +++++---- src/movepick.cpp | 9 +++++---- src/movepick.h | 9 +++++---- src/pawns.cpp | 9 +++++---- src/pawns.h | 9 +++++---- src/phase.h | 9 +++++---- src/piece.cpp | 9 +++++---- src/piece.h | 9 +++++---- src/position.cpp | 9 +++++---- src/position.h | 9 +++++---- src/psqtab.h | 9 +++++---- src/san.cpp | 9 +++++---- src/san.h | 9 +++++---- src/scale.h | 9 +++++---- src/search.cpp | 11 ++++++----- src/search.h | 9 +++++---- src/square.cpp | 9 +++++---- src/square.h | 9 +++++---- src/thread.h | 9 +++++---- src/tt.cpp | 9 +++++---- src/tt.h | 9 +++++---- src/types.h | 9 +++++---- src/uci.cpp | 22 ++++++++++++---------- src/uci.h | 9 +++++---- src/ucioption.cpp | 9 +++++---- src/ucioption.h | 9 +++++---- src/value.cpp | 13 +++++++------ src/value.h | 9 +++++---- 57 files changed, 297 insertions(+), 240 deletions(-) diff --git a/src/benchmark.cpp b/src/benchmark.cpp index 9e63b1c9..5102b369 100644 --- a/src/benchmark.cpp +++ b/src/benchmark.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -58,7 +59,7 @@ const std::string BenchmarkPositions[] = { //// Functions //// -/// benchmark() runs a simple benchmark by letting Glaurung analyze a set +/// benchmark() runs a simple benchmark by letting Stockfish analyze a set /// of positions for a given time each. There are four parameters; the /// transposition table size, the number of search threads that should /// be used, the time in seconds spent for each position (optional, default diff --git a/src/benchmark.h b/src/benchmark.h index 7903a546..ce77e3d9 100644 --- a/src/benchmark.h +++ b/src/benchmark.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/bitbase.cpp b/src/bitbase.cpp index 80db0a41..19cf3f79 100644 --- a/src/bitbase.cpp +++ b/src/bitbase.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/bitbase.h b/src/bitbase.h index 2de54136..b7024ecf 100644 --- a/src/bitbase.h +++ b/src/bitbase.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/bitboard.cpp b/src/bitboard.cpp index 89065c49..e0cb1c20 100644 --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/bitboard.h b/src/bitboard.h index 9fbcbf72..8c6a7007 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/book.cpp b/src/book.cpp index 3ca5efe3..16a0766d 100644 --- a/src/book.cpp +++ b/src/book.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/book.h b/src/book.h index ccbe813f..2c175273 100644 --- a/src/book.h +++ b/src/book.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/color.cpp b/src/color.cpp index 50965a0b..c528b294 100644 --- a/src/color.cpp +++ b/src/color.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/color.h b/src/color.h index 37ba7959..929102d6 100644 --- a/src/color.h +++ b/src/color.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/depth.h b/src/depth.h index 493ecc40..81ba0c9b 100644 --- a/src/depth.h +++ b/src/depth.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/direction.cpp b/src/direction.cpp index 45fda4fd..24c242da 100644 --- a/src/direction.cpp +++ b/src/direction.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/direction.h b/src/direction.h index 63c7c73e..d429782a 100644 --- a/src/direction.h +++ b/src/direction.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/endgame.cpp b/src/endgame.cpp index 76fb597a..11f060bb 100644 --- a/src/endgame.cpp +++ b/src/endgame.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/endgame.h b/src/endgame.h index ae3526fe..dabf233e 100644 --- a/src/endgame.h +++ b/src/endgame.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 30ed0879..8f3ef1cd 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/evaluate.h b/src/evaluate.h index 05183a0a..d573e2df 100644 --- a/src/evaluate.h +++ b/src/evaluate.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/history.cpp b/src/history.cpp index 29631489..d5632986 100644 --- a/src/history.cpp +++ b/src/history.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/history.h b/src/history.h index ced416a8..f2559499 100644 --- a/src/history.h +++ b/src/history.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/lock.h b/src/lock.h index 2efb2076..065ceded 100644 --- a/src/lock.h +++ b/src/lock.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/main.cpp b/src/main.cpp index e89fee0e..7b675d34 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -85,8 +86,8 @@ int main(int argc, char *argv[]) { } // Print copyright notice - std::cout << engine_name() << ". " - << "Copyright (C) 2004-2008 Tord Romstad." + std::cout << engine_name() << ". Copyright (C) " + << "2004-2008 Tord Romstad, Marco Costalba. " << std::endl; // Enter UCI mode diff --git a/src/material.cpp b/src/material.cpp index 2718300d..9818fdce 100644 --- a/src/material.cpp +++ b/src/material.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/material.h b/src/material.h index 7d5c3ce1..59f7f3e2 100644 --- a/src/material.h +++ b/src/material.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/mersenne.h b/src/mersenne.h index 3c1c2268..1a43908c 100644 --- a/src/mersenne.h +++ b/src/mersenne.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/misc.cpp b/src/misc.cpp index 7a28baa3..357a3d14 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/misc.h b/src/misc.h index d3b555cb..3b141983 100644 --- a/src/misc.h +++ b/src/misc.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/move.cpp b/src/move.cpp index d09c3052..f23fcbe0 100644 --- a/src/move.cpp +++ b/src/move.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/move.h b/src/move.h index 65fcc250..ad7c8378 100644 --- a/src/move.h +++ b/src/move.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/movegen.cpp b/src/movegen.cpp index afe561f5..50f8b488 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -1,13 +1,13 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/movegen.h b/src/movegen.h index 16923dcc..94f778ff 100644 --- a/src/movegen.h +++ b/src/movegen.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/movepick.cpp b/src/movepick.cpp index 1024cbff..e1f8e4e7 100644 --- a/src/movepick.cpp +++ b/src/movepick.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/movepick.h b/src/movepick.h index af34711d..a835346d 100644 --- a/src/movepick.h +++ b/src/movepick.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/pawns.cpp b/src/pawns.cpp index e8b509cf..0089c42d 100644 --- a/src/pawns.cpp +++ b/src/pawns.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/pawns.h b/src/pawns.h index c4a616c2..95575184 100644 --- a/src/pawns.h +++ b/src/pawns.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/phase.h b/src/phase.h index a9c0958f..bc9648be 100644 --- a/src/phase.h +++ b/src/phase.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/piece.cpp b/src/piece.cpp index 737a0918..a4c2220d 100644 --- a/src/piece.cpp +++ b/src/piece.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/piece.h b/src/piece.h index 2104baa1..5b669499 100644 --- a/src/piece.h +++ b/src/piece.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/position.cpp b/src/position.cpp index 99ff223b..ff93e532 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/position.h b/src/position.h index af1ba775..48f40dac 100644 --- a/src/position.h +++ b/src/position.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/psqtab.h b/src/psqtab.h index 14156ecd..d1503444 100644 --- a/src/psqtab.h +++ b/src/psqtab.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/san.cpp b/src/san.cpp index c144407e..df169977 100644 --- a/src/san.cpp +++ b/src/san.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/san.h b/src/san.h index 087e52bd..8442ffac 100644 --- a/src/san.h +++ b/src/san.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/scale.h b/src/scale.h index 5e9af029..83858800 100644 --- a/src/scale.h +++ b/src/scale.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/search.cpp b/src/search.cpp index ee7d906e..c5d6e36b 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -301,7 +302,7 @@ History H; // Should be made local? //// Functions //// -/// think() is the external interface to Glaurung's search, and is called when +/// think() is the external interface to Stockfish's search, and is called when /// the program receives the UCI 'go' command. It initializes various /// search-related global variables, and calls root_search() diff --git a/src/search.h b/src/search.h index 106daba9..812f5eea 100644 --- a/src/search.h +++ b/src/search.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/square.cpp b/src/square.cpp index ad23d762..04a88ddf 100644 --- a/src/square.cpp +++ b/src/square.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/square.h b/src/square.h index c158c89e..ff31e865 100644 --- a/src/square.h +++ b/src/square.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/thread.h b/src/thread.h index 19844485..f2f6dd26 100644 --- a/src/thread.h +++ b/src/thread.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/tt.cpp b/src/tt.cpp index 19596932..d7037a30 100644 --- a/src/tt.cpp +++ b/src/tt.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/tt.h b/src/tt.h index c1dd8508..03ce1f55 100644 --- a/src/tt.h +++ b/src/tt.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/types.h b/src/types.h index e540afc4..869114e8 100644 --- a/src/types.h +++ b/src/types.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/uci.cpp b/src/uci.cpp index 6862a5e8..4aade3b6 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -89,7 +90,7 @@ namespace { // get_command() waits for a command from the user, and passes // this command to handle_command. get_command also intercepts // EOF from stdin, by translating EOF to the "quit" command. This - // ensures that Glaurung exits gracefully if the GUI dies + // ensures that Stockfish exits gracefully if the GUI dies // unexpectedly. void get_command() { @@ -124,8 +125,9 @@ namespace { } else if (token == "uci") { - std::cout << "id name " << engine_name() << std::endl; - std::cout << "id author Tord Romstad" << std::endl; + std::cout << "id name " << engine_name() << std::endl + << "id author Tord Romstad, Marco Costalba" + << std::endl; print_uci_options(); std::cout << "uciok" << std::endl; } @@ -184,7 +186,7 @@ namespace { } - // set_position() is called when Glaurung receives the "position" UCI + // set_position() is called when Stockfish receives the "position" UCI // command. The input parameter is a UCIInputParser. It is assumed // that this parser has consumed the first token of the UCI command // ("position"), and is ready to read the second token ("startpos" @@ -231,7 +233,7 @@ namespace { } - // set_option() is called when Glaurung receives the "setoption" UCI + // set_option() is called when Stockfish receives the "setoption" UCI // command. The input parameter is a UCIInputParser. It is assumed // that this parser has consumed the first token of the UCI command // ("setoption"), and is ready to read the second token ("name", if @@ -261,7 +263,7 @@ namespace { } - // go() is called when Glaurung receives the "go" UCI command. The + // go() is called when Stockfish receives the "go" UCI command. The // input parameter is a UCIInputParser. It is assumed that this // parser has consumed the first token of the UCI command ("go"), // and is ready to read the second token. The function sets the diff --git a/src/uci.h b/src/uci.h index 23ece63f..f442ba09 100644 --- a/src/uci.h +++ b/src/uci.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/ucioption.cpp b/src/ucioption.cpp index 14579054..919271a9 100644 --- a/src/ucioption.cpp +++ b/src/ucioption.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/ucioption.h b/src/ucioption.h index f4209de5..7d7ce714 100644 --- a/src/ucioption.h +++ b/src/ucioption.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/src/value.cpp b/src/value.cpp index a93236c5..19944091 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -59,7 +60,7 @@ Value value_from_tt(Value v, int ply) { } -/// value_to_centipawns() converts a value from Glaurung's somewhat unusual +/// value_to_centipawns() converts a value from Stockfish's somewhat unusual /// scale of pawn = 256 to the more conventional pawn = 100. int value_to_centipawns(Value v) { @@ -67,7 +68,7 @@ int value_to_centipawns(Value v) { } -/// value_from_centipawns() converts a centipawn value to Glaurung's internal +/// value_from_centipawns() converts a centipawn value to Stockfish's internal /// evaluation scale. It's used when reading the values of UCI options /// containing material values (e.g. futility pruning margins). diff --git a/src/value.h b/src/value.h index f60e286f..4e75d376 100644 --- a/src/value.h +++ b/src/value.h @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.