Score "no pawns" question

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

ianm
Posts: 15
Joined: Wed Apr 29, 2020 1:58 pm
Location: Tasmania, Australia
Full name: Ian Mitchell

Score "no pawns" question

Post by ianm »

Hi Guys

My simple evaluation function doesn’t have any kind of scoring for material draw. Is it worth having a score for positions with no pawns (which is easy to include)? Would it compensate for a lack of scoring a material draw? If so, what is a reasonable value? ATM, I have -50 (where 100 is the pawn value).

Cheers, Ian
Ras
Posts: 2487
Joined: Tue Aug 30, 2016 8:19 pm
Full name: Rasmus Althoff

Re: Score "no pawns" question

Post by Ras »

ianm wrote: Wed May 13, 2020 6:48 amMy simple evaluation function doesn’t have any kind of scoring for material draw.
You should add the most common configurations, it's pretty easy. There are quite some endgame positions where the defending side can hold the draw by sacrificing a minor piece for one or two pawns so that the stronger side ends up with KN:K or KB:K. The associated search tree can be aborted in this case.

One implementation detail is that KN:KP, KN:KPP, KB:KP and KB:KPP should be corrected to a slightly positive score for the side with the pawns, and the search tree must not be aborted because search has to show whether a pawn promotion is possible.
Would it compensate for a lack of scoring a material draw?
I don't think so because a minor piece is around 3 pawns, and you can't subtract that much for having no pawns.
Rasmus Althoff
https://www.ct800.net
ianm
Posts: 15
Joined: Wed Apr 29, 2020 1:58 pm
Location: Tasmania, Australia
Full name: Ian Mitchell

Re: Score "no pawns" question

Post by ianm »

OK, thanks Ras. Here is code (that is only called when there are no pawns) from Vice that checks if a draw is likely with the remaining pieces. I was hoping for something a bit simpler!

Code: Select all

// sjeng 11.2
//8/6R1/2k5/6P1/8/8/4nP2/6K1 w - - 1 41 
int MaterialDraw(const S_BOARD *pos) {

    ASSERT(CheckBoard(pos));
	
    if (!pos->pceNum[wR] && !pos->pceNum[bR] && !pos->pceNum[wQ] && !pos->pceNum[bQ]) {
	  if (!pos->pceNum[bB] && !pos->pceNum[wB]) {
	      if (pos->pceNum[wN] < 3 && pos->pceNum[bN] < 3) {  return TRUE; }
	  } else if (!pos->pceNum[wN] && !pos->pceNum[bN]) {
	     if (abs(pos->pceNum[wB] - pos->pceNum[bB]) < 2) { return TRUE; }
	  } else if ((pos->pceNum[wN] < 3 && !pos->pceNum[wB]) || (pos->pceNum[wB] == 1 && !pos->pceNum[wN])) {
	    if ((pos->pceNum[bN] < 3 && !pos->pceNum[bB]) || (pos->pceNum[bB] == 1 && !pos->pceNum[bN]))  { return TRUE; }
	  }
	} else if (!pos->pceNum[wQ] && !pos->pceNum[bQ]) {
        if (pos->pceNum[wR] == 1 && pos->pceNum[bR] == 1) {
            if ((pos->pceNum[wN] + pos->pceNum[wB]) < 2 && (pos->pceNum[bN] + pos->pceNum[bB]) < 2)	{ return TRUE; }
        } else if (pos->pceNum[wR] == 1 && !pos->pceNum[bR]) {
            if ((pos->pceNum[wN] + pos->pceNum[wB] == 0) && (((pos->pceNum[bN] + pos->pceNum[bB]) == 1) || ((pos->pceNum[bN] + pos->pceNum[bB]) == 2))) { return TRUE; }
        } else if (pos->pceNum[bR] == 1 && !pos->pceNum[wR]) {
            if ((pos->pceNum[bN] + pos->pceNum[bB] == 0) && (((pos->pceNum[wN] + pos->pceNum[wB]) == 1) || ((pos->pceNum[wN] + pos->pceNum[wB]) == 2))) { return TRUE; }
        }
    }
  return FALSE;
}
User avatar
hgm
Posts: 27796
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Score "no pawns" question

Post by hgm »

Using an additive penalty for this is no good. You will either grossly overestimate KBK or KPP(P)KB. For one, only the side that is ahead suffers from having no Pawns; if your aim is to defend the draw you don't care much whether you have mating potential yourself.

The better method is to apply a mutiplier < 1 to the 'naive' evaluation score when the side ahead as no Pawns, or a single Pawn in jeopardy. Even for won end-games dividing the score by 2 is justified if the leading side has no pawns. (Unless it is an elementary mate against a bare King; no need to reduce the score for those.) For known draws such as KBK, KNK and KNNK a factor 0 of course is more fitting, even when the defending side has one or more Pawns. (But beware of KNNKP; that can sometimes still be won.) The rule of thumb is that being a minor (or exchange) ahead is in general not enough to forces a win when you have no Pawns. So KQBKQ*, KRBKR*, KBNKN*, KRKN* and such (where * means one or more Pawns) can all be multiplied by, say, 0.125 (when ahead), so that even when there is no compensation for the minor the advantage is still reduced to below half a Pawn.

