lichess.org
Donate

Computer chess analysis

hey ojb and other fellow computer analyser amateurs, I did roll my own stockfish analyser in scala.

I'd like to get your advice on the best way to communicate with stockfish (or any UCI engine I suppose).

Actually for each move, I set the previous position and run the go command.

For instance, for a game like "1. h4 e5 2. d4 exd4 3. Qxd4 Nc6 4. ..."

I will have this output:

position startpos moves
go movetime 500
bestmove d2d4 ponder (none)
position startpos moves h2h4
go movetime 500
bestmove d7d5 ponder (none)
position startpos moves h2h4 e7e5
go movetime 500
info depth 1 seldepth 1 score cp 20 nodes 82 nps 166 time 493 multipv 1 pv b1c3
info depth 2 seldepth 2 score cp -32 nodes 293 nps 593 time 494 multipv 1 pv b1c3 b8c6
info depth 3 seldepth 3 score cp 20 nodes 468 nps 947 time 494 multipv 1 pv b1c3 b8c6 g1f3
info depth 4 seldepth 4 score cp -24 nodes 826 nps 1652 time 500 multipv 1 pv b1c3 b8c6 g1f3 d7d5
info depth 5 seldepth 5 score cp -4 nodes 1518 nps 2599 time 584 multipv 1 pv b1c3 b8c6 g1f3 g8f6 d2d4
bestmove b1c3 ponder b8c6
position startpos moves h2h4 e7e5 d2d4
go movetime 500
info depth 1 seldepth 1 score cp 64 nodes 53 nps 53000 time 1 multipv 1 pv e5d4 d1d4 b8c6
info depth 2 seldepth 2 score cp 52 nodes 208 nps 208000 time 1 multipv 1 pv e5d4 d1d4 b8c6 d4e4 g8e7
info depth 3 seldepth 4 score cp 32 nodes 717 nps 358500 time 2 multipv 1 pv e5d4 c2c3 d4c3 b1c3
info depth 4 seldepth 4 score cp 32 nodes 1079 nps 67437 time 16 multipv 1 pv e5d4 c2c3 d4c3 b1c3
info depth 5 seldepth 6 score cp 40 nodes 2281 nps 25344 time 90 multipv 1 pv e5d4 g1f3 c7c5 c2c3 d8a5
info depth 6 seldepth 7 score cp 20 nodes 6237 nps 24081 time 259 multipv 1 pv e5d4 g1f3 g8f6 c2c3 b8c6 c3d4
bestmove e5d4 ponder g1f3

For each move I get the engine "bestmove", so I can tell if there was a better move.
Also I gather the cp and mate scores from the *last info line*.
With the previous example, for the last move I will have {playermove: e5d4, bestmove: e5d4, cp: 20, mate: null}

I'm not sure that's the correct way to go. Especially I'm not sure whether the "cp" represents the state before or after the player moves e5d4.
And I'm also unsure how to get the score delta. I'd like to be able, for each move, to tell "Hey, that move sucks, you lose x cp" or something along this line.

What do you think, am I going the right way? Can you suggest improvements?
A different way is to make the engine find the values of player moves with the 'searchmoves [moves]' option on the 'go' command. Take a silly example like

'position startpos moves d2d4 g7g5'

now

'go movetime 500'

gives you the best engine move, with output like

'info depth 12 seldepth 16 score cp 117 nodes 70510 nps 158449 time 445 multipv 1 pv c1g5 c7c5 g1f3 f8g7 b1c3 c5d4 f3d4 b8c6 d4b5 g8f6 c3d5 f6e4 b5c7 e8f8 c7a8 e4g5
bestmove c1g5 ponder c7c5'

If the player instead makes a move like g3, you get its value by

'go movetime 500 searchmoves g2g3'

with output like

'info depth 10 seldepth 15 score cp 52 nodes 46409 nps 145940 time 318 multipv 1 pv g2g3 h7h6 b1c3 g8f6 g1f3 d7d6 e2e4 g5g4 f3h4 b8c6
bestmove g2g3 ponder h7h6'

So the unconstrained engine move c1g5 gave a value of 117 cp and the move g2g3, chosen by the player, gave 57 cp. Assuming I've understood correctly, you should get a usable delta of -60 here.

I'm not sure if there's much difference to what you're doing except that the cp seem to be displayed from the perspective relative to the player whose move it is as opposed to constantly as white vs black. So in your case, since you feed two different positions with first white to move and the black to move, you'd have to calculate the delta by double minus:

[value of the engine move after h2h4 e7e5] - (-[value of the engine move after h2h4 e7e5 d2d4])

as opposed to

[value of the engine move after h2h4 e7e5] - [value of d2d4 after h2h4 e7e5]
that's interresting. The thing is that if I use "searchmoves g2g3" then I won't get the alternative bestmove.

And I don't want to run two analysis per move if possible.
Yeah, yours looks more sensible now that I think of it. Stockfish does seem to cache its results from 'searchmoves g2g4' and use them to save time if the next position matches that move. With some quick experimentation there doesn't seem to be a huge difference between the engine moves and their evaluations between (assuming position ABC)

position startpos moves ABCD
go movetime x

vs

go movetime ½x searchmoves D
position startpos moves ABCD
go movetime ½x

But even in the latter case you're better off comparing between the results of successive 'go movetime ½x' lines rather than using the results of the searchmoves lines directly at all since those are effectively just intermediary.
Your way looks good to me. I don't think you can avoid doing another analysis if the player misses the best move (unless you start doing multi-PV analysis, which is a whole other ball game). This is what allows you to get the delta, by comparing the engine evaluations of the position before and after the suboptimal move

"Especially I'm not sure whether the "cp" represents the state before or after the player moves e5d4." It's the evaluation of hte position before e5d4 (an easy thought experiment is analysing the start position). However of course the evaluation is predicated on perfect play, so if you don't play e5d4 the evaluation will suffer. :-)
cp is unit abbreviation for centi-pawns.

An advantage of +3.57 pawns for White is converted to an advantage of +357 cp. Advantages are calculated while analysis is in session, not after.

This topic has been archived and can no longer be replied to.