King safety evaluation

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

niel5946
Posts: 174
Joined: Thu Nov 26, 2020 10:06 am
Full name: Niels Abildskov

King safety evaluation

Post by niel5946 »

Hi.

During the last couple of days I've been struggling with writing a working king safety evaluation. Every time I try to test it against the oldest version of my engine it seems to either loose 30-60 elo or only gain a negligible 5-10 elo (as compared to the results of others's implementations that get 40-60 elo), and I dont know if it's my implementation or the weights I'm using.
My implementation is as follows:
1. Loop through the files near the king (king file plus the two adjacent files). Here i give a penalty of 25 cp if either side is missing a pawn on that file (semi-open), and 60cp if both do (open). I also give an advancement penalty ranging from 5 to 45 based on the rank of the pawn of the side to move. Additionally, I give a penalty based on how close the opponent's pawn on that file is to the king (ranging from 0 to 20). I halve the two latter scores if the two pawns on the file are directly blocking each others's advancement.
2. I scale the score for the pawn structure around the king based on the opponents's material (scalar: opponent_material/max_possible_material).
3. From mobility I have knowledge of attacks to the king, and I score this with a safety table if there are more than two attackers and the opponent has a queen.

I don't score any king safety in the endgame yet, but I am planning on implementing some king pawn tropism to make the king protect pawns late in the game.

The above implementation is heavily inspired by the wiki post: https://www.chessprogramming.org/King_Safety, and the safety table is done exactly as suggested on that page, with the same weights.

My eval at the moment consists of material, piece square tables, mobility and space, so I am thinking that king safety should be the next step.

Has anybody else had problems with creating a proper king safety evaluation? And is there something that seems wrong with my implementation above?

Thanks in advance :D

PS: I have checked symmetry with 300 positions, where i did the eval, mirrored the board, and did it again, and this is correct. Therefore I can at least outrule that bug.
Author of Loki, a C++ work in progress.
Code | Releases | Progress Log |
Mike Sherwin
Posts: 860
Joined: Fri Aug 21, 2020 1:25 am
Location: Planet Earth, Sol system
Full name: Michael J Sherwin

Re: King safety evaluation

Post by Mike Sherwin »

niel5946 wrote: Mon Mar 29, 2021 1:27 pm Hi.

During the last couple of days I've been struggling with writing a working king safety evaluation. Every time I try to test it against the oldest version of my engine it seems to either loose 30-60 elo or only gain a negligible 5-10 elo (as compared to the results of others's implementations that get 40-60 elo), and I dont know if it's my implementation or the weights I'm using.
My implementation is as follows:
1. Loop through the files near the king (king file plus the two adjacent files). Here i give a penalty of 25 cp if either side is missing a pawn on that file (semi-open), and 60cp if both do (open). I also give an advancement penalty ranging from 5 to 45 based on the rank of the pawn of the side to move. Additionally, I give a penalty based on how close the opponent's pawn on that file is to the king (ranging from 0 to 20). I halve the two latter scores if the two pawns on the file are directly blocking each others's advancement.
2. I scale the score for the pawn structure around the king based on the opponents's material (scalar: opponent_material/max_possible_material).
3. From mobility I have knowledge of attacks to the king, and I score this with a safety table if there are more than two attackers and the opponent has a queen.

I don't score any king safety in the endgame yet, but I am planning on implementing some king pawn tropism to make the king protect pawns late in the game.

The above implementation is heavily inspired by the wiki post: https://www.chessprogramming.org/King_Safety, and the safety table is done exactly as suggested on that page, with the same weights.

My eval at the moment consists of material, piece square tables, mobility and space, so I am thinking that king safety should be the next step.

Has anybody else had problems with creating a proper king safety evaluation? And is there something that seems wrong with my implementation above?

Thanks in advance :D

PS: I have checked symmetry with 300 positions, where i did the eval, mirrored the board, and did it again, and this is correct. Therefore I can at least outrule that bug.
There is another way to judge king safety, if you're interested. For each root move keep a count of nodes. And count all the times that the stm's king is checked and checkmated. Weight checkmates higher than checks. Then create a ratio (checks.adjusted + checkmates.adjusted) / root_move_nodes to get a ratio. Use that ratio to adjust the score of the root move. The caveat is that this will require a failsoft implementation.
IanKennedy
Posts: 55
Joined: Sun Feb 04, 2018 12:38 pm
Location: UK

Re: King safety evaluation

Post by IanKennedy »

What happens in the games it loses? Maybe post some samples.

have you tried halving the new ksaf factor as an experiment? It may just be too strong.

Mine goes like this:

sum attackers and attacked squares adjacent to king

sum friendly pieces on adjacent squares

ksaf -= attackers * attackedsquares
ksaf += friendlydefenders * ksaf-factor

return ksaf * game-phase-factor

I think my initial attempt had to be 'turned down' somewhat IIRC, but the signs for that should be rather obvious.
Author of the actively developed PSYCHO chess engine
niel5946
Posts: 174
Joined: Thu Nov 26, 2020 10:06 am
Full name: Niels Abildskov

Re: King safety evaluation

Post by niel5946 »

Mike Sherwin wrote: Mon Mar 29, 2021 5:38 pm
niel5946 wrote: Mon Mar 29, 2021 1:27 pm Hi.

During the last couple of days I've been struggling with writing a working king safety evaluation. Every time I try to test it against the oldest version of my engine it seems to either loose 30-60 elo or only gain a negligible 5-10 elo (as compared to the results of others's implementations that get 40-60 elo), and I dont know if it's my implementation or the weights I'm using.
My implementation is as follows:
1. Loop through the files near the king (king file plus the two adjacent files). Here i give a penalty of 25 cp if either side is missing a pawn on that file (semi-open), and 60cp if both do (open). I also give an advancement penalty ranging from 5 to 45 based on the rank of the pawn of the side to move. Additionally, I give a penalty based on how close the opponent's pawn on that file is to the king (ranging from 0 to 20). I halve the two latter scores if the two pawns on the file are directly blocking each others's advancement.
2. I scale the score for the pawn structure around the king based on the opponents's material (scalar: opponent_material/max_possible_material).
3. From mobility I have knowledge of attacks to the king, and I score this with a safety table if there are more than two attackers and the opponent has a queen.

I don't score any king safety in the endgame yet, but I am planning on implementing some king pawn tropism to make the king protect pawns late in the game.

The above implementation is heavily inspired by the wiki post: https://www.chessprogramming.org/King_Safety, and the safety table is done exactly as suggested on that page, with the same weights.

My eval at the moment consists of material, piece square tables, mobility and space, so I am thinking that king safety should be the next step.

Has anybody else had problems with creating a proper king safety evaluation? And is there something that seems wrong with my implementation above?

Thanks in advance :D

PS: I have checked symmetry with 300 positions, where i did the eval, mirrored the board, and did it again, and this is correct. Therefore I can at least outrule that bug.
There is another way to judge king safety, if you're interested. For each root move keep a count of nodes. And count all the times that the stm's king is checked and checkmated. Weight checkmates higher than checks. Then create a ratio (checks.adjusted + checkmates.adjusted) / root_move_nodes to get a ratio. Use that ratio to adjust the score of the root move. The caveat is that this will require a failsoft implementation.
That sounds like an interesting idea to try out! Unfortunately, I use a fail-hard implementation, so this is not possible at the moment. But I have thought about changing to fail-soft, so if I get around to doing it, I will keep this in mind :D
Author of Loki, a C++ work in progress.
Code | Releases | Progress Log |
Mike Sherwin
Posts: 860
Joined: Fri Aug 21, 2020 1:25 am
Location: Planet Earth, Sol system
Full name: Michael J Sherwin

Re: King safety evaluation

Post by Mike Sherwin »

