quad()
in Fruit |

for (rank = 0; rank < RankNb; rank++) Bonus[rank] = 0; |

In Fruit, there are several bonuses for a passed pawn. The endgame score has a fixed minimum, and all the bonuses for the pawn simply increase the maximum. This is equivalent to adding a set endgame bonus with

Endgame passed pawn evaluation in Fruit | Simplified version |

min = PassedEndgameMin; |
eg[att] += quad(PassedEndgameMin,PassedEndgameMax,rank); |

Fruit | Rybka |

op[att] += quad(PassedOpeningMin,PassedOpeningMax,rank); |
opening += PassedOpening[rank]; |

Fruit | Rybka |

min = PassedEndgameMin; |
endgame += PassedEndgame[rank]; |

The unstoppable passer is simply a passer that isn't blocked by a friendly piece and the opponent king is outside its "square". The king passer is a passer on the 6th or 7th rank which the king defends while simultaneously defending the promotion square. These defintions are exact bitboard equivalents in Rybka, and they both receive the same bonus of

Next is the free pawn. The opponent has pieces in this case to potentially keep our pawn from promoting, so we need to check if it can escape. In Fruit, the square in front of the pawn must be empty, and the pawn must be able to advance safely there. We use the static exchange evaluation (SEE) to make sure that even if the square is attacked by the opponent, we can recapture on the square. This check is only done on the square directly in front of the pawn in Fruit, but since Rybka is bitboard based, we can quickly do the same calculation for all squares in front of the pawn up to the promotion square. To do this we make an approximation of the SEE that is usually equivalent. We simply make sure that for every square in the promotion path that is attacked by the opponent, we also have a piece defending that square. There are some cases where this might not be the same as being able to advance safely (according to SEE), but they are rather unusual (two knights attacking, one queen defending).

There is also one more slight difference here: in Fruit, to be a free passer, all of the above conditions must apply. In Rybka, we break the conditions down and award partial bonuses if only some of the conditions are met.

Fruit | Rybka |

if (board->piece_size[def] <= 1 |
if ((Board.pieces[BQ] | Board.pieces[BR] | |

Fruit | Rybka |

delta -= pawn_att_dist(sq,KING_POS(board,att),att) * AttackerDistance; |
endgame -= pawn_att_dist(square,wking_square,White) * PassedAttDistance[rank]; |

Also, note that in the Rybka code, the equivalent rank 8 value of the Bonus array is 256 (like rank 7) instead of 0 as in Fruit. This difference is completely meaningless however, since there can never be a pawn on the 8th rank.

Rybka | Fruit Equivalent |

int PassedOpening[8] = { 0, 0, 0, 489, 1450, 2900, 4821, 4821 }; |
int PassedOpeningMin = 0; |

We also need to take a look at the candidate bonus. This bonus is done statically and stored in the pawn hash table, as discussed here, but we haven't looked at the values yet. We see that in Fruit candidates are scored using the same

Rybka | Fruit Equivalent |

int CandidateOpening[8] = { 0, 0, 0, 382, 1131, 2263, 3763, 3763 }; |
int CandidateOpeningMin = 0; |