New engine: Peacekeeper

Discussion of chess software programming and technical issues.

Moderator: Ras

Sazgr
Posts: 66
Joined: Thu Dec 09, 2021 8:26 pm
Full name: Kyle Zhang

Re: New engine: Peacekeeper

Post by Sazgr »

I have done something along the lines of what you suggested, and although it did not speed up noticeably, the code got shorter by around 30 lines! Thank you so much!
Sazgr
Posts: 66
Joined: Thu Dec 09, 2021 8:26 pm
Full name: Kyle Zhang

Mobility evaluation question

Post by Sazgr »

Hi all,

Lately I have been implementing mobility into my chess engine. Right now, whenever static_eval() is called, I look up the attack mask of each knight, bishop, rook, and queen and index the popcount of that attack bitboard into an array with cp values. It seems to work with fixed nodes, but the problem is that all the magic lookups (one for each slider) in static evaluation now singlehandedly slows my engine down by more than 20%, causing the matches with time control instead to turn out inconclusive. Is there a way to speed up mobility evaluation? Also, I feel there is more than 47.7 elo to gain, is there any way I could improve mobility evaluation? Thanks very much.

Fixed nodes match

Code: Select all

Score of peacekeeper-more vs peacekeeper-less: 258 - 176 - 167  [0.568] 601
...      peacekeeper-more playing White: 138 - 83 - 80  [0.591] 301
...      peacekeeper-more playing Black: 120 - 93 - 87  [0.545] 300
...      White vs Black: 231 - 203 - 167  [0.523] 601
Elo difference: 47.7 +/- 23.7, LOS: 100.0 %, DrawRatio: 27.8 %
SPRT: llr 2.95 (100.1%), lbound -2.94, ubound 2.94 - H1 was accepted
Engine without mobility top, with mobility bottom (the startposition is only as an example)

Code: Select all

info score cp 8 depth 1 nodes 20 nps 17003 time 1 pv g1f3
info score cp 24 depth 2 nodes 79 nps 47693 time 1 pv g1f3 g8f6
info score cp 8 depth 3 nodes 606 nps 166059 time 3 pv g1f3 g8f6 d2d4
info score cp 24 depth 4 nodes 2109 nps 445924 time 4 pv g1f3 g8f6 d2d4 d7d5
info score cp 1 depth 5 nodes 10215 nps 1670400 time 6 pv g1f3 g8f6 d2d4 d7d5 b1c3
info score cp 24 depth 6 nodes 24299 nps 2956946 time 8 pv g1f3 g8f6 d2d4 d7d5 b1c3 b8c6
info score cp 10 depth 7 nodes 176055 nps 6416115 time 27 pv e2e4 b8c6 g1f3 g8f6 f1d3 d7d5 e4d5
info score cp 22 depth 8 nodes 503309 nps 7121296 time 70 pv g1f3 g8f6 d2d4 e7e6 b1c3 f8d6 e2e4 e8g8
info score cp 15 depth 9 nodes 1352670 nps 7880354 time 171 pv e2e4 b8c6 b1c3 g8f6 g1f3 e7e6 d2d4 f8b4 f1d3
info score cp 23 depth 10 nodes 3630433 nps 8251554 time 439 pv e2e4 e7e5 b1c3 g8f6 g1f3 b8c6 f1b5 f8d6 e1g1 e8g8
info score cp 8 depth 11 nodes 10420033 nps 8599587 time 1211 pv d2d4 g8f6 b1c3 d7d5 g1f3 e7e6 e2e3 f8d6 c3b5 e8g8 b5d6
info score cp 21 depth 12 nodes 24828556 nps 8701723 time 2853 pv d2d4 d7d5 g1f3 g8f6 e2e3 b8c6 f1d3 c6b4 e1g1 c8g4 d3e2 g4f3
info score cp 14 depth 13 nodes 94378574 nps 8547638 time 11041 pv e2e4 e7e6 b1c3 d7d5 d2d4 g8f6 c1g5 d5e4 c3e4 f8e7 e4f6 e7f6 g5f6 d8f6
info score cp 22 depth 14 nodes 389777301 nps 8403232 time 46384 pv d2d4 g8f6 g1f3 d7d5 e2e3 e7e6 f1d3 b8c6 e1g1 f8d6 c2c3 e8g8 b1d2 c8d7

