Compare commits

..

11 Commits

Author SHA1 Message Date
Marco Costalba
8ee0842c81 Stockfish 1.5.1
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
2009-10-08 15:16:34 +01:00
Marco Costalba
e59ff49a55 Fix the polling frequency when pondering
When pondering InfiniteSearch == false but myTime == 0 so that
NodesBetweenPolls = 1000 instead of the standard.

The patch fixes the bug and is more robust because checks
directly myTime for a non-zero value, without relying on
an indirect test (InfiniteSearch in this case).

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
2009-10-08 09:09:19 +01:00
Tord Romstad
225dcfeeb7 Use slightly lower polling frequency in the last few seconds.
Instead of checking the time every 100 nodes in the last second,
and every 1000 nodes in the last five seconds, Stockfish now checks
every 1000 nodes in the last second and every 5000 nodes in the last
five seconds.  This was tested in 1036 games at a time control of
40 moves/10 seconds, and no losses on time occured.

Also fixed a bug pointed out by Marco:  In infinite mode, myTime
is actually 0, but of course we still don't want to check the time
more frequently than the standard once per 30000 nodes in this
case.
2009-10-08 08:55:25 +02:00
Tord Romstad
8dd01fda12 Minor change to time management code, to make sure we don't lose on
time at the last move before the time control when there is very
little time left.
2009-10-07 18:27:00 +02:00
Tord Romstad
18cd83a380 Display fail high/fail low in search log file. 2009-10-06 12:51:15 +02:00
Marco Costalba
fd2b3df770 Fix bogus comment in extract_pv()
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
2009-10-06 11:15:05 +01:00
Marco Costalba
da948cc94e Fix use of an initialized SearchStack
In RootMoveList c'tor we allocate a search stack and then
call directly qsearch.

There is called init_node() that clears all the fields of the search
stack array that refers to current ply but not the the killer moves.

The killer moves cleared correspond to ply+2.

In id_loop() this is not a problem because killer moves of
corresponding ply are cleared anyway few instructions later,
but in RootMoveList c'tor we leave them uninitialized.

This patch fixes this very old bug. It comes direclty
from Glaurung age.

Bug spotted by Valgrind.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
2009-10-06 11:12:41 +01:00
Marco Costalba
e49b21eacb Remove a redundant assignment in PawnInfo c'tor
We don't need to set key to 0 because clear() already
takes care of that.

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
2009-10-06 09:18:15 +01:00
Marco Costalba
60bc30275d Small code reformat in TranspositionTable::extract_pv()
In particular don't use an array of StateInfo, this
avoids a possible overflow and is in any case redundant.

Also pass as argument the pv[] array size to avoid a second
possible overflow on this one.

Fix suggested by Joona.

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
2009-10-06 07:14:12 +01:00
Tord Romstad
32dfaa56b0 Fixed an embarassing Chess960 bug found by Alexander Schmidt.
It turned out that we used do_move_bb to update the king and rook
bitboards when making and unmaking castling moves, which obviously
doesn't work in Chess960, where the source and destination squares
for the king or rook could be identical.

No functional change in normal chess.
2009-10-05 16:46:18 +02:00
Marco Costalba
3701a8e57d Restore development version
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
2009-10-05 07:15:13 +01:00
8 changed files with 81 additions and 52 deletions

View File

@@ -50,7 +50,7 @@ using namespace std;
/// Version number. If this is left empty, the current date (in the format
/// YYMMDD) is used as a version number.
static const string EngineVersion = "1.5";
static const string EngineVersion = "1.5.1";
static const string AppName = "Stockfish";
static const string AppTag = "";

View File

