Undefended pieces

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

gladius
Posts: 568
Joined: Tue Dec 12, 2006 10:10 am
Full name: Gary Linscott

Undefended pieces

Post by gladius »

I thought I would try this out after the recent thread on loose pieces. The idea is that in the opening, it's good to have pieces defended by each other. So, pieces that are undefended get a small penalty. This is in addition to the penalty they may receive by being attacked by an enemy piece.

Unfortunately, it did not seem to help. It was decently promising in 16k games at 5ply fixed depth matches, showing +3-4 elo. Due to the loss of speed, this didn't carry over to timed matches that I could see.

The current version of the modification for Stockfish is below. I really like that Marco has posted Stockfish on github! Forking and playing around with the code is so easy. I should note that the branch of the fork is available here: https://github.com/glinscott/Stockfish/ ... ded_pieces.

Code: Select all

const Score UndefendedPenalty[] = {
  S(0, 0), S(3, 0), S(12, 2), S(12, 2), S(25, 6), S(45, 15)
};

// Enemy pieces not defended by a pawn
Bitboard weakEnemies =  pos.pieces(Them)
                  & ~ei.attackedBy[Them][PAWN];

Bitboard undefended = weakEnemies & ~ei.attackedBy[Them][0] & ~(Rank1BB | Rank8BB);
if (undefended)
{
  const int multipliers[] = { 0, 1, 3, 6, 12, 22, 36, 36, 36, 36, 36, 36, 36, 36, 36 };

  int undefendedCount = 0;
  while (undefended)
  {
    Square s = pop_1st_bit(&undefended);
    PieceType pt = type_of(pos.piece_on(s));
    if (pt != KING)
    {
      score += UndefendedPenalty[pt];
      if (pt != PAWN)
        undefendedCount++;
    }
  }
  score = (multipliers[undefendedCount] * score) / 32;
}
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: Undefended pieces

Post by mcostalba »

gladius wrote:I really like that Marco has posted Stockfish on github!
And I really like people experiments with SF code :-)

If your patch seems promising perhaps it is just a problem to find correct values of the parameters, I'd suggest to give it a try with CLOP or change by hand some of them. Regarding the speed your code seems ok, perhaps could be improved a bit moving array definitions in the namespace so to avoid filling them at every call:

Code: Select all

    // Move to namespace

    const Score UndefendedPenalty[] = {
        S(0, 0), S(3, 0), S(12, 2), S(12, 2), S(25, 6), S(45, 15)
    };
    
    
    const int multipliers[] = { 0, 1, 3, 6, 12, 22, 36, 36, 36, 36, 36, 36, 36, 36, 36 };
    

    // Function starts here

    int undefendedCount = 0;
    
    Bitboard undefended = (   pos.pieces(Them)
                           & ~ei.attackedBy[Them][0]
                           & ~(Rank1BB | Rank8BB)) ^ pos.pieces(KING, Them);
    while (undefended)
    {
        PieceType pt = type_of(pos.piece_on(pop_1st_bit(&undefended)));
        score += UndefendedPenalty[pt];
        if (pt != PAWN)
            undefendedCount++;
    }
    if (undefendedCount)
        score = (multipliers[undefendedCount] * score) / 32;
zamar
Posts: 613
Joined: Sun Jan 18, 2009 7:03 am

Re: Undefended pieces

Post by zamar »

Hi Gary!

I like your idea. Few notes:
- Using multipliers seems too complicated for me. I'd suggest using fixed penalty (at least for a starter).
- Having rook or queen defended is not very useful, because they are most often threathened by minors, so I'd suggest to ignore them.

So I'd propose:
- A small fixed penalty for minor not being defended. Or other way around, a small bonus when minor is defended. Or a small bonus when minor is defended by pawn.

Just my two cents.

Regards,
Joona
Joona Kiiski
gladius
Posts: 568
Joined: Tue Dec 12, 2006 10:10 am
Full name: Gary Linscott

Re: Undefended pieces

Post by gladius »

Thanks for the tips both of you!

Marco, thanks, that definitely helped the speed! When I tried testing in games as opposed to fixed depth, the ELO gain did not seem to translate. I only tested a few thousand games though. I will investigate CLOP next I think.

Joona, I tried using a fixed penalty on minors that are not supported, but couldn't get it to work well in fixed depth matches yet.

I'm not sure if that's the wisest testing strategy (using fixed depth initially, then running timed matches). Otherwise, it's so tough to get the appropriate number of games in though.
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: Undefended pieces

Post by mcostalba »

gladius wrote:Thanks for the tips both of you!

Marco, thanks, that definitely helped the speed! When I tried testing in games as opposed to fixed depth, the ELO gain did not seem to translate. I only tested a few thousand games though. I will investigate CLOP next I think.

Joona, I tried using a fixed penalty on minors that are not supported, but couldn't get it to work well in fixed depth matches yet.

I'm not sure if that's the wisest testing strategy (using fixed depth initially, then running timed matches). Otherwise, it's so tough to get the appropriate number of games in though.
Regarding the speed removing the pawns should help another bit because should reduce the needed loop cycles:

Code: Select all

        // Function starts here

    int undefendedCount = 0;

    Bitboard undefended = (pos.pieces(Them) ^ pos.pieces(KING, Them) ^ pos.pieces(PAWN, Them))
                         & ~ei.attackedBy[Them][0]
                         & ~(Rank1BB | Rank8BB) ;
    while (undefended)
    {
        PieceType pt = type_of(pos.piece_on(pop_1st_bit(&undefended)));
        score += UndefendedPenalty[pt];
        undefendedCount++;
    }
    if (undefendedCount)
        score = (multipliers[undefendedCount] * score) / 32;
Of course there is also a loss of accuracy, only test can tell if it is a good compromise. I have never tested at fixed depths, but I think could be a good way to quickly filter out useless stuff, and so could be interesting especially for evaluation terms. This alone is not enough though: only real games give real results.
gladius
Posts: 568
Joined: Tue Dec 12, 2006 10:10 am
Full name: Gary Linscott

Re: Undefended pieces

Post by gladius »

gladius wrote:Thanks for the tips both of you!

Marco, thanks, that definitely helped the speed! When I tried testing in games as opposed to fixed depth, the ELO gain did not seem to translate. I only tested a few thousand games though. I will investigate CLOP next I think.

Joona, I tried using a fixed penalty on minors that are not supported, but couldn't get it to work well in fixed depth matches yet.

I'm not sure if that's the wisest testing strategy (using fixed depth initially, then running timed matches). Otherwise, it's so tough to get the appropriate number of games in though.
Turns out that using fixed depth was not so great. I changed to using fixed node count later on, but even so, I got quite a few results where things appeared to be better at fixed testing, and didn't do well at 40/2 second.

The opposite happened with this change though! Didn't work well at fixed node count, then tested well at 40/2.

Joona, excellent call on only penalizing minors. Still not sure it's a huge win, showing +4 Elo after 8k games, but it looks promising.
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: Undefended pieces

Post by mcostalba »

Thanks Gary, I have pulled into undefended_pieces branch and I will shortly start a match at higher TC to validate the change.