let s see if i understand correctly what happens there.Fguy64 wrote:Code: Select all
... if( count == 0 ) { PV[ply][ply] = 0; for( int j=ply+1; j<=maxPly; j++ ) { PV[ply][j] = 0; } if( inCheck(gs) ) return -(100000-ply+2); else return 0; } ...
- if no legalMove available (count==0) cleanup successors,
beginning at current ply.
After cleanup return mate/stalemate score.
- on ply-1, if returned value is a pvValue and you copy the pv
you are now able to detect, that there arent any successors.
ok, if i understood this is doing the job principal, but
there several things to think about.
analyse
=================
1:
you dont have to loop the "successors". it is enough to set
the PV[ply][ply] = noMove (0).
Because on ply-1 ...
Code: Select all
PV[ply][ply] = m;
for( int j=ply+1; j<=maxPly && PV[ply+1][j]; j++ ) {
PV[ply][j] = PV[ply+1][j];
so now your code may look like this.
Code: Select all
if( count == 0 ) {
PV[ply][ply] = 0;
/*noLoop*/
if( inCheck(gs) ) return -(100000-ply+2);
else return 0;
}
depending on the mate/stalemate recognition. Of course there is
no move, but there are several other searchstates, where also no
move is available. In all this cases you have to set the pv[ply][ply]
to noMove(0) before returning a value !? (hope you will never forget
).
So my proposal is: clean the PV[ply][ply] on entering the search.
Code: Select all
SCORE_T search(params)
{
PV[ply][ply] = 0;
...further code...
return(alpha / score ) //failHard/failSoft
}
simple return the score you found.
2a: make sure that after any kind of shallow search/ nullmoveSearch
... you reset PV[ply][ply] again, if the search continues or the
pvSlot has no valid move.(to be on the safe side).
3:
what is left now ?! (only detecting mate/stalemate!)
Code: Select all
if( count == 0 )
{
//done on entering the search
//and because no move is available
//it cannot be overwritten, and is kept 0
/*PV[ply][ply] = 0;*/
/*noLoop*/
if( inCheck(gs) ) return -(100000-ply+2);
else return 0;
}
an easy mateScore statement could look like this:
return(LOBOUND+ply)
4: return values & failhard/faillow
as long as your engine doesnt profit enormously from failsoft framework,
i also would propose to use the failard framework. It is much easier
to follow what happens in the search.
FAILHARD: Alpha <= Score <= Beta
First i never thought about fhard/fsoft, but short time ago i tried to understand. So, if you use this framework you only have to make
sure you
never return a value < alpha (as i understand)
which leads to the following statements.
Code: Select all
SCORE_T search(...params...)
{
...
...
...
return(bestscore < alpha ? alpha : bestscore)
}
//especially for you mate/stalemate scheme
if(count==0)
{
if(inCheck) return(MATESCORE < alpha ? alpha : MATESCORE)
else return( 0 < alpha ? alpha : 0 )
}
Scenario1:
PLY : score >= beta(cut)
PLY-1: score < alpha (which is upvalued at the end to alpha)
Scenario2:
PLY : score < alpha (upvalue score to alpha)
PLY-1: score==beta (cut)
regards, Michael