/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
- Copyright (C) 2008-2010 Marco Costalba, Joona Kiiski, Tord Romstad
+ Copyright (C) 2008-2012 Marco Costalba, Joona Kiiski, Tord Romstad
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
const Score TempoValue = make_score(48, 22);
// To convert a Piece to and from a FEN char
- const string PieceToChar(".PNBRQK pnbrqk ");
+ const string PieceToChar(" PNBRQK pnbrqk .");
}
checkSq[BISHOP] = pos.attacks_from<BISHOP>(ksq);
checkSq[ROOK] = pos.attacks_from<ROOK>(ksq);
checkSq[QUEEN] = checkSq[BISHOP] | checkSq[ROOK];
- checkSq[KING] = EmptyBoardBB;
+ checkSq[KING] = 0;
}
/// or the FEN string, we want the new born Position object do not depend
/// on any external data so we detach state pointer from the source one.
-Position::Position(const Position& pos, int th) {
+void Position::copy(const Position& pos, int th) {
memcpy(this, &pos, sizeof(Position));
+ startState = *st;
+ st = &startState;
threadID = th;
nodes = 0;
Piece piece = piece_on(sq);
char c = (color_of(piece) == BLACK ? '=' : ' ');
- if (piece == PIECE_NONE && color_of(sq) == DARK)
- piece = PIECE_NONE_DARK_SQ;
+ if (piece == NO_PIECE && !opposite_colors(sq, SQ_A1))
+ piece++; // Index the dot
cout << c << PieceToChar[piece] << c << '|';
}
assert(square_is_ok(s));
- switch (p)
+ switch (type_of(p))
{
- case WB: case BB: return bishop_attacks_bb(s, occ);
- case WR: case BR: return rook_attacks_bb(s, occ);
- case WQ: case BQ: return bishop_attacks_bb(s, occ) | rook_attacks_bb(s, occ);
- default: return StepAttacksBB[p][s];
+ case BISHOP: return bishop_attacks_bb(s, occ);
+ case ROOK : return rook_attacks_bb(s, occ);
+ case QUEEN : return bishop_attacks_bb(s, occ) | rook_attacks_bb(s, occ);
+ default : return StepAttacksBB[p][s];
}
}
assert(square_is_ok(s));
Bitboard occ, xray;
- Square from = move_from(m);
- Square to = move_to(m);
+ Square from = from_sq(m);
+ Square to = to_sq(m);
Piece piece = piece_on(from);
assert(!square_is_empty(from));
assert(pinned == pinned_pieces());
Color us = side_to_move();
- Square from = move_from(m);
+ Square from = from_sq(m);
assert(color_of(piece_on(from)) == us);
assert(piece_on(king_square(us)) == make_piece(us, KING));
if (is_enpassant(m))
{
Color them = flip(us);
- Square to = move_to(m);
+ Square to = to_sq(m);
Square capsq = to + pawn_push(them);
Square ksq = king_square(us);
Bitboard b = occupied_squares();
assert(to == ep_square());
assert(piece_on(from) == make_piece(us, PAWN));
assert(piece_on(capsq) == make_piece(them, PAWN));
- assert(piece_on(to) == PIECE_NONE);
+ assert(piece_on(to) == NO_PIECE);
clear_bit(&b, from);
clear_bit(&b, capsq);
// square is attacked by the opponent. Castling moves are checked
// for legality during move generation.
if (type_of(piece_on(from)) == KING)
- return is_castle(m) || !(attackers_to(move_to(m)) & pieces(flip(us)));
+ return is_castle(m) || !(attackers_to(to_sq(m)) & pieces(flip(us)));
// A non-king move is legal if and only if it is not pinned or it
// is moving along the ray towards or away from the king.
return !pinned
|| !bit_is_set(pinned, from)
- || squares_aligned(from, move_to(m), king_square(us));
+ || squares_aligned(from, to_sq(m), king_square(us));
}
Color us = sideToMove;
Color them = flip(sideToMove);
- Square from = move_from(m);
- Square to = move_to(m);
+ Square from = from_sq(m);
+ Square to = to_sq(m);
Piece pc = piece_on(from);
// Use a slower but simpler function for uncommon cases
return move_is_legal(m);
// Is not a promotion, so promotion piece must be empty
- if (promotion_piece_type(m) - 2 != PIECE_TYPE_NONE)
+ if (promotion_piece_type(m) - 2 != NO_PIECE_TYPE)
return false;
// If the from square is not occupied by a piece belonging to the side to
// move, the move is obviously not legal.
- if (pc == PIECE_NONE || color_of(pc) != us)
+ if (pc == NO_PIECE || color_of(pc) != us)
return false;
// The destination square cannot be occupied by a friendly piece
{
Bitboard b = occupied_squares();
clear_bit(&b, from);
- if (attackers_to(move_to(m), b) & pieces(flip(us)))
+ if (attackers_to(to_sq(m), b) & pieces(flip(us)))
return false;
}
else
// Our move must be a blocking evasion or a capture of the checking piece
target = squares_between(checksq, king_square(us)) | checkers();
- if (!bit_is_set(target, move_to(m)))
+ if (!bit_is_set(target, to_sq(m)))
return false;
}
}
assert(is_ok(m));
assert(ci.dcCandidates == discovered_check_candidates());
- assert(color_of(piece_on(move_from(m))) == side_to_move());
+ assert(color_of(piece_on(from_sq(m))) == side_to_move());
- Square from = move_from(m);
- Square to = move_to(m);
+ Square from = from_sq(m);
+ Square to = to_sq(m);
PieceType pt = type_of(piece_on(from));
// Direct check ?
assert(&newSt != st);
nodes++;
- Key key = st->key;
+ Key k = st->key;
// Copy some fields of old state to our new StateInfo object except the ones
// which are recalculated from scratch anyway, then switch our state pointer
st = &newSt;
// Update side to move
- key ^= zobSideToMove;
+ k ^= zobSideToMove;
// Increment the 50 moves rule draw counter. Resetting it to zero in the
// case of non-reversible moves is taken care of later.
if (is_castle(m))
{
- st->key = key;
+ st->key = k;
do_castle_move<true>(m);
return;
}
Color us = side_to_move();
Color them = flip(us);
- Square from = move_from(m);
- Square to = move_to(m);
+ Square from = from_sq(m);
+ Square to = to_sq(m);
Piece piece = piece_on(from);
PieceType pt = type_of(piece);
PieceType capture = is_enpassant(m) ? PAWN : type_of(piece_on(to));
assert(pt == PAWN);
assert(to == st->epSquare);
assert(relative_rank(us, to) == RANK_6);
- assert(piece_on(to) == PIECE_NONE);
+ assert(piece_on(to) == NO_PIECE);
assert(piece_on(capsq) == make_piece(them, PAWN));
- board[capsq] = PIECE_NONE;
+ board[capsq] = NO_PIECE;
}
st->pawnKey ^= zobrist[them][PAWN][capsq];
pieceList[them][capture][pieceCount[them][capture]] = SQ_NONE;
// Update hash keys
- key ^= zobrist[them][capture][capsq];
+ k ^= zobrist[them][capture][capsq];
st->materialKey ^= zobrist[them][capture][pieceCount[them][capture]];
// Update incremental scores
}
// Update hash key
- key ^= zobrist[us][pt][from] ^ zobrist[us][pt][to];
+ k ^= zobrist[us][pt][from] ^ zobrist[us][pt][to];
// Reset en passant square
if (st->epSquare != SQ_NONE)
{
- key ^= zobEp[st->epSquare];
+ k ^= zobEp[st->epSquare];
st->epSquare = SQ_NONE;
}
if ( st->castleRights != CASTLES_NONE
&& (castleRightsMask[from] & castleRightsMask[to]) != ALL_CASTLES)
{
- key ^= zobCastle[st->castleRights];
+ k ^= zobCastle[st->castleRights];
st->castleRights &= castleRightsMask[from] & castleRightsMask[to];
- key ^= zobCastle[st->castleRights];
+ k ^= zobCastle[st->castleRights];
}
// Prefetch TT access as soon as we know key is updated
- prefetch((char*)TT.first_entry(key));
+ prefetch((char*)TT.first_entry(k));
// Move the piece
Bitboard move_bb = make_move_bb(from, to);
do_move_bb(&occupied, move_bb);
board[to] = board[from];
- board[from] = PIECE_NONE;
+ board[from] = NO_PIECE;
// Update piece lists, index[from] is not updated and becomes stale. This
// works as long as index[] is accessed just by known occupied squares.
&& (attacks_from<PAWN>(from + pawn_push(us), us) & pieces(PAWN, them)))
{
st->epSquare = Square((from + to) / 2);
- key ^= zobEp[st->epSquare];
+ k ^= zobEp[st->epSquare];
}
if (is_promotion(m))
pieceList[us][promotion][index[to]] = to;
// Update hash keys
- key ^= zobrist[us][PAWN][to] ^ zobrist[us][promotion][to];
+ k ^= zobrist[us][PAWN][to] ^ zobrist[us][promotion][to];
st->pawnKey ^= zobrist[us][PAWN][to];
st->materialKey ^= zobrist[us][promotion][pieceCount[us][promotion]++]
^ zobrist[us][PAWN][pieceCount[us][PAWN]];
st->capturedType = capture;
// Update the key with the final value
- st->key = key;
+ st->key = k;
// Update checkers bitboard, piece must be already moved
- st->checkersBB = EmptyBoardBB;
+ st->checkersBB = 0;
if (moveIsCheck)
{
Color us = side_to_move();
Color them = flip(us);
- Square from = move_from(m);
- Square to = move_to(m);
+ Square from = from_sq(m);
+ Square to = to_sq(m);
Piece piece = piece_on(to);
PieceType pt = type_of(piece);
PieceType capture = st->capturedType;
do_move_bb(&occupied, move_bb);
board[from] = board[to];
- board[to] = PIECE_NONE;
+ board[to] = NO_PIECE;
// Update piece lists, index[to] is not updated and becomes stale. This
// works as long as index[] is accessed just by known occupied squares.
assert(pt == PAWN);
assert(to == st->previous->epSquare);
assert(relative_rank(us, to) == RANK_6);
- assert(piece_on(capsq) == PIECE_NONE);
+ assert(piece_on(capsq) == NO_PIECE);
}
// Restore the captured piece
Square kto, kfrom, rfrom, rto, kAfter, rAfter;
Color us = side_to_move();
- Square kBefore = move_from(m);
- Square rBefore = move_to(m);
+ Square kBefore = from_sq(m);
+ Square rBefore = to_sq(m);
// Find after-castle squares for king and rook
if (rBefore > kBefore) // O-O
// Update board
Piece king = make_piece(us, KING);
Piece rook = make_piece(us, ROOK);
- board[kfrom] = board[rfrom] = PIECE_NONE;
+ board[kfrom] = board[rfrom] = NO_PIECE;
board[kto] = king;
board[rto] = rook;
if (Do)
{
// Reset capture field
- st->capturedType = PIECE_TYPE_NONE;
+ st->capturedType = NO_PIECE_TYPE;
// Update incremental scores
st->value += pst_delta(king, kfrom, kto);
assert(is_ok(m));
- Square from = move_from(m);
- Square to = move_to(m);
+ Square from = from_sq(m);
+ Square to = to_sq(m);
// Early return if SEE cannot be negative because captured piece value
// is not less then capturing one. Note that king moves always return
if (is_castle(m))
return 0;
- from = move_from(m);
- to = move_to(m);
+ from = from_sq(m);
+ to = to_sq(m);
capturedType = type_of(piece_on(to));
occ = occupied_squares();
{
Square capQq = to - pawn_push(side_to_move());
- assert(capturedType == PIECE_TYPE_NONE);
+ assert(capturedType == NO_PIECE_TYPE);
assert(type_of(piece_on(capQq)) == PAWN);
// Remove the captured pawn
for (Square sq = SQ_A1; sq <= SQ_H8; sq++)
{
- board[sq] = PIECE_NONE;
+ board[sq] = NO_PIECE;
castleRightsMask[sq] = ALL_CASTLES;
}
sideToMove = WHITE;
zobSideToMove = rk.rand<Key>();
zobExclusion = rk.rand<Key>();
- for (Piece p = WP; p <= WK; p++)
+ for (Piece p = W_PAWN; p <= W_KING; p++)
{
Score ps = make_score(PieceValueMidgame[p], PieceValueEndgame[p]);
// Are the king squares in the position correct?
if (failedStep) (*failedStep)++;
- if (piece_on(king_square(WHITE)) != WK)
+ if (piece_on(king_square(WHITE)) != W_KING)
return false;
if (failedStep) (*failedStep)++;
- if (piece_on(king_square(BLACK)) != BK)
+ if (piece_on(king_square(BLACK)) != B_KING)
return false;
// Do both sides have exactly one king?
// Is there more than 2 checkers?
if (failedStep) (*failedStep)++;
- if (debugCheckerCount && count_1s<CNT32>(st->checkersBB) > 2)
+ if (debugCheckerCount && popcount<Full>(st->checkersBB) > 2)
return false;
// Bitboards OK?
if (debugBitboards)
{
// The intersection of the white and black pieces must be empty
- if ((pieces(WHITE) & pieces(BLACK)) != EmptyBoardBB)
+ if (!(pieces(WHITE) & pieces(BLACK)))
return false;
// The union of the white and black pieces must be equal to all
if (debugPieceCounts)
for (Color c = WHITE; c <= BLACK; c++)
for (PieceType pt = PAWN; pt <= KING; pt++)
- if (pieceCount[c][pt] != count_1s<CNT32>(pieces(pt, c)))
+ if (pieceCount[c][pt] != popcount<Full>(pieces(pt, c)))
return false;
if (failedStep) (*failedStep)++;
if (!can_castle(f))
continue;
- Piece rook = (f & (WHITE_OO | WHITE_OOO) ? WR : BR);
+ Piece rook = (f & (WHITE_OO | WHITE_OOO) ? W_ROOK : B_ROOK);
if ( castleRightsMask[castleRookSquare[f]] != (ALL_CASTLES ^ f)
|| piece_on(castleRookSquare[f]) != rook)