ChessUSA.com TalkChess.com
Hosted by Your Move Chess & Games
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

evaluate loose pieces
Goto page 1, 2, 3  Next
 
Post new topic       TalkChess.com Forum Index -> Computer Chess Club: Programming and Technical Discussions Threaded
View previous topic :: View next topic  
Author Message
Lucas Braesch



Joined: 31 May 2010
Posts: 1732

PostPosted: Sun Feb 26, 2012 5:20 am    Post subject: evaluate loose pieces Reply to topic Reply with quote

One of the many eval components that was missing in my program. After several attempts, I eventually implemented this in the following simplistic way
Code:
static void eval_loose(const Board *B, eval_t *e)
// detect loose pieces and attribute small bonuses for attacking them
{
   assert(B->initialized && e);

   for (unsigned color = White; color <= Black; color++) {
      const unsigned us = color, them = opp_color(us);
      
      // loose pawns = undefended pawns
      uint64_t loose_pawns = B->b[them][Pawn] & ~B->st->attacks[them][NoPiece];
      
      // loose pieces = pieces either attacked by a pawn or not defended by a pawn
      uint64_t enemy_pieces = B->all[them] & ~B->b[them][Pawn];
      uint64_t loose_pieces = enemy_pieces & (~B->st->attacks[them][Pawn] | B->st->attacks[us][Pawn]);
      
      // hanging = loose and attacked
      uint64_t hanging = (loose_pawns | loose_pieces) & B->st->attacks[us][NoPiece];
      
      // scoring (a bit simplistic at the moment, at least it's fast)
      while (hanging) {
         unsigned sq = next_bit(&hanging), victim = B->piece_on[sq];
         e->op[us] += 5 + Material[Opening][victim]/32;
         e->eg[us] += 10 + Material[EndGame][victim]/32;
      }
   }
}

Just to clarify the code a little, B->st->attacks[color][piece] is a bitboard of squares attacked by (color,piece). For example B->st->attacks[Black][Knight] is the set of squares attacked by black knights. And B->st->attacks[color][NoPiece] is the set of squares attacked by any piece of color. The rest should hopefully be self-obvious.

So what I'm doing is basically:
1/ loose pawn = pawn that is not defended
2/ loose piece = piece that is not defended by a pawn, or piece that is attacked by a pawn (regardless of whether it's defended or not).
3/ hanging = loose + attacked

And the scoring function is very simplistic. There is a base score and a linear part proportional to the hanging piece (victim) value.

This approach seems rather stupid when I think about it, but in self-testing it scored almost +48 elo (1000 games) to my surprise. I suppose this kind of feature will never give a huge elo increase anyway, so a compromise has to be found between slowing down the eval and doing something intelligent but complex, and having an over simplistic fast code.

I wonder how others have done this, what they've tried, and with what kind of results.

Intuitively, my thought of hanging pieces is the following:
1/ the quiescent search will grab hanging pieces if it can. but it will choose a stand pat score when the side to move has pieces hanging. so if your opponent has a hanging piece and the quiescent search doesn't chose to take it, there's generally a good reason for it (losing SEE, checks involved, or other complications such as discovering new attacks etc.). However, even if the opponent hanging piece is SEE defended, or defended by other considerations (discovering other attacks etc.) it also means that in a way some opponent pieces are not free of movement and are tied to maintain these defensive tactics
2/ when you have only one hanging piece, it shouldn't be penalized too strongly, and the penalty should typically be the cost of a tempo (unless the piece is actually trapped and a tempo won't save it, but this would be hard to code in the eval in an efficient way).
3/ when you have several hanging pieces, there is no 100% rule nor even a 90% rule, but there are some significant chances that you'll end up losing one. Of course tactical complications such as forks, checks, passed pawn pushes can allow you to leave hanging pieces, so it's hard to know in the eval whether you're going to lose a piece or not.
4/ when you have many hanging pieces, the chances of being able to defend all of them by means of tactical threats becomes smaller and smaller. Perhaps I should start increasing the hanging piece penalty with the number of hanging pieces ?