niel5946 wrote: Mon Mar 29, 2021 5:44 pm
Mike Sherwin wrote: Mon Mar 29, 2021 5:38 pm
niel5946 wrote: Mon Mar 29, 2021 1:27 pm Hi.

During the last couple of days I've been struggling with writing a working king safety evaluation. Every time I try to test it against the oldest version of my engine it seems to either loose 30-60 elo or only gain a negligible 5-10 elo (as compared to the results of others's implementations that get 40-60 elo), and I dont know if it's my implementation or the weights I'm using.
My implementation is as follows:
1. Loop through the files near the king (king file plus the two adjacent files). Here i give a penalty of 25 cp if either side is missing a pawn on that file (semi-open), and 60cp if both do (open). I also give an advancement penalty ranging from 5 to 45 based on the rank of the pawn of the side to move. Additionally, I give a penalty based on how close the opponent's pawn on that file is to the king (ranging from 0 to 20). I halve the two latter scores if the two pawns on the file are directly blocking each others's advancement.
2. I scale the score for the pawn structure around the king based on the opponents's material (scalar: opponent_material/max_possible_material).
3. From mobility I have knowledge of attacks to the king, and I score this with a safety table if there are more than two attackers and the opponent has a queen.

I don't score any king safety in the endgame yet, but I am planning on implementing some king pawn tropism to make the king protect pawns late in the game.

The above implementation is heavily inspired by the wiki post: https://www.chessprogramming.org/King_Safety, and the safety table is done exactly as suggested on that page, with the same weights.

My eval at the moment consists of material, piece square tables, mobility and space, so I am thinking that king safety should be the next step.

Has anybody else had problems with creating a proper king safety evaluation? And is there something that seems wrong with my implementation above?

Thanks in advance :D

PS: I have checked symmetry with 300 positions, where i did the eval, mirrored the board, and did it again, and this is correct. Therefore I can at least outrule that bug.
There is another way to judge king safety, if you're interested. For each root move keep a count of nodes. And count all the times that the stm's king is checked and checkmated. Weight checkmates higher than checks. Then create a ratio (checks.adjusted + checkmates.adjusted) / root_move_nodes to get a ratio. Use that ratio to adjust the score of the root move. The caveat is that this will require a failsoft implementation.
That sounds like an interesting idea to try out! Unfortunately, I use a fail-hard implementation, so this is not possible at the moment. But I have thought about changing to fail-soft, so if I get around to doing it, I will keep this in mind :D
It can be done for the first few (2 or 4) ply to get king safety for both sides. Four ply would be more refined over two ply.
niel5946
Posts: 174
Joined: Thu Nov 26, 2020 10:06 am
Full name: Niels Abildskov

Re: King safety evaluation

Post by niel5946 »

IanKennedy wrote: Mon Mar 29, 2021 5:41 pm What happens in the games it loses? Maybe post some samples.

have you tried halving the new ksaf factor as an experiment? It may just be too strong.

Mine goes like this:

sum attackers and attacked squares adjacent to king

sum friendly pieces on adjacent squares

ksaf -= attackers * attackedsquares
ksaf += friendlydefenders * ksaf-factor

return ksaf * game-phase-factor

I think my initial attempt had to be 'turned down' somewhat IIRC, but the signs for that should be rather obvious.
I am running a test now with some additional pawn shield terms like empty flank and endgame king pawn tropism, but I don't think it'll be much better... When it is done I will look through some of the games and post a PGN if any of them seem odd.
I have tried halving the values from the king safety table, but it didn't really give an improvement. This might be because I also scored king attacks in the endgame, which I've removed. I'll try this again.

King defenders, as I see you're using, might also be a good idea to add. I don't have that right now, and I suspect that because of this, the engine realizes too late that its king is severely threatened, and doesn't have time to bring over defenders...

Thank you for the answer :)
Author of Loki, a C++ work in progress.
Code | Releases | Progress Log |
User avatar
silentshark
Posts: 327
Joined: Sat Mar 27, 2010 7:15 pm

