The first step in localizing the bug in engine's code was to determine
which UCI message of the engine causes GUI like Fritz to answer "no move".
I've found no info on the subj in Fritz help. But looking through the code I have found
one message: "bestmove NULL" in procedure OutputBestMove()
which is sent if the variable ROOT_BEST_MOVE==0. I supposed that just this message
have caused the GUI to give "no move" message.
Catching all messages from engine to GUI into a log file, I confirmed my guess.
The variable ROOT_BEST_MOVE is initialized in Search(POSITION) by 0. Then the execution
goes to MyTop(POSITION), where the move generator writes all legal moves from position POSITION
into loval array ML, from which they are copied into global array ROOT_MOVE_LIST.
It seems natural to reinitialize ROOT_BEST_MOVE in this place
by some of the legal moves, say ML[0]. When I did this, all "no moves" disappeared at once!
But the ML[0], though legal, hardly is the best even in the first
approximation! I checked consecutively, that copying of ML to
ROOT_BEST_MOVE is correct as well, so that ROOT_BEST_MOVE=ROOT_MOVE_LIST[0]
is OK. The array ROOT_MOVE_LIST is modified further by adding
to any move its evaluation (EVAL( move )). RB also are used for evaluation
of moves if position permits. I checked that all modification and
sorting procedures are correct, so the final "no move" fix
(with comments) is now:
#ifdef NO_MOVE_BUG_FIXHere is OK! I.e. ROOT_MOVE_LIST is correct up to here.
So take as the first approximation to ROOT_BEST_MOVE the best move of depth 1 instead of 0,
which creates "no bug", if the engine fails searching at bigger depth for some reason.
Taking into account that order in ROOT_MOVE_LIST is descending one gets:
ROOT_BEST_MOVE=POSITION->wtm?ROOT_MOVE_LIST->move:(list-1)->move;
#endif
placed immediately after bubble sort routine
and before the (first) line
L = -VALUE_MATE;
in MyTop() routine
http://ippolit.wikispaces.com/message/view/IvanHoe/27230721#27230825I do not know why all comment signs // have disappeared from the above post! The essential (non-comment) is the only line:
ROOT_BEST_MOVE=POSITION->wtm?ROOT_MOVE_LIST->move:(list-1)->move;
Vladimir