info score cp 51 depth 1 nodes 20 nps 16030 time 1 pv d2d4
info score cp 24 depth 2 nodes 87 nps 42183 time 2 pv d2d4 d7d5
info score cp 31 depth 3 nodes 638 nps 154371 time 4 pv d2d4 d7d5 g1f3
info score cp 24 depth 4 nodes 2201 nps 379731 time 5 pv d2d4 d7d5 g1f3 g8f6
info score cp 33 depth 5 nodes 15495 nps 1687044 time 9 pv e2e4 d7d5 e4d5 d8d5 d2d4
info score cp 24 depth 6 nodes 52104 nps 3212409 time 16 pv d2d4 g8f6 g1f3 d7d5 b1c3 b8c6
info score cp 26 depth 7 nodes 181545 nps 4456502 time 40 pv e2e4 d7d5 e4d5 g8f6 b1c3 f6d5 d2d4
info score cp 24 depth 8 nodes 499843 nps 5260602 time 95 pv d2d4 d7d5 b1c3 b8c6 g1f3 g8f6 e2e3 e7e6
info score cp 27 depth 9 nodes 1605143 nps 6096165 time 263 pv e2e4 d7d5 e4d5 g8f6 b1c3 f6d5 c3d5 d8d5 d2d4
info score cp 36 depth 10 nodes 2722939 nps 6248319 time 435 pv e2e4 d7d5 e4d5 g8f6 b1c3 f6d5 g1f3 b8c6 d2d4 e7e6
info score cp 24 depth 11 nodes 6815132 nps 6452699 time 1056 pv e2e4 d7d5 e4d5 g8f6 b1c3 f6d5 c3d5 d8d5 d2d4 b8c6 g1f3
info score cp 43 depth 12 nodes 15551058 nps 6620097 time 2349 pv e2e4 d7d5 e4d5 g8f6 d2d4 f6d5 c2c4 d5f6 b1c3 b8c6 g1f3 e7e6
info score cp 21 depth 13 nodes 49065612 nps 6565834 time 7472 pv e2e4 d7d5 e4d5 g8f6 d2d4 f6d5 g1f3 b8c6 b1c3 e7e6 c1g5 d5c3 b2c3
info score cp 37 depth 14 nodes 186373008 nps 6460406 time 28848 pv e2e4 c7c5 b1c3 b8c6 g1f3 g8f6 d2d4 c5d4 f3d4 e7e5 d4c6 d7c6 d1d8 e8d8 c1e3
User avatar
lithander
Posts: 915
Joined: Sun Dec 27, 2020 2:40 am
Location: Bremen, Germany
Full name: Thomas Jahn

Re: Mobility evaluation question

Post by lithander »

Sazgr wrote: Fri Jan 13, 2023 9:39 pm Lately I have been implementing mobility into my chess engine. Right now, whenever static_eval() is called, I look up the attack mask of each knight, bishop, rook, and queen and index the popcount of that attack bitboard into an array with cp values. It seems to work with fixed nodes, but the problem is that all the magic lookups (one for each slider) in static evaluation now singlehandedly slows my engine down by more than 20%, causing the matches with time control instead to turn out inconclusive. Is there a way to speed up mobility evaluation? Also, I feel there is more than 47.7 elo to gain, is there any way I could improve mobility evaluation? Thanks very much.
When I go into QSearch I stop updating the mobility term of the evaluation. I just continue to update the pawn-structure term (cheap enough thanks to a pawn hash table) and material (incremental PSQT is super cheap) and that way my engine doesn't take much of a speed hit from doing mobility eval.

