Unreliable mate scores

Discussion of chess software programming and technical issues.

Moderator: Ras

User avatar
Volker Annuss
Posts: 180
Joined: Mon Sep 03, 2007 9:15 am

Re: Unreliable mate scores

Post by Volker Annuss »

Any idea where unreliable mate scores could come from?
Hello Luca,

I suspect, the bad scores come from the hash table. I had something similar some years ago.

To find out, what happened, try the following:

- Insert some debug code in the hash probing code and/or after your search returns a value and check for unreasonable mate scores.
- When you found the first one, get the positions hash code and the node count.

Now you have two ways to continue debugging.

1st:
- Set a breakpoint (maybe you have to insert some other debug code) that breaks, when the node count comes close to the value you got above.
- Restart your engine and see what happens until the bad score appears.

2nd:
- Set a breakpoint (maybe you have to insert some other debug code) that breaks, when a position with the hash code from above is written to the hash table.
- Set another breakpoint that breaks, when a position with the hash code from above is read from the hash table.
- Restart your engine and see what is written, what you get back when you read it.
metax
Posts: 344
Joined: Wed Sep 23, 2009 5:56 pm
Location: Germany

Re: Unreliable mate scores

Post by metax »

Thank you for the answers. I think I'll spend some time searching the reason for this.

