diff --git a/src/Makefile b/src/Makefile index 65ef297e..840312d9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -35,7 +35,7 @@ PGOBENCH = ./$(EXE) bench 16 1 1000 default time ### Object files OBJS = benchmark.o bitbase.o bitboard.o endgame.o evaluate.o main.o \ - material.o misc.o movegen.o movepick.o pawns.o position.o \ + material.o misc.o movegen.o movepick.o pawns.o position.o psqt.o \ search.o thread.o timeman.o tt.o uci.o ucioption.o syzygy/tbprobe.o ### ========================================================================== diff --git a/src/main.cpp b/src/main.cpp index 8cdf9e6f..adc13db4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -33,6 +33,7 @@ int main(int argc, char* argv[]) { std::cout << engine_info() << std::endl; UCI::init(Options); + PSQT::init(); Bitboards::init(); Position::init(); Bitbases::init(); diff --git a/src/movepick.cpp b/src/movepick.cpp index 3fe09bb7..914cd80e 100644 --- a/src/movepick.cpp +++ b/src/movepick.cpp @@ -147,9 +147,9 @@ void MovePicker::score() { // badCaptures[] array, but instead of doing it now we delay until the move // has been picked up in pick_move_from_list(). This way we save some SEE // calls in case we get a cutoff. - for (auto& m : *this){ - m.value = PieceValue[MG][pos.piece_on(to_sq(m))] - 200*relative_rank(pos.side_to_move(), to_sq(m)); - } + for (auto& m : *this) + m.value = PieceValue[MG][pos.piece_on(to_sq(m))] + - 200 * relative_rank(pos.side_to_move(), to_sq(m)); } template<> diff --git a/src/position.cpp b/src/position.cpp index 573b5df5..1aa476b6 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -27,7 +27,6 @@ #include "misc.h" #include "movegen.h" #include "position.h" -#include "psqtab.h" #include "thread.h" #include "tt.h" #include "uci.h" @@ -52,7 +51,6 @@ Key Position::exclusion_key() const { return st->key ^ Zobrist::exclusion; } namespace { const string PieceToChar(" PNBRQK pnbrqk"); -Score psq[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; // min_attacker() is a helper function used by see() to locate the least // valuable attacker for the side to move, remove the attacker we just found @@ -130,10 +128,7 @@ std::ostream& operator<<(std::ostream& os, const Position& pos) { /// Position::init() initializes at startup the various arrays used to compute -/// hash keys and the piece square tables. The latter is a two-step operation: -/// Firstly, the white halves of the tables are copied from PSQT[] tables. -/// Secondly, the black halves of the tables are initialized by flipping and -/// changing the sign of the white scores. +/// hash keys. void Position::init() { @@ -160,20 +155,6 @@ void Position::init() { Zobrist::side = rng.rand(); Zobrist::exclusion = rng.rand(); - - for (PieceType pt = PAWN; pt <= KING; ++pt) - { - PieceValue[MG][make_piece(BLACK, pt)] = PieceValue[MG][pt]; - PieceValue[EG][make_piece(BLACK, pt)] = PieceValue[EG][pt]; - - Score v = make_score(PieceValue[MG][pt], PieceValue[EG][pt]); - - for (Square s = SQ_A1; s <= SQ_H8; ++s) - { - psq[WHITE][pt][ s] = (v + PSQT[pt][s]); - psq[BLACK][pt][~s] = -(v + PSQT[pt][s]); - } - } } @@ -373,7 +354,7 @@ void Position::set_state(StateInfo* si) const { Square s = pop_lsb(&b); Piece pc = piece_on(s); si->key ^= Zobrist::psq[color_of(pc)][type_of(pc)][s]; - si->psq += psq[color_of(pc)][type_of(pc)][s]; + si->psq += PSQT::psq[color_of(pc)][type_of(pc)][s]; } if (si->epSquare != SQ_NONE) @@ -725,7 +706,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { do_castling(us, from, to, rfrom, rto); captured = NO_PIECE_TYPE; - st->psq += psq[us][ROOK][rto] - psq[us][ROOK][rfrom]; + st->psq += PSQT::psq[us][ROOK][rto] - PSQT::psq[us][ROOK][rfrom]; k ^= Zobrist::psq[us][ROOK][rfrom] ^ Zobrist::psq[us][ROOK][rto]; } @@ -764,7 +745,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { prefetch(thisThread->materialTable[st->materialKey]); // Update incremental scores - st->psq -= psq[them][captured][capsq]; + st->psq -= PSQT::psq[them][captured][capsq]; // Reset rule 50 counter st->rule50 = 0; @@ -820,7 +801,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { ^ Zobrist::psq[us][PAWN][pieceCount[us][PAWN]]; // Update incremental score - st->psq += psq[us][promotion][to] - psq[us][PAWN][to]; + st->psq += PSQT::psq[us][promotion][to] - PSQT::psq[us][PAWN][to]; // Update material st->nonPawnMaterial[us] += PieceValue[MG][promotion]; @@ -835,7 +816,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { } // Update incremental scores - st->psq += psq[us][pt][to] - psq[us][pt][from]; + st->psq += PSQT::psq[us][pt][to] - PSQT::psq[us][pt][from]; // Set capture piece st->capturedType = captured; diff --git a/src/position.h b/src/position.h index ece3f442..e38020d5 100644 --- a/src/position.h +++ b/src/position.h @@ -30,6 +30,13 @@ class Position; struct Thread; +namespace PSQT { + + extern Score psq[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; + + void init(); +} + /// CheckInfo struct is initialized at c'tor time and keeps info used to detect /// if a move gives check. diff --git a/src/psqtab.h b/src/psqt.cpp similarity index 84% rename from src/psqtab.h rename to src/psqt.cpp index 57fb30b9..32601c0a 100644 --- a/src/psqtab.h +++ b/src/psqt.cpp @@ -17,19 +17,16 @@ along with this program. If not, see . */ -#ifndef PSQTAB_H_INCLUDED -#define PSQTAB_H_INCLUDED - #include "types.h" +namespace PSQT { + #define S(mg, eg) make_score(mg, eg) - -/// PSQT[PieceType][Square] contains Piece-Square scores. For each piece type on -/// a given square a (middlegame, endgame) score pair is assigned. PSQT is defined -/// for the white side and the tables are symmetric for the black side. - -static const Score PSQT[][SQUARE_NB] = { +/// BaseTable[PieceType][Square] contains Piece-Square scores. For each piece +/// type on a given square a (middlegame, endgame) score pair is assigned. Table +/// is defined just for the white side; it is symmetric for the black side. +const Score BaseTable[][SQUARE_NB] = { { }, { // Pawn S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), S( 0, 0), @@ -95,4 +92,23 @@ static const Score PSQT[][SQUARE_NB] = { #undef S -#endif // #ifndef PSQTAB_H_INCLUDED +Score psq[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; + +// init() initializes piece square tables: the white halves of the tables are +// copied from BaseTable[] adding the piece value, then the black halves of the +// tables are initialized by flipping and changing the sign of the white scores. +void init() { + + for (PieceType pt = PAWN; pt <= KING; ++pt) + { + PieceValue[MG][make_piece(BLACK, pt)] = PieceValue[MG][pt]; + PieceValue[EG][make_piece(BLACK, pt)] = PieceValue[EG][pt]; + + Score v = make_score(PieceValue[MG][pt], PieceValue[EG][pt]); + + for (Square s = SQ_A1; s <= SQ_H8; ++s) + psq[BLACK][pt][~s] = -(psq[WHITE][pt][ s] = (v + BaseTable[pt][s])); + } +} + +} // namespace PSQT diff --git a/src/search.cpp b/src/search.cpp index 636b1db4..18e0cb95 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -961,7 +961,8 @@ moves_loop: // When in check and at SpNode search starts from here if ( (!PvNode && cutNode) || ( History[pos.piece_on(to_sq(move))][to_sq(move)] < VALUE_ZERO - && CounterMovesHistory[pos.piece_on(prevMoveSq)][prevMoveSq][pos.piece_on(to_sq(move))][to_sq(move)] <= VALUE_ZERO)) + && CounterMovesHistory[pos.piece_on(prevMoveSq)][prevMoveSq] + [pos.piece_on(to_sq(move))][to_sq(move)] <= VALUE_ZERO)) ss->reduction += ONE_PLY; if (move == countermove)