This may introduce a small inaccuracy to the eval but so does Qsearch by just ignoring most of the available moves and just playing winning captures. ;)
Minimal Chess (simple, open source, C#) - Youtube & Github
Leorik (competitive, in active development, C#) - Github & Lichess
Mike Sherwin
Posts: 965
Joined: Fri Aug 21, 2020 1:25 am
Location: Planet Earth, Sol system
Full name: Michael J Sherwin

Re: Mobility evaluation question

Post by Mike Sherwin »

lithander wrote: Sat Jan 14, 2023 6:28 pm This may introduce a small inaccuracy to the eval but so does Qsearch by just ignoring most of the available moves and just playing winning captures. ;)
One could make the call Qsearch( alpha, beta, 1, 1);

The first 1 is for one side and the second 1 is for the other side. Meaning that after playing all the winning captures if that side still has a 1 then that side generates the rest of the moves and plays them. But that side's 1 becomes a 0 so it can be done once anywhere in a line. Qsearch will then become far more accurate. But of course regular Search may lose a ply of depth or it might not because of better pruning from the increased accuracy of Qsearch.
User avatar
Ras
Posts: 2696
Joined: Tue Aug 30, 2016 8:19 pm
Full name: Rasmus Althoff

Re: New engine: Peacekeeper

Post by Ras »

I update the mobility during move generation where it doesn't cost much extra. The price is that the mobility data in eval are slightly outdated.
Rasmus Althoff
https://www.ct800.net
Sazgr
Posts: 66
Joined: Thu Dec 09, 2021 8:26 pm
Full name: Kyle Zhang

Re: New engine: Peacekeeper

Post by Sazgr »

Thanks for the suggestions!

I tried lithander's method over the weekend, and the speed did increase, up to within 5% of the speed without mobility evaluation! However, while playing a match the elo difference still stubbornly stuck at 0! :evil:

I will try Rasmus's way later this week, it seems good also. I have also been trying various methods of tuning the mobility bounds for more elo with varying degrees of success. Unfortunately mostly varying in how much elo I lose...
User avatar
Ras
Posts: 2696
Joined: Tue Aug 30, 2016 8:19 pm
Full name: Rasmus Althoff

Re: New engine: Peacekeeper

Post by Ras »

Sazgr wrote: Tue Jan 17, 2023 8:07 pmHowever, while playing a match the elo difference still stubbornly stuck at 0!
You can experiment with a multiplier for the motal mobility sum (white minus black) before adding that to the evaluation, like maybe 2 or 3.
Rasmus Althoff
https://www.ct800.net
User avatar
hgm
Posts: 28353
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Mobility evaluation question

Post by hgm »

lithander wrote: Sat Jan 14, 2023 6:28 pmWhen I go into QSearch I stop updating the mobility term of the evaluation.
A compromise is to incorporate the mobility in the piece values before entering QS ('static mobility'), and update your material term during QS on a per-piece basis rather than per type. This would prevent that you trade, say, a very active Knight of yourself for a trapped Knight of the opponent.

Mobility is an expensive evaluation term. To speed it up it can be calculated incrementally, but that is not really trivial.
Sazgr
Posts: 66
Joined: Thu Dec 09, 2021 8:26 pm
Full name: Kyle Zhang

Re: New engine: Peacekeeper

Post by Sazgr »

Ras wrote: Tue Jan 17, 2023 8:54 pm
Sazgr wrote: Tue Jan 17, 2023 8:07 pmHowever, while playing a match the elo difference still stubbornly stuck at 0!
You can experiment with a multiplier for the motal mobility sum (white minus black) before adding that to the evaluation, like maybe 2 or 3.
I have separately tuned multipliers for each piece right now.
Aldus
Posts: 27
Joined: Mon Sep 03, 2018 12:59 pm
Location: Romania
Full name: Cristi Ilovan

Re: New engine: Peacekeeper

Post by Aldus »

If I was writing a chess engine, I would probably consider implementing first a correct (even if slow) detection of mobility and then running fixed depth games against the older version, just to see if the new eval is any better. If this is not the case, it doesn't even worth trying to optimise it.

As to the mobility itself, we may already evaluate it without even knowing. For instance, one might argue that the Piece-Square Tables (PST) values are an approximation of mobility considering an empty board. For why does a knight on E4 have a greater PST value than a knight on A1 other that on E4 the knight has 8 moves versus only 2 on A1? This leads us to the following 2 important points:

1. Maybe mobility should not be evaluated in a simplistic and linear way (the optimum PST values for the knight on E4 and A1 are probably not 8 and 2).

2. Mobility overlaps somehow with PST.

Especially due to the last point, if we have a carefully tuned (either by hand/intuition or with Texel etc.) PST value for the knight on E4 and we suddenly and blindly add it's mobility count, we may destabilise the evaluation.

I guess mobility is both expensive to calculate and tricky to get it right. On the other hand, we may just get it left by randomly trying various ideas (as suggested here) until finding one that rises the ELO with a few points. :)