- // Evaluate pawn storms?
- const bool EvaluatePawnStorms = true;
-
- // Pawn storm tables for positions with opposite castling:
- const int QStormTable[64] = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- -22,-22,-22,-13,-4, 0, 0, 0,
- -4, -9, -9, -9,-4, 0, 0, 0,
- 9, 18, 22, 18, 9, 0, 0, 0,
- 22, 31, 31, 22, 0, 0, 0, 0,
- 31, 40, 40, 31, 0, 0, 0, 0,
- 31, 40, 40, 31, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
- };
-
- const int KStormTable[64] = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,-4,-13,-22,-27,-27,
- 0, 0, 0,-4, -9,-13,-18,-18,
- 0, 0, 0, 0, 9, 9, 9, 9,
- 0, 0, 0, 0, 9, 18, 27, 27,
- 0, 0, 0, 0, 9, 27, 40, 36,
- 0, 0, 0, 0, 0, 31, 40, 31,
- 0, 0, 0, 0, 0, 0, 0, 0
- };
+ // Loop through all pawns of the current color and score each pawn
+ while ((s = *pl++) != SQ_NONE)
+ {
+ assert(pos.piece_on(s) == make_piece(Us, PAWN));
+
+ File f = file_of(s);
+
+ e->semiopenFiles[Us] &= ~(1 << f);
+ e->pawnAttacksSpan[Us] |= pawn_attack_span(Us, s);
+
+ // Flag the pawn
+ opposed = theirPawns & forward_file_bb(Us, s);
+ stoppers = theirPawns & passed_pawn_mask(Us, s);
+ lever = theirPawns & PawnAttacks[Us][s];
+ leverPush = theirPawns & PawnAttacks[Us][s + Up];
+ doubled = ourPawns & (s - Up);
+ neighbours = ourPawns & adjacent_files_bb(f);
+ phalanx = neighbours & rank_bb(s);
+ supported = neighbours & rank_bb(s - Up);
+
+ // A pawn is backward when it is behind all pawns of the same color
+ // on the adjacent files and cannot be safely advanced.
+ backward = !(ourPawns & pawn_attack_span(Them, s + Up))
+ && (stoppers & (leverPush | (s + Up)));
+
+ // Passed pawns will be properly scored in evaluation because we need
+ // full attack info to evaluate them. Include also not passed pawns
+ // which could become passed after one or two pawn pushes when are
+ // not attacked more times than defended.
+ if ( !(stoppers ^ lever ^ leverPush)
+ && !(ourPawns & forward_file_bb(Us, s))
+ && popcount(supported) >= popcount(lever) - 1
+ && popcount(phalanx) >= popcount(leverPush))
+ e->passedPawns[Us] |= s;
+
+ else if ( stoppers == SquareBB[s + Up]
+ && relative_rank(Us, s) >= RANK_5)
+ {
+ b = shift<Up>(supported) & ~theirPawns;
+ while (b)
+ if (!more_than_one(theirPawns & PawnAttacks[Us][pop_lsb(&b)]))
+ e->passedPawns[Us] |= s;
+ }