for (File f = FILE_A; f <= FILE_H; ++f)
os << " | " << PieceToChar[pos.piece_on(make_square(f, r))];
- os << " |\n +---+---+---+---+---+---+---+---+\n";
+ os << " | " << (1 + r) << "\n +---+---+---+---+---+---+---+---+\n";
}
- os << "\nFen: " << pos.fen() << "\nKey: " << std::hex << std::uppercase
+ os << " a b c d e f g h\n"
+ << "\nFen: " << pos.fen() << "\nKey: " << std::hex << std::uppercase
<< std::setfill('0') << std::setw(16) << pos.key()
<< std::setfill(' ') << std::dec << "\nCheckers: ";
for (Piece pc : Pieces)
for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
for (Square s2 = Square(s1 + 1); s2 <= SQ_H8; ++s2)
- if (PseudoAttacks[type_of(pc)][s1] & s2)
+ if ((type_of(pc) != PAWN) && (attacks_bb(type_of(pc), s1, 0) & s2))
{
Move move = make_move(s1, s2);
Key key = Zobrist::psq[pc][s1] ^ Zobrist::psq[pc][s2] ^ Zobrist::side;
Square rto = relative_square(c, cr & KING_SIDE ? SQ_F1 : SQ_D1);
castlingPath[cr] = (between_bb(rfrom, rto) | between_bb(kfrom, kto) | rto | kto)
- & ~(square_bb(kfrom) | rfrom);
+ & ~(kfrom | rfrom);
}
Square ksq = square<KING>(~sideToMove);
- si->checkSquares[PAWN] = attacks_from<PAWN>(ksq, ~sideToMove);
- si->checkSquares[KNIGHT] = attacks_from<KNIGHT>(ksq);
- si->checkSquares[BISHOP] = attacks_from<BISHOP>(ksq);
- si->checkSquares[ROOK] = attacks_from<ROOK>(ksq);
+ si->checkSquares[PAWN] = pawn_attacks_bb(~sideToMove, ksq);
+ si->checkSquares[KNIGHT] = attacks_bb<KNIGHT>(ksq);
+ si->checkSquares[BISHOP] = attacks_bb<BISHOP>(ksq, pieces());
+ si->checkSquares[ROOK] = attacks_bb<ROOK>(ksq, pieces());
si->checkSquares[QUEEN] = si->checkSquares[BISHOP] | si->checkSquares[ROOK];
si->checkSquares[KING] = 0;
}
Position& Position::set(const string& code, Color c, StateInfo* si) {
- assert(code.length() > 0 && code.length() < 8);
assert(code[0] == 'K');
string sides[] = { code.substr(code.find('K', 1)), // Weak
- code.substr(0, code.find('K', 1)) }; // Strong
+ code.substr(0, std::min(code.find('v'), code.find('K', 1))) }; // Strong
+
+ assert(sides[0].length() > 0 && sides[0].length() < 8);
+ assert(sides[1].length() > 0 && sides[1].length() < 8);
std::transform(sides[c].begin(), sides[c].end(), sides[c].begin(), tolower);
pinners = 0;
// Snipers are sliders that attack 's' when a piece and other snipers are removed
- Bitboard snipers = ( (PseudoAttacks[ ROOK][s] & pieces(QUEEN, ROOK))
- | (PseudoAttacks[BISHOP][s] & pieces(QUEEN, BISHOP))) & sliders;
+ Bitboard snipers = ( (attacks_bb< ROOK>(s) & pieces(QUEEN, ROOK))
+ | (attacks_bb<BISHOP>(s) & pieces(QUEEN, BISHOP))) & sliders;
Bitboard occupancy = pieces() ^ snipers;
while (snipers)
Bitboard Position::attackers_to(Square s, Bitboard occupied) const {
- return (attacks_from<PAWN>(s, BLACK) & pieces(WHITE, PAWN))
- | (attacks_from<PAWN>(s, WHITE) & pieces(BLACK, PAWN))
- | (attacks_from<KNIGHT>(s) & pieces(KNIGHT))
+ return (pawn_attacks_bb(BLACK, s) & pieces(WHITE, PAWN))
+ | (pawn_attacks_bb(WHITE, s) & pieces(BLACK, PAWN))
+ | (attacks_bb<KNIGHT>(s) & pieces(KNIGHT))
| (attacks_bb< ROOK>(s, occupied) & pieces( ROOK, QUEEN))
| (attacks_bb<BISHOP>(s, occupied) & pieces(BISHOP, QUEEN))
- | (attacks_from<KING>(s) & pieces(KING));
+ | (attacks_bb<KING>(s) & pieces(KING));
}
if ((Rank8BB | Rank1BB) & to)
return false;
- if ( !(attacks_from<PAWN>(from, us) & pieces(~us) & to) // Not a capture
+ if ( !(pawn_attacks_bb(us, from) & pieces(~us) & to) // Not a capture
&& !((from + pawn_push(us) == to) && empty(to)) // Not a single push
&& !( (from + 2 * pawn_push(us) == to) // Not a double push
- && (rank_of(from) == relative_rank(us, RANK_2))
+ && (relative_rank(us, from) == RANK_2)
&& empty(to)
&& empty(to - pawn_push(us))))
return false;
}
- else if (!(attacks_from(type_of(pc), from) & to))
+ else if (!(attacks_bb(type_of(pc), from, pieces()) & to))
return false;
// Evasions generator already takes care to avoid some kind of illegal moves
Square to = to_sq(m);
// Is there a direct check?
- if (st->checkSquares[type_of(piece_on(from))] & to)
+ if (check_squares(type_of(piece_on(from))) & to)
return true;
// Is there a discovered check?
- if ( (st->blockersForKing[~sideToMove] & from)
+ if ( (blockers_for_king(~sideToMove) & from)
&& !aligned(from, to, square<KING>(~sideToMove)))
return true;
case CASTLING:
{
Square kfrom = from;
- Square rfrom = to; // Castling is encoded as 'King captures the rook'
+ Square rfrom = to; // Castling is encoded as 'king captures the rook'
Square kto = relative_square(sideToMove, rfrom > kfrom ? SQ_G1 : SQ_C1);
Square rto = relative_square(sideToMove, rfrom > kfrom ? SQ_F1 : SQ_D1);
- return (PseudoAttacks[ROOK][rto] & square<KING>(~sideToMove))
+ return (attacks_bb<ROOK>(rto) & square<KING>(~sideToMove))
&& (attacks_bb<ROOK>(rto, (pieces() ^ kfrom ^ rfrom) | rto | kto) & square<KING>(~sideToMove));
}
default:
{
// Set en-passant square if the moved pawn can be captured
if ( (int(to) ^ int(from)) == 16
- && (attacks_from<PAWN>(to - pawn_push(us), us) & pieces(them, PAWN)))
+ && (pawn_attacks_bb(us, to - pawn_push(us)) & pieces(them, PAWN)))
{
st->epSquare = to - pawn_push(us);
k ^= Zobrist::enpassant[file_of(st->epSquare)];
// Return a draw score if a position repeats once earlier but strictly
// after the root, or repeats twice before or at the root.
- if (st->repetition && st->repetition < ply)
- return true;
-
- return false;
+ return st->repetition && st->repetition < ply;
}