}
};
+
////
-//// Variables
+//// Constants and variables
////
+/// Bonus for having the side to move (modified by Joona Kiiski)
+
+static const Score TempoValue = make_score(48, 22);
+
+
Key Position::zobrist[2][8][64];
Key Position::zobEp[64];
Key Position::zobCastle[16];
{
if (isdigit(token))
{
- file += token - '0'; // Skip the given number of files
+ file += File(token - '0'); // Skip the given number of files
continue;
}
else if (token == '/')
castleRightsMask[make_square(initialQRFile, RANK_1)] ^= WHITE_OOO;
castleRightsMask[make_square(initialQRFile, RANK_8)] ^= BLACK_OOO;
+ isChess960 = initialKFile != FILE_E
+ || initialQRFile != FILE_A
+ || initialKRFile != FILE_H;
+
find_checkers();
st->key = compute_key();
if (st->castleRights != CASTLES_NONE)
{
- const bool Chess960 = initialKFile != FILE_E
- || initialQRFile != FILE_A
- || initialKRFile != FILE_H;
-
if (can_castle_kingside(WHITE))
- fen += Chess960 ? char(toupper(file_to_char(initialKRFile))) : 'K';
+ fen += isChess960 ? char(toupper(file_to_char(initialKRFile))) : 'K';
if (can_castle_queenside(WHITE))
- fen += Chess960 ? char(toupper(file_to_char(initialQRFile))) : 'Q';
+ fen += isChess960 ? char(toupper(file_to_char(initialQRFile))) : 'Q';
if (can_castle_kingside(BLACK))
- fen += Chess960 ? file_to_char(initialKRFile) : 'k';
+ fen += isChess960 ? file_to_char(initialKRFile) : 'k';
if (can_castle_queenside(BLACK))
- fen += Chess960 ? file_to_char(initialQRFile) : 'q';
+ fen += isChess960 ? file_to_char(initialQRFile) : 'q';
} else
fen += '-';
// Reset rule 50 draw counter
st->rule50 = 0;
- // Update pawn hash key
+ // Update pawn hash key and prefetch in L1/L2 cache
st->pawnKey ^= zobrist[us][PAWN][from] ^ zobrist[us][PAWN][to];
+ prefetchPawn(st->pawnKey, threadID);
// Set en passant square, only if moved pawn can be captured
if ((to ^ from) == 16)
st->value += pst(us, promotion, to);
// Update material
- st->npMaterial[us] += piece_value_midgame(promotion);
+ st->npMaterial[us] += PieceValueMidgame[promotion];
}
}
st->pawnKey ^= zobrist[them][PAWN][capsq];
}
else
- st->npMaterial[them] -= piece_value_midgame(capture);
+ st->npMaterial[them] -= PieceValueMidgame[capture];
// Remove captured piece
clear_bit(&(byColorBB[them]), capsq);
/// updated by do_move and undo_move when the program is running in debug mode.
Score Position::compute_value() const {
- Score result = make_score(0, 0);
+ Score result = SCORE_ZERO;
Bitboard b;
Square s;
Value Position::compute_non_pawn_material(Color c) const {
- Value result = Value(0);
+ Value result = VALUE_ZERO;
for (PieceType pt = KNIGHT; pt <= QUEEN; pt++)
{
while (b)
{
assert(piece_on(first_1(b)) == piece_of_color_and_type(c, pt));
+
pop_1st_bit(&b);
- result += piece_value_midgame(pt);
+ result += PieceValueMidgame[pt];
}
}
return result;
bool Position::is_mate() const {
MoveStack moves[256];
- return is_check() && (generate_moves(*this, moves, false) == moves);
+ return is_check() && (generate_moves(*this, moves) == moves);
}
-/// Position::has_mate_threat() tests whether a given color has a mate in one
-/// from the current position.
+/// Position::has_mate_threat() tests whether the side to move is under
+/// a threat of being mated in one from the current position.
-bool Position::has_mate_threat(Color c) {
+bool Position::has_mate_threat() {
+ MoveStack mlist[256], *last, *cur;
StateInfo st1, st2;
- Color stm = side_to_move();
+ bool mateFound = false;
+ // If we are under check it's up to evasions to do the job
if (is_check())
return false;
- // If the input color is not equal to the side to move, do a null move
- if (c != stm)
- do_null_move(st1);
-
- MoveStack mlist[120];
- bool result = false;
- Bitboard pinned = pinned_pieces(sideToMove);
+ // First pass the move to our opponent doing a null move
+ do_null_move(st1);
- // Generate pseudo-legal non-capture and capture check moves
- MoveStack* last = generate_non_capture_checks(*this, mlist);
+ // Then generate pseudo-legal moves that give check
+ last = generate_non_capture_checks(*this, mlist);
last = generate_captures(*this, last);
- // Loop through the moves, and see if one of them is mate
- for (MoveStack* cur = mlist; cur != last; cur++)
+ // Loop through the moves, and see if one of them gives mate
+ Bitboard pinned = pinned_pieces(sideToMove);
+ CheckInfo ci(*this);
+ for (cur = mlist; cur != last && !mateFound; cur++)
{
Move move = cur->move;
- if (!pl_move_is_legal(move, pinned))
+ if ( !pl_move_is_legal(move, pinned)
+ || !move_is_check(move, ci))
continue;
- do_move(move, st2);
+ do_move(move, st2, ci, true);
+
if (is_mate())
- result = true;
+ mateFound = true;
undo_move(move);
}
- // Undo null move, if necessary
- if (c != stm)
- undo_null_move();
-
- return result;
+ undo_null_move();
+ return mateFound;
}
-/// Position::init_zobrist() is a static member function which initializes the
-/// various arrays used to compute hash keys.
+/// Position::init_zobrist() is a static member function which initializes at
+/// startup the various arrays used to compute hash keys.
void Position::init_zobrist() {
- for (int i = 0; i < 2; i++)
- for (int j = 0; j < 8; j++)
- for (int k = 0; k < 64; k++)
- zobrist[i][j][k] = Key(genrand_int64());
+ int i,j, k;
- for (int i = 0; i < 64; i++)
+ for (i = 0; i < 2; i++) for (j = 0; j < 8; j++) for (k = 0; k < 64; k++)
+ zobrist[i][j][k] = Key(genrand_int64());
+
+ for (i = 0; i < 64; i++)
zobEp[i] = Key(genrand_int64());
- for (int i = 0; i < 16; i++)
- zobCastle[i] = genrand_int64();
+ for (i = 0; i < 16; i++)
+ zobCastle[i] = Key(genrand_int64());
- zobSideToMove = genrand_int64();
- zobExclusion = genrand_int64();
+ zobSideToMove = Key(genrand_int64());
+ zobExclusion = Key(genrand_int64());
}
/// Position::init_piece_square_tables() initializes the piece square tables.
-/// This is a two-step operation:
-/// First, the white halves of the tables are
-/// copied from the MgPST[][] and EgPST[][] arrays.
-/// Second, the black halves of the tables are initialized by mirroring
-/// and changing the sign of the corresponding white scores.
+/// This is a two-step operation: First, the white halves of the tables are
+/// copied from the MgPST[][] and EgPST[][] arrays. Second, the black halves
+/// of the tables are initialized by mirroring and changing the sign of the
+/// corresponding white scores.
void Position::init_piece_square_tables() {