Anyway, thoughts, suggestions welcome
Back to top
View user's profile Send private message
Larry Kaufman



Joined: 10 Jan 2010
Posts: 1229
Location: Maryland USA

PostPosted: Sun Feb 26, 2012 3:57 pm    Post subject: Re: evaluate loose pieces Reply to topic Reply with quote

A bonus for attacks on loose pieces (or up-attacks) is quite standard. I introduced it in Rybka, it was duplicated in Ippolit, and of course is in Komodo. Since the Ippolit code is open-source, there is nothing secret about how this was done.
Back to top
View user's profile Send private message Visit poster's website
Lucas Braesch



Joined: 31 May 2010
Posts: 1732

PostPosted: Sun Feb 26, 2012 4:11 pm    Post subject: Re: evaluate loose pieces Reply to topic Reply with quote

lkaufman wrote:
A bonus for attacks on loose pieces (or up-attacks) is quite standard. I introduced it in Rybka, it was duplicated in Ippolit, and of course is in Komodo. Since the Ippolit code is open-source, there is nothing secret about how this was done.

Yes, of course I can have a look at IvanHoe's source code, and many other source codes. But I want to build my own stuff from my own understanding rather than copy... Anyway, I'll have a look at how IvanHoe does it and Stockfish too, just to see if there are some ideas (not code) I can use there.
Back to top
View user's profile Send private message
Miguel A. Ballicora



Joined: 09 Mar 2006
Posts: 4428
Location: Chicago, Illinois, USA

PostPosted: Sun Feb 26, 2012 5:11 pm    Post subject: Re: evaluate loose pieces Reply to topic Reply with quote

lkaufman wrote:
A bonus for attacks on loose pieces (or up-attacks) is quite standard. I introduced it in Rybka, it was duplicated in Ippolit, and of course is in Komodo. Since the Ippolit code is open-source, there is nothing secret about how this was done.


And it has been in Gaviota for at least 10 years, which makes me think that it must be in many other engines, long before all those.

Miguel
EDIT: Should not this be widespread?
_________________
http://sites.google.com/site/gaviotachessengine/
Back to top
View user's profile Send private message Visit poster's website
Larry Kaufman



Joined: 10 Jan 2010
Posts: 1229
Location: Maryland USA

PostPosted: Sun Feb 26, 2012 5:20 pm    Post subject: Re: evaluate loose pieces Reply to topic Reply with quote

I think you are right. I have a vague recollection that it was in some of the engines of around 1990, perhaps in RexChess and/or in various Fidelity machines and others of that time. But perhaps it was just for pieces attacked by the last-moved piece, I don't remember this detail.
Back to top
View user's profile Send private message Visit poster's website
Eelco de Groot



Joined: 12 Mar 2006
Posts: 2591
Location: Groningen

PostPosted: Sun Feb 26, 2012 5:57 pm    Post subject: Re: evaluate loose pieces Reply to topic Reply with quote

lucasart wrote:
lkaufman wrote:
A bonus for attacks on loose pieces (or up-attacks) is quite standard. I introduced it in Rybka, it was duplicated in Ippolit, and of course is in Komodo. Since the Ippolit code is open-source, there is nothing secret about how this was done.

Yes, of course I can have a look at IvanHoe's source code, and many other source codes. But I want to build my own stuff from my own understanding rather than copy... Anyway, I'll have a look at how IvanHoe does it and Stockfish too, just to see if there are some ideas (not code) I can use there.


The surprising thing about Stockfish way of implementing is that at least I could not find code that takes into account undefended ("loose") pieces in general for evaluating attacks from the opponent, only a defence by one's own pawns. I think I introduced including defences by other pieces (which is all already existing bitboardcode in Stockfish, but it just was not used for evaluating attacks) to Rainbow Serpent and other clones of Stockfish then, just like Larry did in Rybka Smile but it is not much tested. Maybe it is only not in Stockfish because it did not bring much elo, I don't know.

Evaluating attacked pieces in general was not in Fruit or Toga, which being non bitboard programs is not such a surprise. But also not in Glaurung after that moved to bitboards and I also can't remember hearing Bob Hyatt talk about this so it probably is not yet in Crafty? So from that point of view it is also maybe not such a surprise Vas had not heard of it yet, and the introduction in Stockfish by the Stockfish team came indeed after the code from Ippolit went public. That is the other side of the medal, if I just want to talk about Stockfish attack code.

I have experimented also, in one Ancalagon I think it was, with increased bonuses if the attacked piece does not have the move (sente/gote code) but I was not enthusiastic in the end about what probably amounts to search instabilities caused by this. Also have experimented with more than just additive bonuses in Stockfish if more than just one piece is attacked, like you are suggesting in your other post Lucas, but the way it is implemented in Stockfish makes it a bit hard (or more expensive) to count attacks for instance, it does not count separate attacks from a type of piece on another type of piece, just registers if the second type is attacked, not how many times it is attacked. This code I also abandoned, it was also too messy I think. Also experiments with X-Ray attacks are possible, to include pins but in a 32 bit environment the needed popcounts are a bit expensive. The X-ray/pin detection code is still lying around somewhere in old archived code but not in use in Rainbow Serpent now.

Regards, Eelco
_________________
Debugging is twice as hard as writing the code in the first
place. Therefore, if you write the code as cleverly as possible, you
are, by definition, not smart enough to debug it.
-- Brian W. Kernighan
Back to top
View user's profile Send private message
Sam Hamilton



Joined: 23 Jun 2006
Posts: 1095

PostPosted: Sun Feb 26, 2012 6:50 pm    Post subject: Re: evaluate loose pieces Reply to topic Reply with quote

lkaufman wrote:
I think you are right. I have a vague recollection that it was in some of the engines of around 1990, perhaps in RexChess and/or in various Fidelity machines and others of that time. But perhaps it was just for pieces attacked by the last-moved piece, I don't remember this detail.


Yes, and I did it in my first engine Pawniac, I think that was either 1989 or 1990. Basically, like many things, the idea that "attacking loose pieces is good" is a pretty intuitive concept, and it seems silly to try to identify an origination of it, though the specific conditions and weights are always interesting.

-Sam
Back to top
View user's profile Send private message
Michael Hoffmann



Joined: 15 Dec 2008
Posts: 525

PostPosted: Sun Feb 26, 2012 6:53 pm    Post subject: Re: evaluate loose pieces Reply to topic Reply with quote

Hello everyone,

just to give my 2 cents on that topic, i want to give an idea i used
a while back (and maybe i do it in future again).

_Similar_ to king safty approach (like fruit uses), hanging pieces
can be counted and weighted. This works pretty fast because
mobility(attacks) have to be simply masked to get attackers on that square,
so the attackcounter is incremented and a weight counter will
be summed up too. Finally you can compute from these 2 values a
score, just like many of you do with king safty, the same technique.

So the overhead is minimal, it is fine to tune and easy to implement.
The tradeoff between accuracy and speed is of course a matter of
taste, but it is just another way to handle hanging pieces, and _can_
be used as good evaluation heuristic.

maybe someone wants to try it out for himself Smile

Michael
Back to top
View user's profile Send private message
Marco Costalba



Joined: 14 Jun 2008
Posts: 2090

PostPosted: Sun Feb 26, 2012 7:04 pm    Post subject: Re: evaluate loose pieces Reply to topic Reply with quote

Here is the code in SF:

Code:

  // evaluate_threats<>() assigns bonuses according to the type of attacking piece
  // and the type of attacked one.

  template<Color Us>
  Score evaluate_threats(const Position& pos, EvalInfo& ei) {

    const Color Them = (Us == WHITE ? BLACK : WHITE);

    Bitboard b;
    Score score = SCORE_ZERO;

    // Enemy pieces not defended by a pawn and under our attack
    Bitboard weakEnemies =  pos.pieces(Them)
                          & ~ei.attackedBy[Them][PAWN]
                          & ei.attackedBy[Us][0];
    if (!weakEnemies)
        return SCORE_ZERO;

    // Add bonus according to type of attacked enemy piece and to the
    // type of attacking piece, from knights to queens. Kings are not
    // considered because are already handled in king evaluation.
    for (PieceType pt1 = KNIGHT; pt1 < KING; pt1++)
    {
        b = ei.attackedBy[Us][pt1] & weakEnemies;
        if (b)
            for (PieceType pt2 = PAWN; pt2 < KING; pt2++)
                if (b & pos.pieces(pt2))
                    score += ThreatBonus[pt1][pt2];
    }
    return score;
  }


If I have understood correctly the idea of Lucas, it could be implemented changing weakEnemies definition to:
Code:


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

// Add enemy non-pawns attacked by our pawns, even if defended by a pawn
weakEnemies |= (pos.pieces(Them) ^ pos.pieces(PAWN, Them)) & ei.attackedBy[Us][PAWN];



But it seems to be redundant with this piece of code in evaluate_piecs() that already does the same thing.

Code:

        // Decrease score if we are attacked by an enemy pawn. Remaining part
        // of threat evaluation must be done later when we have full attack info.
        if (ei.attackedBy[Them][PAWN] & s)
            score -= ThreatenedByPawnPenalty[Piece];
Back to top
View user's profile Send private message
Sam Hamilton



Joined: 23 Jun 2006
Posts: 1095

PostPosted: Sun Feb 26, 2012 7:12 pm    Post subject: Re: evaluate loose pieces Reply to topic Reply with quote

Eelco de Groot wrote:


The surprising thing about Stockfish way of implementing is that at least I could not find code that takes into account undefended ("loose") pieces in general for evaluating attacks from the opponent, only a defence by one's own pawns. I think I introduced including defences by other pieces (which is all already existing bitboardcode in Stockfish, but it just was not used for evaluating attacks) to Rainbow Serpent and other clones of Stockfish then, just like Larry did in Rybka Smile but it is not much tested. Maybe it is only not in Stockfish because it did not bring much elo, I don't know.

...

I have experimented also, in one Ancalagon I think it was, with increased bonuses if the attacked piece does not have the move (sente/gote code) but I was not enthusiastic in the end about what probably amounts to search instabilities caused by this. Also have experimented with more than just additive bonuses in Stockfish if more than just one piece is attacked, like you are suggesting in your other post Lucas, but the way it is implemented in Stockfish makes it a bit hard (or more expensive) to count attacks for instance, it does not count separate attacks from a type of piece on another type of piece, just registers if the second type is attacked, not how many times it is attacked. This code I also abandoned, it was also too messy I think. Also experiments with X-Ray attacks are possible, to include pins but in a 32 bit environment the needed popcounts are a bit expensive. The X-ray/pin detection code is still lying around somewhere in old archived code but not in use in Rainbow Serpent now.

Regards, Eelco


Yes, the Stockfish code is not intuitive to me. Edsel had something vaguely similar in Hannibal, and I did a lot of the same experiments you did without finding a good improvement. Basically my conclusion was that Stockfish has a good marriage between speed of calculation, and help to the search (in my opinion these bonuses in eval have a primary contribution of molding the search space). It was a good learning experience for me as it helped me improve some other weird eval functions I had been playing with using a similar "inexact but not too slow" style.

-Sam
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic       TalkChess.com Forum Index -> Computer Chess Club: Programming and Technical Discussions All times are GMT
Goto page 1, 2, 3  Next
Threaded
Page 1 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum




Powered by phpBB © 2001, 2005 phpBB Group
Enhanced with Moby Threads