If the leading side has only a single Pawn and the defender has at least one piece, you should judge the position after the defender sacs his weakest piece for the Pawn. If that would give one of the material compositions discussmentioned above, you should also discount, but less severe (say by 0.5 instead of 0.125, and by 0.25 instead of 0). If KBNPKNN gets discounted by 0.5 (so you have +50cP instead of +100cP), and (after sac) KBNKN gets discounted by 0.125 (so you have +40cP instead of +320cP), you still have a higher score before the sac, so that the leading side will try to protect his Pawn rather than 'gaining' a Knight with it.
Karlo Bala
Posts: 373
Joined: Wed Mar 22, 2006 10:17 am
Location: Novi Sad, Serbia
Full name: Karlo Balla

Re: Score "no pawns" question

Post by Karlo Bala »

ianm wrote: Wed May 13, 2020 9:56 am OK, thanks Ras. Here is code (that is only called when there are no pawns) from Vice that checks if a draw is likely with the remaining pieces. I was hoping for something a bit simpler!

Code: Select all

// sjeng 11.2
//8/6R1/2k5/6P1/8/8/4nP2/6K1 w - - 1 41 
int MaterialDraw(const S_BOARD *pos) {

    ASSERT(CheckBoard(pos));
	
    if (!pos->pceNum[wR] && !pos->pceNum[bR] && !pos->pceNum[wQ] && !pos->pceNum[bQ]) {
	  if (!pos->pceNum[bB] && !pos->pceNum[wB]) {
	      if (pos->pceNum[wN] < 3 && pos->pceNum[bN] < 3) {  return TRUE; }
	  } else if (!pos->pceNum[wN] && !pos->pceNum[bN]) {
	     if (abs(pos->pceNum[wB] - pos->pceNum[bB]) < 2) { return TRUE; }
	  } else if ((pos->pceNum[wN] < 3 && !pos->pceNum[wB]) || (pos->pceNum[wB] == 1 && !pos->pceNum[wN])) {
	    if ((pos->pceNum[bN] < 3 && !pos->pceNum[bB]) || (pos->pceNum[bB] == 1 && !pos->pceNum[bN]))  { return TRUE; }
	  }
	} else if (!pos->pceNum[wQ] && !pos->pceNum[bQ]) {
        if (pos->pceNum[wR] == 1 && pos->pceNum[bR] == 1) {
            if ((pos->pceNum[wN] + pos->pceNum[wB]) < 2 && (pos->pceNum[bN] + pos->pceNum[bB]) < 2)	{ return TRUE; }
        } else if (pos->pceNum[wR] == 1 && !pos->pceNum[bR]) {
            if ((pos->pceNum[wN] + pos->pceNum[wB] == 0) && (((pos->pceNum[bN] + pos->pceNum[bB]) == 1) || ((pos->pceNum[bN] + pos->pceNum[bB]) == 2))) { return TRUE; }
        } else if (pos->pceNum[bR] == 1 && !pos->pceNum[wR]) {
            if ((pos->pceNum[bN] + pos->pceNum[bB] == 0) && (((pos->pceNum[wN] + pos->pceNum[wB]) == 1) || ((pos->pceNum[wN] + pos->pceNum[wB]) == 2))) { return TRUE; }
        }
    }
  return FALSE;
}
Look at the old Fruit code, a very elegant solution.
Best Regards,
Karlo Balla Jr.
ianm
Posts: 15
Joined: Wed Apr 29, 2020 1:58 pm
Location: Tasmania, Australia
Full name: Ian Mitchell

Re: Score "no pawns" question

Post by ianm »

Thanks HG, I'm going to try multiplying the score by 0.5 when there are no pawns and see how it goes.

Cheers, Ian
mjlef
Posts: 1494
Joined: Thu Mar 30, 2006 2:08 pm

Re: Score "no pawns" question

Post by mjlef »

ianm wrote: Thu May 14, 2020 11:29 am Thanks HG, I'm going to try multiplying the score by 0.5 when there are no pawns and see how it goes.

Cheers, Ian
The general rule is it the side that is ahead in material, but has has no pawns, then it needs to have 4 pawn units more to win. So things like RR vs NN are mostly wins, but RB vs NN are draws. There are many exceptions, but that is a good general rule.
User avatar
hgm
Posts: 27796
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Score "no pawns" question

Post by hgm »

Indeed, that is the "minor ahead (i.e. +3) is not enough" rule. In that case a factor 0.5 is not nearly enough, it will almost always be a dead draw. The factor 0.5 is good for cases like KRRKNNP, where you have a good winning chance, but where it is much more difficult than when you would be 2 Pawns ahead with equal piece material. For the minor-ahead case it would be better to apply a factor 0.125; that would still put you at +0.40 in KBK (which is already very generous for a dead draw). With 0.5 you would still be at +1.6 in KBK or +1.1 in KBKP, and prefer those over KBPPKNP (and thus trading your 2P for N when you get the chance, or allowing the Knight to trade itself this way).