@@ -45,7 +45,7 @@ class PawnInfo {
friend class PawnInfoTable;
public:
PawnInfo() : key(0) { clear(); }
PawnInfo() { clear(); }
Value mg_value() const;
Value eg_value() const;

View File

@@ -985,17 +985,22 @@ void Position::do_castle_move(Move m) {
rto = relative_square(us, SQ_D1);
}
// Move the pieces
Bitboard kmove_bb = make_move_bb(kfrom, kto);
do_move_bb(&(byColorBB[us]), kmove_bb);
do_move_bb(&(byTypeBB[KING]), kmove_bb);
do_move_bb(&(byTypeBB[0]), kmove_bb); // HACK: byTypeBB[0] == occupied squares
Bitboard rmove_bb = make_move_bb(rfrom, rto);
do_move_bb(&(byColorBB[us]), rmove_bb);
do_move_bb(&(byTypeBB[ROOK]), rmove_bb);
do_move_bb(&(byTypeBB[0]), rmove_bb); // HACK: byTypeBB[0] == occupied squares
// Remove pieces from source squares:
clear_bit(&(byColorBB[us]), kfrom);
clear_bit(&(byTypeBB[KING]), kfrom);
clear_bit(&(byTypeBB[0]), kfrom); // HACK: byTypeBB[0] == occupied squares
clear_bit(&(byColorBB[us]), rfrom);
clear_bit(&(byTypeBB[ROOK]), rfrom);
clear_bit(&(byTypeBB[0]), rfrom); // HACK: byTypeBB[0] == occupied squares
// Put pieces on destination squares:
set_bit(&(byColorBB[us]), kto);
set_bit(&(byTypeBB[KING]), kto);
set_bit(&(byTypeBB[0]), kto); // HACK: byTypeBB[0] == occupied squares
set_bit(&(byColorBB[us]), rto);
set_bit(&(byTypeBB[ROOK]), rto);
set_bit(&(byTypeBB[0]), rto); // HACK: byTypeBB[0] == occupied squares
// Update board array
Piece king = piece_of_color_and_type(us, KING);
Piece rook = piece_of_color_and_type(us, ROOK);
@@ -1106,6 +1111,7 @@ void Position::undo_move(Move m) {
pieceList[us][PAWN][index[to]] = to;
}
// Put the piece back at the source square
Bitboard move_bb = make_move_bb(to, from);
do_move_bb(&(byColorBB[us]), move_bb);
@@ -1183,17 +1189,22 @@ void Position::undo_castle_move(Move m) {
assert(piece_on(kto) == piece_of_color_and_type(us, KING));
assert(piece_on(rto) == piece_of_color_and_type(us, ROOK));
// Put the pieces back at the source square
Bitboard kmove_bb = make_move_bb(kto, kfrom);
do_move_bb(&(byColorBB[us]), kmove_bb);
do_move_bb(&(byTypeBB[KING]), kmove_bb);
do_move_bb(&(byTypeBB[0]), kmove_bb); // HACK: byTypeBB[0] == occupied squares
Bitboard rmove_bb = make_move_bb(rto, rfrom);
do_move_bb(&(byColorBB[us]), rmove_bb);
do_move_bb(&(byTypeBB[ROOK]), rmove_bb);
do_move_bb(&(byTypeBB[0]), rmove_bb); // HACK: byTypeBB[0] == occupied squares
// Remove pieces from destination squares:
clear_bit(&(byColorBB[us]), kto);
clear_bit(&(byTypeBB[KING]), kto);
clear_bit(&(byTypeBB[0]), kto); // HACK: byTypeBB[0] == occupied squares
clear_bit(&(byColorBB[us]), rto);
clear_bit(&(byTypeBB[ROOK]), rto);
clear_bit(&(byTypeBB[0]), rto); // HACK: byTypeBB[0] == occupied squares
// Put pieces on source squares:
set_bit(&(byColorBB[us]), kfrom);
set_bit(&(byTypeBB[KING]), kfrom);
set_bit(&(byTypeBB[0]), kfrom); // HACK: byTypeBB[0] == occupied squares
set_bit(&(byColorBB[us]), rfrom);
set_bit(&(byTypeBB[ROOK]), rfrom);
set_bit(&(byTypeBB[0]), rfrom); // HACK: byTypeBB[0] == occupied squares
// Update board
board[rto] = board[kto] = EMPTY;

View File

@@ -325,14 +325,15 @@ const string line_to_san(const Position& pos, Move line[], int startColumn, bool
/// when the UCI parameter "Use Search Log" is "true").
const string pretty_pv(const Position& pos, int time, int depth,
uint64_t nodes, Value score, Move pv[]) {
uint64_t nodes, Value score, ValueType type, Move pv[]) {
std::stringstream s;
// Depth
s << std::setw(2) << depth << " ";
// Score
s << std::setw(8) << score_string(score);
s << ((type == VALUE_TYPE_LOWER)? ">" : ((type == VALUE_TYPE_UPPER)? "<" : " "));
s << std::setw(7) << score_string(score);
// Time
s << std::setw(8) << time_string(time) << " ";

View File

@@ -39,6 +39,6 @@
extern const std::string move_to_san(const Position& pos, Move m);
extern Move move_from_san(const Position& pos, const std::string& str);
extern const std::string line_to_san(const Position& pos, Move line[], int startColumn, bool breakLines);
extern const std::string pretty_pv(const Position& pos, int time, int depth, uint64_t nodes, Value score, Move pv[]);
extern const std::string pretty_pv(const Position& pos, int time, int depth, uint64_t nodes, Value score, ValueType type, Move pv[]);
#endif // !defined(SAN_H_INCLUDED)

View File

@@ -299,6 +299,7 @@ namespace {
void ponderhit();
void print_current_line(SearchStack ss[], int ply, int threadID);
void wait_for_stop_or_ponderhit();
void init_ss_array(SearchStack ss[]);
void idle_loop(int threadID, SplitPoint* waitSp);
void init_split_point_stack();
@@ -445,7 +446,8 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move,
if (movesToGo == 1)
{
MaxSearchTime = myTime / 2;
AbsoluteMaxSearchTime = Min(myTime / 2, myTime - 500);
AbsoluteMaxSearchTime =
(myTime > 3000)? (myTime - 500) : ((myTime * 3) / 4);
} else {
MaxSearchTime = myTime / Min(movesToGo, 20);
AbsoluteMaxSearchTime = Min((4 * myTime) / movesToGo, myTime / 3);
@@ -469,6 +471,10 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move,
NodesBetweenPolls = Min(MaxNodes, 30000);
InfiniteSearch = true; // HACK
}
else if (myTime && myTime < 1000)
NodesBetweenPolls = 1000;
else if (myTime && myTime < 5000)
NodesBetweenPolls = 5000;
else
NodesBetweenPolls = 30000;
@@ -636,11 +642,7 @@ namespace {
// Initialize
TT.new_search();
H.clear();
for (int i = 0; i < 3; i++)
{
ss[i].init(i);
ss[i].initKillers();
}
init_ss_array(ss);
IterationInfo[1] = IterationInfoType(rml.get_move_score(0), rml.get_move_score(0));
Iteration = 1;
@@ -947,7 +949,7 @@ namespace {
// Update PV
rml.set_move_score(i, value);
update_pv(ss, 0);
TT.extract_pv(pos, ss[0].pv);
TT.extract_pv(pos, ss[0].pv, PLY_MAX);
rml.set_move_pv(i, ss[0].pv);
if (MultiPV == 1)
@@ -974,7 +976,10 @@ namespace {
std::cout << std::endl;
if (UseLogFile)
LogFile << pretty_pv(pos, current_search_time(), Iteration, nodes_searched(), value, ss[0].pv)
LogFile << pretty_pv(pos, current_search_time(), Iteration, nodes_searched(), value,
((value >= beta)? VALUE_TYPE_LOWER
: ((value <= alpha)? VALUE_TYPE_UPPER : VALUE_TYPE_EXACT)),
ss[0].pv)
<< std::endl;
if (value > alpha)
@@ -1961,6 +1966,7 @@ namespace {
// Find a quick score for the move
StateInfo st;
SearchStack ss[PLY_MAX_PLUS_2];
init_ss_array(ss);
moves[count].move = cur->move;
pos.do_move(moves[count].move, st);
@@ -2560,6 +2566,18 @@ namespace {
}
// init_ss_array() does a fast reset of the first entries of a SearchStack array
void init_ss_array(SearchStack ss[]) {
for (int i = 0; i < 3; i++)
{
ss[i].init(i);
ss[i].initKillers();
}
}
// wait_for_stop_or_ponderhit() is called when the maximum depth is reached
// while the program is pondering. The point is to work around a wrinkle in
// the UCI protocol: When pondering, the engine is not allowed to give a

View File

@@ -220,27 +220,26 @@ void TranspositionTable::insert_pv(const Position& pos, Move pv[]) {
/// will often get single-move PVs when the search stops while failing high,
/// and a single-move PV means that we don't have a ponder move.
void TranspositionTable::extract_pv(const Position& pos, Move pv[]) {
void TranspositionTable::extract_pv(const Position& pos, Move pv[], int pvSize) {
int ply;
Position p(pos);
StateInfo st[100];
for (ply = 0; pv[ply] != MOVE_NONE; ply++)
p.do_move(pv[ply], st[ply]);
bool stop;
const TTEntry* tte;
for (stop = false, tte = retrieve(p.get_key());
tte && tte->move() != MOVE_NONE && !stop;
tte = retrieve(p.get_key()), ply++)
StateInfo st;
Position p(pos);
int ply = 0;
// Update position to the end of current PV
while (pv[ply] != MOVE_NONE)
p.do_move(pv[ply++], st);
// Try to add moves from TT while possible
while ( (tte = retrieve(p.get_key())) != NULL
&& tte->move() != MOVE_NONE
&& move_is_legal(p, tte->move())
&& (!p.is_draw() || ply < 2)
&& ply < pvSize)
{
if (!move_is_legal(p, tte->move()))
break;
pv[ply] = tte->move();
p.do_move(pv[ply], st[ply]);
for (int j = 0; j < ply; j++)
if (st[j].key == p.get_key()) stop = true;
p.do_move(pv[ply++], st);
}
pv[ply] = MOVE_NONE;
}

View File

@@ -102,7 +102,7 @@ public:
void prefetch(const Key posKey) const;
void new_search();
void insert_pv(const Position& pos, Move pv[]);
void extract_pv(const Position& pos, Move pv[]);
void extract_pv(const Position& pos, Move pv[], int pvSize);
int full() const;
private: