Question to syzygy author

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: Question to syzygy author

Post by mcostalba »

syzygy wrote: It seems to be correct.
Thanks!

I have further simplified the opponent DTZ search loop

https://github.com/official-stockfish/S ... .cpp#L1487

It seems to work on my test cases, but I would be more confident if you could give it a look.
syzygy
Posts: 5557
Joined: Tue Feb 28, 2012 11:56 pm

Re: Question to syzygy author

Post by syzygy »

mcostalba wrote:
syzygy wrote: It seems to be correct.
Thanks!

I have further simplified the opponent DTZ search loop

https://github.com/official-stockfish/S ... .cpp#L1487

It seems to work on my test cases, but I would be more confident if you could give it a look.
This seems to go wrong for a winning position with at least one losing move. It will return a negative dtz. So don't update minDTZ if WDLScore > 0 and dtz < 0.

I don't know if you missed my earlier suggestion or prefer your current approach, but in the ZEROING_MOVE case, you could simply set dtz to 0 and fall through to the "*result != CHANGE_STM" test to convert wdl to -101/-1/1/101.
syzygy
Posts: 5557
Joined: Tue Feb 28, 2012 11:56 pm

Re: Question to syzygy author

Post by syzygy »

syzygy wrote:
mcostalba wrote:
syzygy wrote: It seems to be correct.
Thanks!

I have further simplified the opponent DTZ search loop

https://github.com/official-stockfish/S ... .cpp#L1487

It seems to work on my test cases, but I would be more confident if you could give it a look.
This seems to go wrong for a winning position with at least one losing move. It will return a negative dtz. So don't update minDTZ if WDLScore > 0 and dtz < 0.
The problem is more serious.

Suppose the position is losing and has a pawn move or a capture.
The pawn move or capture will also be losing, obviously. They would convert immediately into another lost position, so they should count as dtz = -1 or dtz = -101 (if cursed).
But your code will look up the dtz for the position after the pawn move or capture. That dtz could be -10 or -20 or whatever number you like.

For winning positions the problem does not occur, because at this point we know there are no winning pawn moves or captures.

So you really have to treat pawn moves or captures differently in the losing case (and you can skip them in the winning case). The previous code showed how to do it (with special treatment for cursed loss etc.).
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: Question to syzygy author

Post by mcostalba »

syzygy wrote:The problem is more serious.
You are right. This is my second attempt:

https://github.com/official-stockfish/S ... .cpp#L1500
syzygy
Posts: 5557
Joined: Tue Feb 28, 2012 11:56 pm

Re: Question to syzygy author

Post by syzygy »

mcostalba wrote:
syzygy wrote:The problem is more serious.
You are right. This is my second attempt:

https://github.com/official-stockfish/S ... .cpp#L1500
The first branch of this line makes little sense:

Code: Select all

 dtz = isZeroingMove ? -zeroing_move_dtz&#40;wdl&#41; &#58; -probe_dtz&#40;pos, result&#41;;
A losing capture would be scored positive. If the only legal move is a losing capture, you will return 0x10000.

Even if you correct the sign, it wil not work. In a winning position, a drawing or losing capture will now be counted as an immediate win. So it will return dtz = 1 (or 101 if cursed win), which is wrong.

For wdl > 0, the zeroing moves may be skipped (or counted as 0 or something).

For wdl < 0, all zeroing moves may be counted as zeroing_move_dtz(wdl).
(Doing a call to probe_ab() in case wdl == -1 to distinguish between a losing and a cursed losing zeroing move is not necessary, I now realise.)
syzygy
Posts: 5557
Joined: Tue Feb 28, 2012 11:56 pm

Re: Question to syzygy author

Post by syzygy »

What if you initialise minDTZ to something big if wdl > 0 and to zeroing_move_dtz(wdl) + 1 if wdl < 0? Then you can skip probing all zeroing moves, I think...

(The + 1 is needed because you deduct 1 later.)
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: Question to syzygy author

Post by mcostalba »

syzygy wrote:What if you initialise minDTZ to something big if wdl > 0 and to zeroing_move_dtz(wdl) + 1 if wdl < 0? Then you can skip probing all zeroing moves, I think...
Thanks!

I would like to briefly describe how I try to write code, especially complex code as this one.

For me code should be easy to understand and to read and to get to this goal I use the following guidelines:

- Call variables for what they are and use them sticking to what their name suggest (in particular try to avoid giving special meanings or special case the variable). In our case if a variable is called dtz then that variable should hold the (correct) dtz value as much as possible, not a dtz value but sometimes also a 'don't care' value: this makes code more difficult to understand.

- Use each variable for exactly one thing. Don't multiplex different semantics on a single variable: use more variables for this.

- Naming is the single most important (and most difficult) effort to make code readable. A good naming means the developer understands what he is doing and the reader will understand too.

- Make the single algorithm as general as possible: prefer one general algorithm to a bunch of special case ones (even if this can be a little slower)

- Make the single algorithm as self-contained as possible, in particular the algorithm should not use/rely on external proprieties or prior knowledge: who reads the single code chunk should understand it even not knowing the context.

- Make fast code only where fast is needed (and use a profiler to verify it is actually needed), otherwise always prefer readability.


And finally here is my (hopefully last :-) ) attempt:

https://github.com/official-stockfish/S ... .cpp#L1494

In this case dtz has the correct meaning in all the cases: losing capture in winning position, drawing move when winning, losing move in a cursed loss position, etc..

Not all that cases needs to be handled correctly as long as the final minDTZ does not change, but (as written above) I'd prefer to have the algorithm easy and correct without shortcuts and tricks.
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: Question to syzygy author

Post by mcostalba »

Unfortunately current bench signature is no more feasible because I have changed move generation and reorder in TB.

So I have added some instrumenting code that ensures that original TB code (the one in master) and the current one are fully in sync:

https://github.com/mcostalba/Stockfish/commit/tb_dbg

I have verified current code is fully equivalent to original one ona fixed depth 10 search on about 600 endgame positions.
syzygy
Posts: 5557
Joined: Tue Feb 28, 2012 11:56 pm

Re: Question to syzygy author

Post by syzygy »

mcostalba wrote:For me code should be easy to understand and to read
Well, I think you have succeeded in reducing the number of lines by a lot, but figuring out *why* it works correctly (if it actually does work correctly) is now a LOT harder. The original code had a clear logical plan (first ignore en passant, then fix it only as the last step, etc.).

And you have absolutely no need to teach me how to program. Really.

Now go figure it out yourself. I have had enough of correcting the bugs you are introducing even after I explain the errors that should be avoided.
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: Question to syzygy author

Post by mcostalba »

syzygy wrote:
mcostalba wrote:For me code should be easy to understand and to read
Well, I think you have succeeded in reducing the number of lines by a lot, but figuring out *why* it works correctly (if it actually does work correctly) is now a LOT harder. The original code had a clear logical plan (first ignore en passant, then fix it only as the last step, etc.).

And you have absolutely no need to teach me how to program. Really.

Now go figure it out yourself. I have had enough of correcting the bugs you are introducing even after I explain the errors that should be avoided.
I am very sorry for this. I didn't mean to teach anything, I just wanted to explain why I choose one way instead of another.

Your help is invaluable, of course I can't figure out myself the tb code without your explanations and yes, I introduce bugs and I am not quick to figure them out. Perhaps I need to redo again 2-3 times before to get it right, but I don't think this is a sin.

I don't understand why you got angry, but anyhow I apologize if I have said something wrong, of course I don't want to teach tb code to the tb author!