Change from [Color][PieceType] to [Piece]

Speed up of almost 1% in both normal and
pgo builds.

No functional change.
This commit is contained in:
syzygy
2016-09-03 18:14:01 +02:00
committed by Marco Costalba
parent c5828c4eba
commit ca6c9f85a5
6 changed files with 124 additions and 119 deletions

View File

@@ -36,7 +36,7 @@ using std::string;
namespace Zobrist { namespace Zobrist {
Key psq[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; Key psq[PIECE_NB][SQUARE_NB];
Key enpassant[FILE_NB]; Key enpassant[FILE_NB];
Key castling[CASTLING_RIGHT_NB]; Key castling[CASTLING_RIGHT_NB];
Key side; Key side;
@@ -112,7 +112,7 @@ void Position::init() {
for (Color c = WHITE; c <= BLACK; ++c) for (Color c = WHITE; c <= BLACK; ++c)
for (PieceType pt = PAWN; pt <= KING; ++pt) for (PieceType pt = PAWN; pt <= KING; ++pt)
for (Square s = SQ_A1; s <= SQ_H8; ++s) for (Square s = SQ_A1; s <= SQ_H8; ++s)
Zobrist::psq[c][pt][s] = rng.rand<Key>(); Zobrist::psq[make_piece(c, pt)][s] = rng.rand<Key>();
for (File f = FILE_A; f <= FILE_H; ++f) for (File f = FILE_A; f <= FILE_H; ++f)
Zobrist::enpassant[f] = rng.rand<Key>(); Zobrist::enpassant[f] = rng.rand<Key>();
@@ -178,7 +178,7 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th
std::memset(this, 0, sizeof(Position)); std::memset(this, 0, sizeof(Position));
std::memset(si, 0, sizeof(StateInfo)); std::memset(si, 0, sizeof(StateInfo));
std::fill_n(&pieceList[0][0][0], sizeof(pieceList) / sizeof(Square), SQ_NONE); std::fill_n(&pieceList[0][0], sizeof(pieceList) / sizeof(Square), SQ_NONE);
st = si; st = si;
ss >> std::noskipws; ss >> std::noskipws;
@@ -194,7 +194,7 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th
else if ((idx = PieceToChar.find(token)) != string::npos) else if ((idx = PieceToChar.find(token)) != string::npos)
{ {
put_piece(color_of(Piece(idx)), type_of(Piece(idx)), sq); put_piece(Piece(idx), sq);
++sq; ++sq;
} }
} }
@@ -324,8 +324,8 @@ void Position::set_state(StateInfo* si) const {
{ {
Square s = pop_lsb(&b); Square s = pop_lsb(&b);
Piece pc = piece_on(s); Piece pc = piece_on(s);
si->key ^= Zobrist::psq[color_of(pc)][type_of(pc)][s]; si->key ^= Zobrist::psq[pc][s];
si->psq += PSQT::psq[color_of(pc)][type_of(pc)][s]; si->psq += PSQT::psq[pc][s];
} }
if (si->epSquare != SQ_NONE) if (si->epSquare != SQ_NONE)
@@ -339,17 +339,17 @@ void Position::set_state(StateInfo* si) const {
for (Bitboard b = pieces(PAWN); b; ) for (Bitboard b = pieces(PAWN); b; )
{ {
Square s = pop_lsb(&b); Square s = pop_lsb(&b);
si->pawnKey ^= Zobrist::psq[color_of(piece_on(s))][PAWN][s]; si->pawnKey ^= Zobrist::psq[piece_on(s)][s];
} }
for (Color c = WHITE; c <= BLACK; ++c) for (Color c = WHITE; c <= BLACK; ++c)
for (PieceType pt = PAWN; pt <= KING; ++pt) for (PieceType pt = PAWN; pt <= KING; ++pt)
for (int cnt = 0; cnt < pieceCount[c][pt]; ++cnt) for (int cnt = 0; cnt < pieceCount[make_piece(c, pt)]; ++cnt)
si->materialKey ^= Zobrist::psq[c][pt][cnt]; si->materialKey ^= Zobrist::psq[make_piece(c, pt)][cnt];
for (Color c = WHITE; c <= BLACK; ++c) for (Color c = WHITE; c <= BLACK; ++c)
for (PieceType pt = KNIGHT; pt <= QUEEN; ++pt) for (PieceType pt = KNIGHT; pt <= QUEEN; ++pt)
si->nonPawnMaterial[c] += pieceCount[c][pt] * PieceValue[MG][pt]; si->nonPawnMaterial[c] += pieceCount[make_piece(c, pt)] * PieceValue[MG][pt];
} }
@@ -657,23 +657,24 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
Color them = ~us; Color them = ~us;
Square from = from_sq(m); Square from = from_sq(m);
Square to = to_sq(m); Square to = to_sq(m);
PieceType pt = type_of(piece_on(from)); Piece pc = piece_on(from);
PieceType captured = type_of(m) == ENPASSANT ? PAWN : type_of(piece_on(to)); Piece captured = type_of(m) == ENPASSANT ? make_piece(them, PAWN) : piece_on(to);
assert(color_of(piece_on(from)) == us); assert(color_of(pc) == us);
assert(piece_on(to) == NO_PIECE || color_of(piece_on(to)) == (type_of(m) != CASTLING ? them : us)); assert(captured == NO_PIECE || color_of(captured) == (type_of(m) != CASTLING ? them : us));
assert(captured != KING); assert(type_of(captured) != KING);
if (type_of(m) == CASTLING) if (type_of(m) == CASTLING)
{ {
assert(pt == KING); assert(pc == make_piece(us, KING));
assert(captured == make_piece(us, ROOK));
Square rfrom, rto; Square rfrom, rto;
do_castling<true>(us, from, to, rfrom, rto); do_castling<true>(us, from, to, rfrom, rto);
captured = NO_PIECE_TYPE; st->psq += PSQT::psq[captured][rto] - PSQT::psq[captured][rfrom];
st->psq += PSQT::psq[us][ROOK][rto] - PSQT::psq[us][ROOK][rfrom]; k ^= Zobrist::psq[captured][rfrom] ^ Zobrist::psq[captured][rto];
k ^= Zobrist::psq[us][ROOK][rfrom] ^ Zobrist::psq[us][ROOK][rto]; captured = NO_PIECE;
} }
if (captured) if (captured)
@@ -682,13 +683,13 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
// If the captured piece is a pawn, update pawn hash key, otherwise // If the captured piece is a pawn, update pawn hash key, otherwise
// update non-pawn material. // update non-pawn material.
if (captured == PAWN) if (type_of(captured) == PAWN)
{ {
if (type_of(m) == ENPASSANT) if (type_of(m) == ENPASSANT)
{ {
capsq -= pawn_push(us); capsq -= pawn_push(us);
assert(pt == PAWN); assert(pc == make_piece(us, PAWN));
assert(to == st->epSquare); assert(to == st->epSquare);
assert(relative_rank(us, to) == RANK_6); assert(relative_rank(us, to) == RANK_6);
assert(piece_on(to) == NO_PIECE); assert(piece_on(to) == NO_PIECE);
@@ -697,28 +698,28 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
board[capsq] = NO_PIECE; // Not done by remove_piece() board[capsq] = NO_PIECE; // Not done by remove_piece()
} }
st->pawnKey ^= Zobrist::psq[them][PAWN][capsq]; st->pawnKey ^= Zobrist::psq[captured][capsq];
} }
else else
st->nonPawnMaterial[them] -= PieceValue[MG][captured]; st->nonPawnMaterial[them] -= PieceValue[MG][captured];
// Update board and piece lists // Update board and piece lists
remove_piece(them, captured, capsq); remove_piece(captured, capsq);
// Update material hash key and prefetch access to materialTable // Update material hash key and prefetch access to materialTable
k ^= Zobrist::psq[them][captured][capsq]; k ^= Zobrist::psq[captured][capsq];
st->materialKey ^= Zobrist::psq[them][captured][pieceCount[them][captured]]; st->materialKey ^= Zobrist::psq[captured][pieceCount[captured]];
prefetch(thisThread->materialTable[st->materialKey]); prefetch(thisThread->materialTable[st->materialKey]);
// Update incremental scores // Update incremental scores
st->psq -= PSQT::psq[them][captured][capsq]; st->psq -= PSQT::psq[captured][capsq];
// Reset rule 50 counter // Reset rule 50 counter
st->rule50 = 0; st->rule50 = 0;
} }
// Update hash key // Update hash key
k ^= Zobrist::psq[us][pt][from] ^ Zobrist::psq[us][pt][to]; k ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
// Reset en passant square // Reset en passant square
if (st->epSquare != SQ_NONE) if (st->epSquare != SQ_NONE)
@@ -737,10 +738,10 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
// Move the piece. The tricky Chess960 castling is handled earlier // Move the piece. The tricky Chess960 castling is handled earlier
if (type_of(m) != CASTLING) if (type_of(m) != CASTLING)
move_piece(us, pt, from, to); move_piece(pc, from, to);
// If the moving piece is a pawn do some special extra work // If the moving piece is a pawn do some special extra work
if (pt == PAWN) if (type_of(pc) == PAWN)
{ {
// Set en-passant square if the moved pawn can be captured // Set en-passant square if the moved pawn can be captured
if ( (int(to) ^ int(from)) == 16 if ( (int(to) ^ int(from)) == 16
@@ -752,29 +753,29 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
else if (type_of(m) == PROMOTION) else if (type_of(m) == PROMOTION)
{ {
PieceType promotion = promotion_type(m); Piece promotion = make_piece(us, promotion_type(m));
assert(relative_rank(us, to) == RANK_8); assert(relative_rank(us, to) == RANK_8);
assert(promotion >= KNIGHT && promotion <= QUEEN); assert(type_of(promotion) >= KNIGHT && type_of(promotion) <= QUEEN);
remove_piece(us, PAWN, to); remove_piece(pc, to);
put_piece(us, promotion, to); put_piece(promotion, to);
// Update hash keys // Update hash keys
k ^= Zobrist::psq[us][PAWN][to] ^ Zobrist::psq[us][promotion][to]; k ^= Zobrist::psq[pc][to] ^ Zobrist::psq[promotion][to];
st->pawnKey ^= Zobrist::psq[us][PAWN][to]; st->pawnKey ^= Zobrist::psq[pc][to];
st->materialKey ^= Zobrist::psq[us][promotion][pieceCount[us][promotion]-1] st->materialKey ^= Zobrist::psq[promotion][pieceCount[promotion]-1]
^ Zobrist::psq[us][PAWN][pieceCount[us][PAWN]]; ^ Zobrist::psq[pc][pieceCount[pc]];
// Update incremental score // Update incremental score
st->psq += PSQT::psq[us][promotion][to] - PSQT::psq[us][PAWN][to]; st->psq += PSQT::psq[promotion][to] - PSQT::psq[pc][to];
// Update material // Update material
st->nonPawnMaterial[us] += PieceValue[MG][promotion]; st->nonPawnMaterial[us] += PieceValue[MG][promotion];
} }
// Update pawn hash key and prefetch access to pawnsTable // Update pawn hash key and prefetch access to pawnsTable
st->pawnKey ^= Zobrist::psq[us][PAWN][from] ^ Zobrist::psq[us][PAWN][to]; st->pawnKey ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
prefetch(thisThread->pawnsTable[st->pawnKey]); prefetch(thisThread->pawnsTable[st->pawnKey]);
// Reset rule 50 draw counter // Reset rule 50 draw counter
@@ -782,10 +783,10 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
} }
// Update incremental scores // Update incremental scores
st->psq += PSQT::psq[us][pt][to] - PSQT::psq[us][pt][from]; st->psq += PSQT::psq[pc][to] - PSQT::psq[pc][from];
// Set capture piece // Set capture piece
st->capturedType = captured; st->capturedPiece = captured;
// Update the key with the final value // Update the key with the final value
st->key = k; st->key = k;
@@ -814,20 +815,20 @@ void Position::undo_move(Move m) {
Color us = sideToMove; Color us = sideToMove;
Square from = from_sq(m); Square from = from_sq(m);
Square to = to_sq(m); Square to = to_sq(m);
PieceType pt = type_of(piece_on(to)); Piece pc = piece_on(to);
assert(empty(from) || type_of(m) == CASTLING); assert(empty(from) || type_of(m) == CASTLING);
assert(st->capturedType != KING); assert(type_of(st->capturedPiece) != KING);
if (type_of(m) == PROMOTION) if (type_of(m) == PROMOTION)
{ {
assert(relative_rank(us, to) == RANK_8); assert(relative_rank(us, to) == RANK_8);
assert(pt == promotion_type(m)); assert(type_of(pc) == promotion_type(m));
assert(pt >= KNIGHT && pt <= QUEEN); assert(type_of(pc) >= KNIGHT && type_of(pc) <= QUEEN);
remove_piece(us, pt, to); remove_piece(pc, to);
put_piece(us, PAWN, to); pc = make_piece(us, PAWN);
pt = PAWN; put_piece(pc, to);
} }
if (type_of(m) == CASTLING) if (type_of(m) == CASTLING)
@@ -837,9 +838,9 @@ void Position::undo_move(Move m) {
} }
else else
{ {
move_piece(us, pt, to, from); // Put the piece back at the source square move_piece(pc, to, from); // Put the piece back at the source square
if (st->capturedType) if (st->capturedPiece)
{ {
Square capsq = to; Square capsq = to;
@@ -847,14 +848,14 @@ void Position::undo_move(Move m) {
{ {
capsq -= pawn_push(us); capsq -= pawn_push(us);
assert(pt == PAWN); assert(type_of(pc) == PAWN);
assert(to == st->previous->epSquare); assert(to == st->previous->epSquare);
assert(relative_rank(us, to) == RANK_6); assert(relative_rank(us, to) == RANK_6);
assert(piece_on(capsq) == NO_PIECE); assert(piece_on(capsq) == NO_PIECE);
assert(st->capturedType == PAWN); assert(st->capturedPiece == make_piece(~us, PAWN));
} }
put_piece(~us, st->capturedType, capsq); // Restore the captured piece put_piece(st->capturedPiece, capsq); // Restore the captured piece
} }
} }
@@ -867,7 +868,7 @@ void Position::undo_move(Move m) {
/// Position::do_castling() is a helper used to do/undo a castling move. This /// Position::do_castling() is a helper used to do/undo a castling move. This
/// is a bit tricky, especially in Chess960. /// is a bit tricky in Chess960 where from/to squares can overlap.
template<bool Do> template<bool Do>
void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto) { void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto) {
@@ -877,11 +878,11 @@ void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Squ
to = relative_square(us, kingSide ? SQ_G1 : SQ_C1); to = relative_square(us, kingSide ? SQ_G1 : SQ_C1);
// Remove both pieces first since squares could overlap in Chess960 // Remove both pieces first since squares could overlap in Chess960
remove_piece(us, KING, Do ? from : to); remove_piece(make_piece(us, KING), Do ? from : to);
remove_piece(us, ROOK, Do ? rfrom : rto); remove_piece(make_piece(us, ROOK), Do ? rfrom : rto);
board[Do ? from : to] = board[Do ? rfrom : rto] = NO_PIECE; // Since remove_piece doesn't do it for us board[Do ? from : to] = board[Do ? rfrom : rto] = NO_PIECE; // Since remove_piece doesn't do it for us
put_piece(us, KING, Do ? to : from); put_piece(make_piece(us, KING), Do ? to : from);
put_piece(us, ROOK, Do ? rto : rfrom); put_piece(make_piece(us, ROOK), Do ? rto : rfrom);
} }
@@ -931,17 +932,16 @@ void Position::undo_null_move() {
Key Position::key_after(Move m) const { Key Position::key_after(Move m) const {
Color us = sideToMove;
Square from = from_sq(m); Square from = from_sq(m);
Square to = to_sq(m); Square to = to_sq(m);
PieceType pt = type_of(piece_on(from)); Piece pc = piece_on(from);
PieceType captured = type_of(piece_on(to)); Piece captured = piece_on(to);
Key k = st->key ^ Zobrist::side; Key k = st->key ^ Zobrist::side;
if (captured) if (captured)
k ^= Zobrist::psq[~us][captured][to]; k ^= Zobrist::psq[captured][to];
return k ^ Zobrist::psq[us][pt][to] ^ Zobrist::psq[us][pt][from]; return k ^ Zobrist::psq[pc][to] ^ Zobrist::psq[pc][from];
} }
@@ -1139,12 +1139,13 @@ bool Position::pos_is_ok(int* failedStep) const {
for (Color c = WHITE; c <= BLACK; ++c) for (Color c = WHITE; c <= BLACK; ++c)
for (PieceType pt = PAWN; pt <= KING; ++pt) for (PieceType pt = PAWN; pt <= KING; ++pt)
{ {
if (pieceCount[c][pt] != popcount(pieces(c, pt))) Piece pc = make_piece(c, pt);
if (pieceCount[pc] != popcount(pieces(c, pt)))
return false; return false;
for (int i = 0; i < pieceCount[c][pt]; ++i) for (int i = 0; i < pieceCount[pc]; ++i)
if ( board[pieceList[c][pt][i]] != make_piece(c, pt) if (board[pieceList[pc][i]] != pc || index[pieceList[pc][i]] != i)
|| index[pieceList[c][pt][i]] != i)
return false; return false;
} }

View File

@@ -36,7 +36,7 @@ class Thread;
namespace PSQT { namespace PSQT {
extern Score psq[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; extern Score psq[PIECE_NB][SQUARE_NB];
void init(); void init();
} }
@@ -61,7 +61,7 @@ struct StateInfo {
// Not copied when making a move // Not copied when making a move
Key key; Key key;
Bitboard checkersBB; Bitboard checkersBB;
PieceType capturedType; Piece capturedPiece;
StateInfo* previous; StateInfo* previous;
Bitboard blockersForKing[COLOR_NB]; Bitboard blockersForKing[COLOR_NB];
Bitboard checkSquares[PIECE_TYPE_NB]; Bitboard checkSquares[PIECE_TYPE_NB];
@@ -131,7 +131,7 @@ public:
bool gives_check(Move m) const; bool gives_check(Move m) const;
bool advanced_pawn_push(Move m) const; bool advanced_pawn_push(Move m) const;
Piece moved_piece(Move m) const; Piece moved_piece(Move m) const;
PieceType captured_piece_type() const; Piece captured_piece() const;
// Piece specific // Piece specific
bool pawn_passed(Color c, Square s) const; bool pawn_passed(Color c, Square s) const;
@@ -177,9 +177,9 @@ private:
void set_check_info(StateInfo* si) const; void set_check_info(StateInfo* si) const;
// Other helpers // Other helpers
void put_piece(Color c, PieceType pt, Square s); void put_piece(Piece pc, Square s);
void remove_piece(Color c, PieceType pt, Square s); void remove_piece(Piece pc, Square s);
void move_piece(Color c, PieceType pt, Square from, Square to); void move_piece(Piece pc, Square from, Square to);
template<bool Do> template<bool Do>
void do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto); void do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto);
@@ -187,8 +187,8 @@ private:
Piece board[SQUARE_NB]; Piece board[SQUARE_NB];
Bitboard byTypeBB[PIECE_TYPE_NB]; Bitboard byTypeBB[PIECE_TYPE_NB];
Bitboard byColorBB[COLOR_NB]; Bitboard byColorBB[COLOR_NB];
int pieceCount[COLOR_NB][PIECE_TYPE_NB]; int pieceCount[PIECE_NB];
Square pieceList[COLOR_NB][PIECE_TYPE_NB][16]; Square pieceList[PIECE_NB][16];
int index[SQUARE_NB]; int index[SQUARE_NB];
int castlingRightsMask[SQUARE_NB]; int castlingRightsMask[SQUARE_NB];
Square castlingRookSquare[CASTLING_RIGHT_NB]; Square castlingRookSquare[CASTLING_RIGHT_NB];
@@ -244,16 +244,16 @@ inline Bitboard Position::pieces(Color c, PieceType pt1, PieceType pt2) const {
} }
template<PieceType Pt> inline int Position::count(Color c) const { template<PieceType Pt> inline int Position::count(Color c) const {
return pieceCount[c][Pt]; return pieceCount[make_piece(c, Pt)];
} }
template<PieceType Pt> inline const Square* Position::squares(Color c) const { template<PieceType Pt> inline const Square* Position::squares(Color c) const {
return pieceList[c][Pt]; return pieceList[make_piece(c, Pt)];
} }
template<PieceType Pt> inline Square Position::square(Color c) const { template<PieceType Pt> inline Square Position::square(Color c) const {
assert(pieceCount[c][Pt] == 1); assert(pieceCount[make_piece(c, Pt)] == 1);
return pieceList[c][Pt][0]; return pieceList[make_piece(c, Pt)][0];
} }
inline Square Position::ep_square() const { inline Square Position::ep_square() const {
@@ -358,8 +358,8 @@ inline void Position::set_nodes_searched(uint64_t n) {
} }
inline bool Position::opposite_bishops() const { inline bool Position::opposite_bishops() const {
return pieceCount[WHITE][BISHOP] == 1 return pieceCount[W_BISHOP] == 1
&& pieceCount[BLACK][BISHOP] == 1 && pieceCount[B_BISHOP] == 1
&& opposite_colors(square<BISHOP>(WHITE), square<BISHOP>(BLACK)); && opposite_colors(square<BISHOP>(WHITE), square<BISHOP>(BLACK));
} }
@@ -380,54 +380,54 @@ inline bool Position::capture(Move m) const {
return (!empty(to_sq(m)) && type_of(m) != CASTLING) || type_of(m) == ENPASSANT; return (!empty(to_sq(m)) && type_of(m) != CASTLING) || type_of(m) == ENPASSANT;
} }
inline PieceType Position::captured_piece_type() const { inline Piece Position::captured_piece() const {
return st->capturedType; return st->capturedPiece;
} }
inline Thread* Position::this_thread() const { inline Thread* Position::this_thread() const {
return thisThread; return thisThread;
} }
inline void Position::put_piece(Color c, PieceType pt, Square s) { inline void Position::put_piece(Piece pc, Square s) {
board[s] = make_piece(c, pt); board[s] = pc;
byTypeBB[ALL_PIECES] |= s; byTypeBB[ALL_PIECES] |= s;
byTypeBB[pt] |= s; byTypeBB[type_of(pc)] |= s;
byColorBB[c] |= s; byColorBB[color_of(pc)] |= s;
index[s] = pieceCount[c][pt]++; index[s] = pieceCount[pc]++;
pieceList[c][pt][index[s]] = s; pieceList[pc][index[s]] = s;
pieceCount[c][ALL_PIECES]++; pieceCount[make_piece(color_of(pc), ALL_PIECES)]++;
} }
inline void Position::remove_piece(Color c, PieceType pt, Square s) { inline void Position::remove_piece(Piece pc, Square s) {
// WARNING: This is not a reversible operation. If we remove a piece in // WARNING: This is not a reversible operation. If we remove a piece in
// do_move() and then replace it in undo_move() we will put it at the end of // do_move() and then replace it in undo_move() we will put it at the end of
// the list and not in its original place, it means index[] and pieceList[] // the list and not in its original place, it means index[] and pieceList[]
// are not guaranteed to be invariant to a do_move() + undo_move() sequence. // are not guaranteed to be invariant to a do_move() + undo_move() sequence.
byTypeBB[ALL_PIECES] ^= s; byTypeBB[ALL_PIECES] ^= s;
byTypeBB[pt] ^= s; byTypeBB[type_of(pc)] ^= s;
byColorBB[c] ^= s; byColorBB[color_of(pc)] ^= s;
/* board[s] = NO_PIECE; Not needed, overwritten by the capturing one */ /* board[s] = NO_PIECE; Not needed, overwritten by the capturing one */
Square lastSquare = pieceList[c][pt][--pieceCount[c][pt]]; Square lastSquare = pieceList[pc][--pieceCount[pc]];
index[lastSquare] = index[s]; index[lastSquare] = index[s];
pieceList[c][pt][index[lastSquare]] = lastSquare; pieceList[pc][index[lastSquare]] = lastSquare;
pieceList[c][pt][pieceCount[c][pt]] = SQ_NONE; pieceList[pc][pieceCount[pc]] = SQ_NONE;
pieceCount[c][ALL_PIECES]--; pieceCount[make_piece(color_of(pc), ALL_PIECES)]--;
} }
inline void Position::move_piece(Color c, PieceType pt, Square from, Square to) { inline void Position::move_piece(Piece pc, Square from, Square to) {
// index[from] is not updated and becomes stale. This works as long as index[] // index[from] is not updated and becomes stale. This works as long as index[]
// is accessed just by known occupied squares. // is accessed just by known occupied squares.
Bitboard from_to_bb = SquareBB[from] ^ SquareBB[to]; Bitboard from_to_bb = SquareBB[from] ^ SquareBB[to];
byTypeBB[ALL_PIECES] ^= from_to_bb; byTypeBB[ALL_PIECES] ^= from_to_bb;
byTypeBB[pt] ^= from_to_bb; byTypeBB[type_of(pc)] ^= from_to_bb;
byColorBB[c] ^= from_to_bb; byColorBB[color_of(pc)] ^= from_to_bb;
board[from] = NO_PIECE; board[from] = NO_PIECE;
board[to] = make_piece(c, pt); board[to] = pc;
index[to] = index[from]; index[to] = index[from];
pieceList[c][pt][index[to]] = to; pieceList[pc][index[to]] = to;
} }
#endif // #ifndef POSITION_H_INCLUDED #endif // #ifndef POSITION_H_INCLUDED

View File

@@ -99,25 +99,25 @@ const Score Bonus[][RANK_NB][int(FILE_NB) / 2] = {
#undef S #undef S
Score psq[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; Score psq[PIECE_NB][SQUARE_NB];
// init() initializes piece-square tables: the white halves of the tables are // init() initializes piece-square tables: the white halves of the tables are
// copied from Bonus[] adding the piece value, then the black halves of the // copied from Bonus[] adding the piece value, then the black halves of the
// tables are initialized by flipping and changing the sign of the white scores. // tables are initialized by flipping and changing the sign of the white scores.
void init() { void init() {
for (PieceType pt = PAWN; pt <= KING; ++pt) for (Piece pc = W_PAWN; pc <= W_KING; ++pc)
{ {
PieceValue[MG][make_piece(BLACK, pt)] = PieceValue[MG][pt]; PieceValue[MG][~pc] = PieceValue[MG][pc];
PieceValue[EG][make_piece(BLACK, pt)] = PieceValue[EG][pt]; PieceValue[EG][~pc] = PieceValue[EG][pc];
Score v = make_score(PieceValue[MG][pt], PieceValue[EG][pt]); Score v = make_score(PieceValue[MG][pc], PieceValue[EG][pc]);
for (Square s = SQ_A1; s <= SQ_H8; ++s) for (Square s = SQ_A1; s <= SQ_H8; ++s)
{ {
File f = std::min(file_of(s), FILE_H - file_of(s)); File f = std::min(file_of(s), FILE_H - file_of(s));
psq[WHITE][pt][ s] = v + Bonus[pt][rank_of(s)][f]; psq[ pc][ s] = v + Bonus[pc][rank_of(s)][f];
psq[BLACK][pt][~s] = -psq[WHITE][pt][s]; psq[~pc][~s] = -psq[pc][s];
} }
} }
} }

View File

@@ -650,7 +650,7 @@ namespace {
} }
// Extra penalty for a quiet TT move in previous ply when it gets refuted // Extra penalty for a quiet TT move in previous ply when it gets refuted
if ((ss-1)->moveCount == 1 && !pos.captured_piece_type()) if ((ss-1)->moveCount == 1 && !pos.captured_piece())
{ {
Value penalty = Value(d * d + 4 * d + 1); Value penalty = Value(d * d + 4 * d + 1);
Square prevSq = to_sq((ss-1)->currentMove); Square prevSq = to_sq((ss-1)->currentMove);
@@ -1138,7 +1138,7 @@ moves_loop: // When in check search starts from here
} }
// Extra penalty for a quiet TT move in previous ply when it gets refuted // Extra penalty for a quiet TT move in previous ply when it gets refuted
if ((ss-1)->moveCount == 1 && !pos.captured_piece_type()) if ((ss-1)->moveCount == 1 && !pos.captured_piece())
{ {
Value penalty = Value(d * d + 4 * d + 1); Value penalty = Value(d * d + 4 * d + 1);
Square prevSq = to_sq((ss-1)->currentMove); Square prevSq = to_sq((ss-1)->currentMove);
@@ -1147,7 +1147,7 @@ moves_loop: // When in check search starts from here
} }
// Bonus for prior countermove that caused the fail low // Bonus for prior countermove that caused the fail low
else if ( depth >= 3 * ONE_PLY else if ( depth >= 3 * ONE_PLY
&& !pos.captured_piece_type() && !pos.captured_piece()
&& is_ok((ss-1)->currentMove)) && is_ok((ss-1)->currentMove))
{ {
int d = depth / ONE_PLY; int d = depth / ONE_PLY;

View File

@@ -22,7 +22,7 @@
#include "tbcore.cpp" #include "tbcore.cpp"
namespace Zobrist { namespace Zobrist {
extern Key psq[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; extern Key psq[PIECE_NB][SQUARE_NB];
} }
int Tablebases::MaxCardinality = 0; int Tablebases::MaxCardinality = 0;
@@ -60,11 +60,11 @@ static uint64 calc_key(Position& pos, int mirror)
color = !mirror ? WHITE : BLACK; color = !mirror ? WHITE : BLACK;
for (pt = PAWN; pt <= KING; ++pt) for (pt = PAWN; pt <= KING; ++pt)
for (i = popcount(pos.pieces(color, pt)); i > 0; i--) for (i = popcount(pos.pieces(color, pt)); i > 0; i--)
key ^= Zobrist::psq[WHITE][pt][i - 1]; key ^= Zobrist::psq[make_piece(WHITE, pt)][i - 1];
color = ~color; color = ~color;
for (pt = PAWN; pt <= KING; ++pt) for (pt = PAWN; pt <= KING; ++pt)
for (i = popcount(pos.pieces(color, pt)); i > 0; i--) for (i = popcount(pos.pieces(color, pt)); i > 0; i--)
key ^= Zobrist::psq[BLACK][pt][i - 1]; key ^= Zobrist::psq[make_piece(BLACK, pt)][i - 1];
return key; return key;
} }
@@ -83,11 +83,11 @@ static uint64 calc_key_from_pcs(int *pcs, int mirror)
color = !mirror ? 0 : 8; color = !mirror ? 0 : 8;
for (pt = PAWN; pt <= KING; ++pt) for (pt = PAWN; pt <= KING; ++pt)
for (i = 0; i < pcs[color + pt]; i++) for (i = 0; i < pcs[color + pt]; i++)
key ^= Zobrist::psq[WHITE][pt][i]; key ^= Zobrist::psq[make_piece(WHITE, pt)][i];
color ^= 8; color ^= 8;
for (pt = PAWN; pt <= KING; ++pt) for (pt = PAWN; pt <= KING; ++pt)
for (i = 0; i < pcs[color + pt]; i++) for (i = 0; i < pcs[color + pt]; i++)
key ^= Zobrist::psq[BLACK][pt][i]; key ^= Zobrist::psq[make_piece(BLACK, pt)][i];
return key; return key;
} }
@@ -123,7 +123,7 @@ static int probe_wdl_table(Position& pos, int *success)
key = pos.material_key(); key = pos.material_key();
// Test for KvK. // Test for KvK.
if (key == (Zobrist::psq[WHITE][KING][0] ^ Zobrist::psq[BLACK][KING][0])) if (key == (Zobrist::psq[W_KING][0] ^ Zobrist::psq[B_KING][0]))
return 0; return 0;
ptr2 = TB_hash[key >> (64 - TBHASHBITS)]; ptr2 = TB_hash[key >> (64 - TBHASHBITS)];

View File

@@ -336,6 +336,10 @@ inline Square operator~(Square s) {
return Square(s ^ SQ_A8); // Vertical flip SQ_A1 -> SQ_A8 return Square(s ^ SQ_A8); // Vertical flip SQ_A1 -> SQ_A8
} }
inline Piece operator~(Piece pc) {
return Piece(pc ^ 8);
}
inline CastlingRight operator|(Color c, CastlingSide s) { inline CastlingRight operator|(Color c, CastlingSide s) {
return CastlingRight(WHITE_OO << ((s == QUEEN_SIDE) + 2 * c)); return CastlingRight(WHITE_OO << ((s == QUEEN_SIDE) + 2 * c));
} }
@@ -353,7 +357,7 @@ inline Square make_square(File f, Rank r) {
} }
inline Piece make_piece(Color c, PieceType pt) { inline Piece make_piece(Color c, PieceType pt) {
return Piece((c << 3) | pt); return Piece((c << 3) + pt);
} }
inline PieceType type_of(Piece pc) { inline PieceType type_of(Piece pc) {