Ah, ok, interesting approach. Here are some thoughts.lithander wrote: ↑Tue Jul 05, 2022 12:49 pm Here's the source code of one of my attempts to do add a king-safety related term. Basically it counts how many squares around the king are threatened by enemy pieces. If the same square is attacked by multiple pieces the threatcounter increases each time so the count can be bigger than the amount of squares around the king. Then you modify the evaluation based on that counter and a lookup how that should affect the evaluation from the two arrays. One adjusts the base score (midgame) the other governs the modification of that base score as the game transitions into endgame.
The values in these arrays are tuned by extending the feature-vector so that each position will set a component to one that is exclusively associated with a specific threatcount on a specific king. So each position will set two components - one for the black king and one for the white king.Code: Select all
static short[] KingThreatsBase = new short[20] { -56, -50, -48, -51, -47, -36, -27, 1, 8, 37, 81, 42, 51, 91, 4, 0, 0, 0, 0, 0, }; static short[] KingThreatsEndgame = new short[20] { 45, 39, 23, 37, 34, 15, 14, -23, -29, -66, -94, -34, 22, 15, 0, 0, 0, 0, 0, 0, }; public static void Update(BoardState board, ref EvalTerm eval) { //White int count = Features.CountBlackKingThreats(board); eval.Base += KingThreatsBase[count]; eval.Endgame += KingThreatsEndgame[count]; //Black count = Features.CountWhiteKingThreats(board); eval.Base -= KingThreatsBase[count]; eval.Endgame -= KingThreatsEndgame[count]; }
In the middle game it seems that a threatcount of 7 or more on the opposing king starts to be a sign for a winning position and less starts to be contributing to a losing position. Each slot in the array represents a few percent of positions and can be tuned linearly. It's resulting in a lookup table for a function mapping the threat-count to a value and this function is not constrained to be linear as far as I can see.
...but on the other hand it doesn't work. So I'm sure I'm missing something important. Looking forward to your paper!
In Blunder, I have a couple of conditions for when king safety can be evaluated. The queen has to be on the board, there have to be at least two pieces attacking the king, including the queen, and king safety is only applied to the middlegame score.
The first two restrictions help Blunder to avoid getting itself in losing positions over an unsound attack, especially one with no queen. And the last helps Blunder to avoid hiding it's king away as the endgame approach since there are less threats and the king should start becoming more active.
So trying to add some of the above restrictions to your scheme may help things work a little bit better.
Second, I think it might help to score attack squares based on the type of piece that's attacking. So a queen attacking three squares isn't treated the same as a knight attacking three squares. I think this would help teach the engine when it has a good attack (e.g. queen and two minors bearing down around an exposed king), versus a more unsound one (e.g. bishop and rook laser-beaming an exposed king).
Lastly, I remember in the past I tried directly tuning the attack table for king safety, but it never produced very good results, and I was advised by some other authors on the forum that if I wanted to tune an attack table, it'd be better to tune the coefficients of some formula which is used to create a non-linear attack table, instead of exposing the table directly to the tuner. So that might be something to try as well.
And thanks, hopefully this paper will be wrapped up pretty soon
