Easier for tuning psq tables:
TUNE(myParameters, PSQT::init);
Also move PSQT code in a new *.cpp file, and retire the
old and hacky psqtab.h that required to be included only
once to work correctly, this is not idiomatic for a header
file.
Give wide visibility to psq tables (previously visible only
in position.cpp), this will easy the use of psq tables outside
Position, for instance in move ordering.
Finally trivial code style fixes of the latest patches.
Original patch of Lucas Braesch.
No functional change.
### Object files
OBJS = benchmark.o bitbase.o bitboard.o endgame.o evaluate.o main.o \
### 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
### ==========================================================================
search.o thread.o timeman.o tt.o uci.o ucioption.o syzygy/tbprobe.o
### ==========================================================================
std::cout << engine_info() << std::endl;
UCI::init(Options);
std::cout << engine_info() << std::endl;
UCI::init(Options);
Bitboards::init();
Position::init();
Bitbases::init();
Bitboards::init();
Position::init();
Bitbases::init();
// 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.
// 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));
#include "misc.h"
#include "movegen.h"
#include "position.h"
#include "misc.h"
#include "movegen.h"
#include "position.h"
#include "thread.h"
#include "tt.h"
#include "uci.h"
#include "thread.h"
#include "tt.h"
#include "uci.h"
namespace {
const string PieceToChar(" PNBRQK pnbrqk");
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
// 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
/// Position::init() initializes at startup the various arrays used to compute
/// 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.
Zobrist::side = rng.rand<Key>();
Zobrist::exclusion = rng.rand<Key>();
Zobrist::side = rng.rand<Key>();
Zobrist::exclusion = rng.rand<Key>();
-
- 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]);
- }
- }
Square s = pop_lsb(&b);
Piece pc = piece_on(s);
si->key ^= Zobrist::psq[color_of(pc)][type_of(pc)][s];
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)
}
if (si->epSquare != SQ_NONE)
do_castling<true>(us, from, to, rfrom, rto);
captured = NO_PIECE_TYPE;
do_castling<true>(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];
}
k ^= Zobrist::psq[us][ROOK][rfrom] ^ Zobrist::psq[us][ROOK][rto];
}
prefetch(thisThread->materialTable[st->materialKey]);
// Update incremental scores
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;
// Reset rule 50 counter
st->rule50 = 0;
^ Zobrist::psq[us][PAWN][pieceCount[us][PAWN]];
// Update incremental score
^ 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];
// Update material
st->nonPawnMaterial[us] += PieceValue[MG][promotion];
}
// Update incremental scores
}
// 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;
// Set capture piece
st->capturedType = captured;
class Position;
struct Thread;
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.
/// CheckInfo struct is initialized at c'tor time and keeps info used to detect
/// if a move gives check.
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef PSQTAB_H_INCLUDED
-#define PSQTAB_H_INCLUDED
-
-#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.
+#define S(mg, eg) make_score(mg, eg)
-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),
{ },
{ // 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),
-#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
if ( (!PvNode && cutNode)
|| ( History[pos.piece_on(to_sq(move))][to_sq(move)] < VALUE_ZERO
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)
ss->reduction += ONE_PLY;
if (move == countermove)