Re: King safety evaluation

Post by silentshark »

Well tuned king safety is not easy, not something that can be cracked quickly, for sure.

I don't have the answer, other than gradual tweaking then lots of testing. Maybe automated tuning (Texel tuning etc.) is a good way forward for tuning king safety and other stuff.
amanjpro
Posts: 883
Joined: Sat Mar 13, 2021 1:47 am
Full name: Amanj Sherwany

Re: King safety evaluation

Post by amanjpro »

I am on the same boat, it has been more than a month trying to tune king safety, and all I get is either lame boosts or dramatic elo cuts :(
User avatar
emadsen
Posts: 434
Joined: Thu Apr 26, 2012 1:51 am
Location: Oak Park, IL, USA
Full name: Erik Madsen

Re: King safety evaluation

Post by emadsen »

I managed to get about 60 ELO from king safety by tracking "points" that negatively impact king safety. I track these king safety points when I calculate piece mobility. Piece mobility examines potential moves. These potential moves may include moves to squares near the opponent king. I'm interested in attacks on the outer ring (16 squares) and inner ring (8 squares) around the king.
  • Add a point (x minorAttackOuterRing) for each knight move to an outer ring square.
  • Add a point (x minorAttackInnerRing) for each knight move to an inner ring square.
  • Add a point (x minorAttackOuterRing) for each bishop move to an outer ring square.
  • Add a point (x minorAttackInnerRing) for each bishop move to an inner ring square.
  • Add a point (x rookAttackOuterRing) for each rook move to an outer ring square.
  • Add a point (x rookAttackInnerRing) for each rook move to an inner ring square.
  • Add a point (x queenAttackOuterRing) for each queen move to an outer ring square.
  • Add a point (x queenAttackInnerRing) for each queen move to an inner ring square.
Like this:

Code: Select all

private static int GetKingSafetyIndexIncrement(ulong PieceDestinations, ulong KingOuterRing, ulong KingInnerRing,
  int OuterRingAttackWeight, int InnerRingAttackWeight)
{
    var attackedOuterRingSquares = Bitwise.CountSetBits(PieceDestinations & KingOuterRing);
    var attackedInnerRingSquares = Bitwise.CountSetBits(PieceDestinations & KingInnerRing);
    return (attackedOuterRingSquares * OuterRingAttackWeight) + (attackedInnerRingSquares * InnerRingAttackWeight);
}
Optionally, add points for open files near the king or missing pawn shield in front of the king.

Then lookup the king safety score in a pre-computed array (kingSafety = _kingSafety[points]) where the array's values increase by the square of the index.

Code: Select all

for (var index = 0; index < _kingSafety.Length; index++) // Length = 64
{
    var scale = -Config.KingSafetyScalePer128 / 128d;
    _kingSafety[index] = GetNonLinearBonus(index, scale, 2, 0);
}

public static int GetNonLinearBonus(double Bonus, double Scale, double Power, int Constant) =>
  (int)(Scale * Math.Pow(Bonus, Power)) + Constant;
Tune all these weights using the Texel tuning technique.
My C# chess engine: https://www.madchess.net
jdart
Posts: 4366
Joined: Fri Mar 10, 2006 5:23 am
Location: http://www.arasanchess.org

Re: King safety evaluation

Post by jdart »

My code for this is complex, but the core of it sums attack "weights" for each piece attacking squares near the king. The weights depend on piece type and take into account "stacked" attackers like a Rook behind a Queen. The sum is then put through a sigmoid function. There is more to it than that - for example, there's also some interaction between king cover and king safety, so an uncovered king gets more attack points and there is some scoring for friendly pieces near the king that reduce the attack factor.

No claim this optimal but it has been tuned and it doesn't make weird unsound sacs, which is easy to have happen if you value king attacks too highly. And it destroys programs w/o king safety or very weak king safety.