alpha bound in hash table
Posted: Sun Nov 25, 2018 1:53 pm
I may be wrong (as often ...) but it seems to me that TT move with alpha bound has a score but never has an associated move.
Since the only way to insert an alpha bound in TT is if no move raised alpha and thus "best move" was never updated.
In this old post http://talkchess.com/forum3/viewtopic.p ... 10#p762826, I found that in Weini I was never using alpha bound in TT because I was never inserting something in TT without a "valid move". That is why the (bad) solution was to use the first move in list when an alpha bound in inserted inside TT so that alpha bound are in TT and TT scores might be returned more often. In Weini this indeed leads to solve fine70 way faster than before.
This morning I faced more or less the same issue in Minic, but the other way around. I was trying to get ride of the ugly line
and simply accept to add TT entry without valid move ; I had to add some guards at some point to ensure TT move is valid before using it, but was able to use (and return) TT score without valid move in case of alpha bound.
I was expecting absolutely no change in playing strength but see a great -150elo !! and a totally new behavior in solving fine70.
I am quite confused with this ...
Let's take the simplest code
Is it what shall be done ??
Since the only way to insert an alpha bound in TT is if no move raised alpha and thus "best move" was never updated.
In this old post http://talkchess.com/forum3/viewtopic.p ... 10#p762826, I found that in Weini I was never using alpha bound in TT because I was never inserting something in TT without a "valid move". That is why the (bad) solution was to use the first move in list when an alpha bound in inserted inside TT so that alpha bound are in TT and TT scores might be returned more often. In Weini this indeed leads to solve fine70 way faster than before.
This morning I faced more or less the same issue in Minic, but the other way around. I was trying to get ride of the ugly line
Code: Select all
if (bestMove == INVALIDMOVE) bestMove = moves[0]; // so that B_alpha are stored in TT
I was expecting absolutely no change in playing strength but see a great -150elo !! and a totally new behavior in solving fine70.
I am quite confused with this ...
Let's take the simplest code
Code: Select all
ScoreType pvs(ScoreType alpha, ScoreType beta, const Position & p, DepthType depth, bool pvnode, unsigned int ply, std::vector<Move> & pv, DepthType & seldepth){
if ( std::max(1,(int)std::chrono::duration_cast<std::chrono::milliseconds>(Clock::now() - TimeMan::startTime).count()) > currentMoveMs ){
stopFlag = true;
return STOPSCORE;
}
if ((int)ply > seldepth) seldepth = ply;
if ( depth <= 0 ) return qsearch(alpha,beta,p,ply,seldepth);
const bool rootnode = ply == 1;
if (isDraw(p, pvnode)) return 0;
float gp = 0;
if (ply >= MAX_PLY - 1 || depth >= MAX_DEPTH - 1) return eval(p, gp);
alpha = std::max(alpha, (ScoreType)(-MATE + ply));
beta = std::min(beta, (ScoreType)( MATE - ply - 1));
if (alpha >= beta) return alpha;
TT::Entry e;
if (TT::getEntry(computeHash(p), depth, e)) {
if (e.h != 0 && !rootnode && std::abs(e.score) < MATE - MAX_DEPTH && !pvnode &&
( (e.b == TT::B_alpha && e.score <= alpha) || (e.b == TT::B_beta && e.score >= beta) || (e.b == TT::B_exact) ) ) {
if ( e.m != INVALIDMOVE) pv.push_back(e.m); // here e.m might be INVALIDMOVE if B_alpha
return e.score;
}
}
const bool isInCheck = isAttacked(p, kingSquare(p));
ScoreType val;
// IID
if ( (e.h == 0 /*|| e.d < depth/3*/) && pvnode && depth >= iidMinDepth){
std::vector<Move> iidPV;
pvs(alpha,beta,p,depth/2,pvnode,ply,iidPV,seldepth);
if ( !stopFlag) TT::getEntry(computeHash(p), depth, e);
if (stopFlag) return STOPSCORE;
}
int validMoveCount = 0;
bool alphaUpdated = false;
Move bestMove = INVALIDMOVE;
std::vector<Move> moves;
generate(p,moves);
if ( moves.empty() ) return isInCheck?-MATE + ply : 0;
sort(*this,moves,p,&e);
/// ????? if (bestMove == INVALIDMOVE) bestMove = moves[0]; // so that B_alpha are stored in TT
for(auto it = moves.begin() ; it != moves.end() && !stopFlag ; ++it){
Position p2 = p;
if ( ! apply(p2,*it) ) continue;
validMoveCount++;
val = -pvs(-beta,-alpha,p2,depth-1+extension,pvnode,ply+1,childPV,seldepth);
if ( !stopFlag && val > alpha ){
alphaUpdated = true;
if ( val >= beta ){
TT::setEntry({*it,val,TT::B_beta,depth,computeHash(p)});
return val;
}
alpha = val;
bestMove = *it;
}
}
if ( validMoveCount==0 && !stopFlag) return isInCheck?-MATE + ply : 0;
///@todo here validMoveCount shall not be present, this does not allow to store alpha bound !!!!
if ( !stopFlag && /*validMoveCount*/ bestMove != INVALIDMOVE ) TT::setEntry({bestMove,alpha,alphaUpdated?TT::B_exact:TT::B_alpha,depth,computeHash(p)});
return stopFlag?STOPSCORE:alpha;