- I am actually using Mate Distance Pruning (I'll look again if it's implemented 100% correctly or I'll disable it and look if the bug occurs again)
- My normal mate scores are (as in most engines) in the form mate_value - currentDepth (currentDepth = distance to the root). What I do when storing mate scores in the TT is: I add back the currentDepth when storing it and subtract the currentDepth _at that time_ when I retrieve the value from the TT (but, of course, I don't store that modified value in the TT, but only return it). If have not looked in other engine code dealing with storing mate scores in the TT so far but my approach seems reasonable to me...
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Unreliable mate scores

Post by Sven »

metax wrote:Thank you for the answers. I think I'll spend some time searching the reason for this.

- I am actually using Mate Distance Pruning (I'll look again if it's implemented 100% correctly or I'll disable it and look if the bug occurs again)
- My normal mate scores are (as in most engines) in the form mate_value - currentDepth (currentDepth = distance to the root). What I do when storing mate scores in the TT is: I add back the currentDepth when storing it and subtract the currentDepth _at that time_ when I retrieve the value from the TT (but, of course, I don't store that modified value in the TT, but only return it). If have not looked in other engine code dealing with storing mate scores in the TT so far but my approach seems reasonable to me...
I hope you don't always *subtract* your currentDepth but do the right thing depending on the sign. The result must be that the mate score that you store is relative to the current node, not to the root, while within the search you are dealing with scores relative to the root.

So for a positive mate score "+(mate in N plies)" you'll subtract currentDepth before storing, and add back the (potentially different) currentDepth when retrieving from the TT.

And for a negative mate score "-(mated in N plies)" you'll *add* currentDepth before storing, and *subtract* when retrieving.

So in both cases the absolute value gets lowered before storing it in the TT.

This is a common source of problems, I think.

Sven
metax
Posts: 344
Joined: Wed Sep 23, 2009 5:56 pm
Location: Germany

Re: Unreliable mate scores

Post by metax »

@Sven: No, of course I do not always add the depth.

Code: Select all

                        value = entry->Value;

                        if (entry->Value > MATEVAL - PLY_MAX)
                        {
                            value = entry->Value - currentDepth;
                        }
                        if (entry->Value < -MATEVAL + PLY_MAX)
                        {
                             value = entry->Value + currentDepth;
                        }
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Unreliable mate scores

Post by Sven »

metax wrote:@Sven: No, of course I do not always add the depth.

Code: Select all

                        value = entry->Value;

                        if (entry->Value > MATEVAL - PLY_MAX)
                        {
                            value = entry->Value - currentDepth;
                        }
                        if (entry->Value < -MATEVAL + PLY_MAX)
                        {
                             value = entry->Value + currentDepth;
                        }
Correct for retrieving from TT. So I assume you do just the opposite when storing.

Maybe it has not been noticed that my own explanation was just wrong :oops: In the following, "negate" the red parts:
Sven Schüle wrote:So for a positive mate score "+(mate in N plies)" you'll subtract currentDepth before storing, and add back the (potentially different) currentDepth when retrieving from the TT.

And for a negative mate score "-(mated in N plies)" you'll *add* currentDepth before storing, and *subtract* when retrieving.

So in both cases the absolute value gets lowered before storing it in the TT.
In fact it is just the opposite: the absolute value is increased before storing, and decreased when retrieving. As I wrote: a common source of problems, even when posting here ...

So to sum up, it seems that this is not causing your error. Does it still exist?

Sven
User avatar
Desperado
Posts: 879
Joined: Mon Dec 15, 2008 11:45 am

Re: Unreliable mate scores

Post by Desperado »

Just another (maybe simple) question on this topic.

How does "aging" influence the mateScores stored
in the ttb ?!

I mean, if we have mateScores from previous
search stored in the table, shouldnt they be updated too ?
(similar to the relative scores within a search ?)

(i ask for this because i update my code for ttbs at the moment
and some strange things are happening :lol:.
just confusing me at the moment :? :? )
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Unreliable mate scores

Post by Sven »

Desperado wrote:Just another (maybe simple) question on this topic.

How does "aging" influence the mateScores stored
in the ttb ?!

I mean, if we have mateScores from previous
search stored in the table, shouldnt they be updated too ?
(similar to the relative scores within a search ?)

(i ask for this because i update my code for ttbs at the moment
and some strange things are happening :lol:.
just confusing me at the moment :? :? )
If you store adjusted mate scores, i.e. relative to the current position instead of the root, then they remain valid independent from the age of the search, so I don't think there is anything to be updated.

Can you describe the strange things that are happening for you now?

Sven
User avatar
Desperado
Posts: 879
Joined: Mon Dec 15, 2008 11:45 am

Re: Unreliable mate scores

Post by Desperado »

[d]3R4/qb3p1p/1p2p1pk/pB2P3/4PP2/Q3K1P1/7r/8 w - - 0 42

just one example.

here my engine starts the line with Df8+ ... and a correct mate-score.
Suddenly it blunders the queen for nothing with a mate in one, thinking
it is mating the opponent.

now having a look on this position, i went forward and backward
while let the engine thinking (cb-gui).
It blunders by random just like:

ex1:
Dg5 with m#1 ??

[d]3R4/qb2Qp2/1p2p1pp/pB2P2k/4PP2/4K1P1/7r/8 w - - 0 44

or if the line is continued with Rd2 - Kg4

Rh2 is given with mate in 1,2,3.

all i did is going forward and backward through the position
while the engine thinks.Especially doing this the engine begins
to go crazy.

Code: Select all

//--------writeTTB----------------------
//--------------------------------------

void writeTTB(TRANSTABLE_T	*ttb,
			     BOARD_T		  *brd,
			     MVE_T			 mve,
			     VAL_T			 score,
			     PLY_T			 rdp,
			     int			   type)
	{
	 TRANSDAT_T *tdat = connectTTB(ttb,brd->key);

	 //empty slot
	 if(tdat->type == 0)
		{
		 tdat->lock = lockTTB(brd->key);
		 tdat->mve  = mve;
		 tdat->score= score;
		 tdat->rdp  = rdp;
		 tdat->type = type;
		 tdat->age  = ttb->age;
		}

	 //overwrite aged slot
	 else if(tdat->age != ttb->age)
		{
		 tdat->lock = lockTTB(brd->key);
		 tdat->mve  = mve;
		 tdat->score= score;
		 tdat->rdp  = rdp;
		 tdat->type = type;
		 tdat->age  = ttb->age;
		}

	 //position already in
	 else if(tdat->lock == lockTTB(brd->key))
		{
		 if(FULLPLY(rdp) >= tdat->rdp)
			{
			 tdat->lock = lockTTB(brd->key);
			 tdat->mve  = mve;
			 tdat->score= score;
			 tdat->rdp  = rdp;
			 tdat->type = type;
			 tdat->age  = ttb->age;
			}
		}

	 //always replace
	 else
		{
		 tdat->lock = lockTTB(brd->key);
		 tdat->mve  = mve;
		 tdat->score= score;
		 tdat->rdp  = rdp;
		 tdat->type = type;
		 tdat->age  = ttb->age;	
		}

	 return;
	}

//--------valuaToTTB--------------------
//--------------------------------------

VAL_T valueToTTB(VAL_T score,PLY_T cdp)
	{
		   if(score < lbound+MAXDEPTH) score -= cdp;
	 else if(score > ubound-MAXDEPTH) score += cdp;
	 return(score);
	}

//--------valueFrTTB--------------------
//--------------------------------------

VAL_T valueFrTTB(VAL_T score,PLY_T cdp)
	{
		   if(score < lbound + MAXDEPTH) score += cdp;
	 else if(score > ubound + MAXDEPTH) score -= cdp;
	 return(score);
	}
and retrieving looks for the moment like this...

Code: Select all

	 if(lockTTB(brd->key) == tdat->lock)
		{
		 ttb->hits++;

		 pd->tScore = valueFrTTB(tdat->score,cdp);
		 pd->tmv	= tdat->mve;

		 if(tdat->type == typeEX)
			{
			 if(FULLPLY(rdp) < tdat->rdp) return(pd->tScore);
			}
		 else if(tdat->type == typeLB)
			{
			 if(FULLPLY(rdp) < tdat->rdp)
			 if(pd->tScore>=beta) return(pd->tScore);
			}
		 else if(tdat->type == typeUB)
			{
			 if(FULLPLY(rdp) < tdat->rdp)
			 if(pd->tScore<=alpha) return(pd->tScore);
			}
		}
:shock: :? :lol:

Michael
User avatar
Desperado
Posts: 879
Joined: Mon Dec 15, 2008 11:45 am

Re: Unreliable mate scores

Post by Desperado »

just posted, just saw a bug, which i fixed immediatelly...

writeTTB(...)

Code: Select all


if(FULLPLY(rdp) >= tdat->rdp)

has to be (rdp >= tdat->rdp).

but that doesnt fix the problem... :cry:

anyway one simple bug less...

Perhaps i should mention:

score: given to writeTTB()with : valueToTTB(score)
rdp : given to writeTTB()with : FULLPLY(rdp)

and additionally type-param is

Code: Select all

//--------typeTTB-----------------------
//--------------------------------------

extern __inline int typeTTB(VAL_T score,
							       int	alphaOld,
							       int	beta)
	{
	 int type = 0;

		  if(score <= alphaOld)	type = typeUB;
	 else if(score >= beta)		type = typeLB;
	 else						      type = typeEX;

	 return(type);
	}
Micha
User avatar
Desperado
Posts: 879
Joined: Mon Dec 15, 2008 11:45 am

Re: Unreliable mate scores

Post by Desperado »

just one more info:

the situation becomes more crazy

if i change the statements when retrieving from

FULLPLY(rdp) < rdp

into

FULLPLY(rdp) <= rdp

???!!!

edit!:

uhps, second bug found in valueFrTTB (ubound+maxdepth ???)

i think everything works now, like it should :).

from now i will always debug my code online :lol: :lol: