Question regarding static evaluation of pawns

Discussion of chess software programming and technical issues.

Moderators: hgm, Dann Corbit, Harvey Williamson

jfern2011

Question regarding static evaluation of pawns

Post by jfern2011 »

In my chess engine (which I've yet to name) I've decided to make the pawn evaluation such that its accuracy relies heavily on there being no available pawn captures for the position being evaluated. I figured this makes sense because I've got a quiescence search to generate captures, so every time evalPawns() is called, no pawn will be attacking another pawn. Note PxP will always be searched because it is not losing.

However, I recently came to the realization that I may need to apply "delta" pruning within the quiescence, and to do this requires an evaluation of the position to establish a lower bound before continuing the search. Now, not only will evalPawns() be inaccurate, but I've got potentially hanging pieces that too are being evaluated. For you more experienced folks:

1. Do you agree that it is OK to design the pawn evaluation for cases where no pawn captures are available?
2. I don't totally understand delta pruning, but I believe the issue I described is the reason for applying a margin?
3. Are there any other cases where this pawn evaluation approach would not be safe?
User avatar
Don
Posts: 5106
Joined: Tue Apr 29, 2008 4:27 pm

Re: Question regarding static evaluation of pawns

Post by Don »

jfern2011 wrote:In my chess engine (which I've yet to name) I've decided to make the pawn evaluation such that its accuracy relies heavily on there being no available pawn captures for the position being evaluated. I figured this makes sense because I've got a quiescence search to generate captures, so every time evalPawns() is called, no pawn will be attacking another pawn. Note PxP will always be searched because it is not losing.

However, I recently came to the realization that I may need to apply "delta" pruning within the quiescence, and to do this requires an evaluation of the position to establish a lower bound before continuing the search. Now, not only will evalPawns() be inaccurate, but I've got potentially hanging pieces that too are being evaluated. For you more experienced folks:

1. Do you agree that it is OK to design the pawn evaluation for cases where no pawn captures are available?
2. I don't totally understand delta pruning, but I believe the issue I described is the reason for applying a margin?
3. Are there any other cases where this pawn evaluation approach would not be safe?
The quies search is supposed to stop when the position is quiet. So it will be compelled to make the last capture to increase the score unless of course it doesn't need to in order the get the cut-off.

However, I do not want to be dogmatic about this. My best guess is that this would be a big waste of time though.

Note that if a PxP is possible the capturing pawn may become a passed pawn - and yes, you could miss this with capture futility if you need more than a pawn + margin. But capture futility is not an issue because the whole point of futility is to AVOID having to call the evaluator.

Some of the old fashioned programs did a lot of tricks to try to see a bit more in quies, but modern programs keep the quies quite simple. In fact in all the top programs you could easily consider the "low depth" portion of the search part of the "quies" search. It is ridiculously selective already. Don't forget that SEE, which any good program uses, is full of errors too but it's still a huge win.
Capital punishment would be more effective as a preventive measure if it were administered prior to the crime.
jfern2011

Re: Question regarding static evaluation of pawns

Post by jfern2011 »

jfern2011 wrote:However, I recently came to the realization that I may need to apply "delta" pruning within the quiescence, and to do this requires an evaluation of the position to establish a lower bound before continuing the search. Now, not only will evalPawns() be inaccurate, but I've got potentially hanging pieces that too are being evaluated.
I'm sorry, I used the term "delta pruning" incorrectly. What I had in mind was computing a "stand pat" score at the beginning of quiesce(). The problem with this is that you're evaluating a position that is NOT static (there are captures or checks available). How then can you rely on your evaluation function to compute a score that you can compare to the current beta and, if score >= beta, return the score? I feel that this can potentially lead to gross errors. For example, let's say the eval applies a bonus for a rook on an open file, and this is just enough to make the evaluation score exceed beta. As a result, quiesce() returns this score. However, it turns out that this rook is hanging and is under attack, so quiesce() returned a horribly inaccurate score. For some reason however, authors seem to be okay with their program running an evaluation before trying captures. If I decide to do the same, then I probably should modify my code for evaluatePawns() to consider the fact that there will be PxP captures available.

One reason I ask this is for the evaluation of weak pawns. You might say that if a pawn is defended at least as many times as it is attacked then it is not weak. Then I come by and say, "who cares" because when my program evaluates a static position, no pawn will be attacking another pawn (obviously the evaluation of weak pawns is a little more involved, but you get the idea).
User avatar
hgm
Posts: 27701
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Question regarding static evaluation of pawns

Post by hgm »

The assumption inherent in stand-pat is that the one that has the move will be able to use it to his advantage, so the it is a lower limit to the true score. This could indeed be a false assumption when you are under attack, and have to use the move to rescue the situation at the expense of some damage.

The logical way to repair this is to give penalties for such attacks in the static evaluation. Like in your example, you could give points for the existence of an attack on a hanging piece (or a Low x High attack) by the side not to move. In fact the existence of two such attacks could be a reason for extension. (Apparently you are being forked!) The penalty could also be dependent on positional features. E.g. you could revoke (part of) open-line and 7th-rank bonuses for attacked Rooks, or passer bonuses for tradable Pawns.
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: Question regarding static evaluation of pawns

Post by lucasart »

jfern2011 wrote:In my chess engine (which I've yet to name) I've decided to make the pawn evaluation such that its accuracy relies heavily on there being no available pawn captures for the position being evaluated. I figured this makes sense because I've got a quiescence search to generate captures, so every time evalPawns() is called, no pawn will be attacking another pawn. Note PxP will always be searched because it is not losing.

However, I recently came to the realization that I may need to apply "delta" pruning within the quiescence, and to do this requires an evaluation of the position to establish a lower bound before continuing the search. Now, not only will evalPawns() be inaccurate, but I've got potentially hanging pieces that too are being evaluated. For you more experienced folks:

1. Do you agree that it is OK to design the pawn evaluation for cases where no pawn captures are available?
2. I don't totally understand delta pruning, but I believe the issue I described is the reason for applying a margin?
3. Are there any other cases where this pawn evaluation approach would not be safe?
- The qsearch ensures that you never stand pat in a position where you have a capture that can improve your position. So you should write your eval not caring about possible captures.
- HOWEVER: you can perfectly stand pat having 3 pieces hanging, because it's your turn to play... Reversly, the opponent can have lots of loose pieces that can't be taken because of some threats in the position, but these threats will be hard to maintain, and deeper searches will break his position. That's why it's best to have a solid position in chess (where pieces and pawns are defending each other, rather than relying on complex and volatile threats). All humans know that.

So, what I do is:
1/ write the eval as if I didn't care about captures
2/ write an additional eval component that penalizes loose pieces and pawns that are attacked.

I was amazed at the elo gain I got from 2/. My implementation is very simple, and can certainly be improved:
https://github.com/lucasart/chess/commi ... e1f881e8f0
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
User avatar
Don
Posts: 5106
Joined: Tue Apr 29, 2008 4:27 pm

Re: Question regarding static evaluation of pawns

Post by Don »

hgm wrote:The assumption inherent in stand-pat is that the one that has the move will be able to use it to his advantage, so the it is a lower limit to the true score. This could indeed be a false assumption when you are under attack, and have to use the move to rescue the situation at the expense of some damage.

The logical way to repair this is to give penalties for such attacks in the static evaluation. Like in your example, you could give points for the existence of an attack on a hanging piece (or a Low x High attack) by the side not to move. In fact the existence of two such attacks could be a reason for extension. (Apparently you are being forked!) The penalty could also be dependent on positional features. E.g. you could revoke (part of) open-line and 7th-rank bonuses for attacked Rooks, or passer bonuses for tradable Pawns.
Komodo does give a small penalty if a piece is up-attacked by a pawn or knight. Those are trivial to test with bit operations and no see() is required - and more importantly it did add a little bit of ELO.

The penalty is symmetrically applied to both colors.
Capital punishment would be more effective as a preventive measure if it were administered prior to the crime.
mar
Posts: 2552
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: Question regarding static evaluation of pawns

Post by mar »

lucasart wrote: So, what I do is:
1/ write the eval as if I didn't care about captures
2/ write an additional eval component that penalizes loose pieces and pawns that are attacked.

I was amazed at the elo gain I got from 2/. My implementation is very simple, and can certainly be improved:
https://github.com/lucasart/chess/commi ... e1f881e8f0
Are you sure it does what was intended?
I think it penalizes when king is in check too (unless your material value for king is zero).
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: Question regarding static evaluation of pawns

Post by lucasart »

mar wrote:
lucasart wrote: So, what I do is:
1/ write the eval as if I didn't care about captures
2/ write an additional eval component that penalizes loose pieces and pawns that are attacked.

I was amazed at the elo gain I got from 2/. My implementation is very simple, and can certainly be improved:
https://github.com/lucasart/chess/commi ... e1f881e8f0
Are you sure it does what was intended?
I think it penalizes when king is in check too (unless your material value for king is zero).
Yes. I *never* call the eval when in check:

Code: Select all

int eval(const Board& B)
{
	assert(!B.is_check());
	...
}
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: Question regarding static evaluation of pawns

Post by bob »

jfern2011 wrote:In my chess engine (which I've yet to name) I've decided to make the pawn evaluation such that its accuracy relies heavily on there being no available pawn captures for the position being evaluated. I figured this makes sense because I've got a quiescence search to generate captures, so every time evalPawns() is called, no pawn will be attacking another pawn. Note PxP will always be searched because it is not losing.

However, I recently came to the realization that I may need to apply "delta" pruning within the quiescence, and to do this requires an evaluation of the position to establish a lower bound before continuing the search. Now, not only will evalPawns() be inaccurate, but I've got potentially hanging pieces that too are being evaluated. For you more experienced folks:

1. Do you agree that it is OK to design the pawn evaluation for cases where no pawn captures are available?
2. I don't totally understand delta pruning, but I believe the issue I described is the reason for applying a margin?
3. Are there any other cases where this pawn evaluation approach would not be safe?
1. No. In the q-search, one must ALWAYS be able to stand pat. If you force that side to play a capture, then you are not finding the best move/path, because most of the time in chess, the best move is NOT a capture.

2. I hate the name, but the basic idea is this. If your current alpha/beta window is at something like (0, 0.25) and your current material score (or minimal eval score) is something like -5.0, then looking at PxP is futile, as it only gains 1.0 and still leaves you WAY below alpha...

3. Almost all cases are unsafe using your idea. You HAVE to have the stand pat option or your q-search is going to return bogus scores.
jfern2011

Re: Question regarding static evaluation of pawns

Post by jfern2011 »

Thanks everyone for your input! :D