home /
fornax-v3-0 /
src /
eval /
eval_pawn_structure.inc.h
eval_pawn_structure.inc.h
//
// eval_pawn_structure.h
// fornax3
//
// Created by Anders on 26/04/2020.
//
#ifndef eval_pawn_structure_h
#define eval_pawn_structure_h
#include "../bits.h"
#include "eval_defs.h"
#include "eval_debug_print.hpp"
template<direction dir>
static inline bits64 pawn_span(bits64 pawns) {
return bits_fill<dir>(bits_shift<dir>(pawns));
}
static inline bits64 pawn_file_fill(bits64 pawns) {
return bits_fill<S>(pawns) | bits_fill<N>(pawns);
}
template<color col>
static inline bits64 backward_pawns(bits64 pawns, bits64 opposingpawns) {
constexpr direction spandir = col ? S : N;
constexpr direction shiftE = col ? NE : SE;
constexpr direction shiftW = col ? NW : SW;
constexpr direction shift = col ? N : S;
bits64 stops = bits_shift<spandir>(pawns);
bits64 attack_spans = pawn_span<spandir>(bits_shift_guarded<W>(stops)) | pawn_span<spandir>(bits_shift_guarded<E>(stops));
bits64 opposing_attacks = bits_shift_guarded<shiftE>(opposingpawns) | bits_shift_guarded<shiftW>(opposingpawns);
return bits_shift<shift>(stops & opposing_attacks & ~attack_spans);
}
template<color col>
static inline bits64 passed_pawns(bits64 pawns, bits64 opposingpawns) {
constexpr direction spandir = col ? N : S;
bits64 opposing = pawn_span<spandir>(opposingpawns);
opposing |= bits_shift_guarded<E>(opposing) | bits_shift_guarded<W>(opposing);
return pawns & ~opposing;
}
static inline bits64 doubled_pawns(bits64 pawns) {
return (pawn_span<N>(pawns) | pawn_span<S>(pawns)) & pawns;
}
static inline bits64 isolated_pawns(bits64 pawns) {
bits64 filefill = pawn_file_fill(pawns);
return (pawns & ~bits_shift_guarded<E>(filefill)) & (pawns & ~bits_shift_guarded<W>(filefill));
}
template<bool debug>
static constexpr void eval_pawn_structure(eval* mg, eval* eg, const Board* board) {
bits64 white = board->side[WHITE].pieces[PAWN];
bits64 black = board->side[BLACK].pieces[PAWN];
eval mg_tot = 0;
eval eg_tot = 0;
bits64 white_pawn_attacks = board->side[WHITE].attackkmaps[1].bits | board->side[WHITE].attackkmaps[2].bits;
bits64 black_pawn_attacks = board->side[BLACK].attackkmaps[1].bits | board->side[BLACK].attackkmaps[2].bits;
bits64 white_protected= board->side[WHITE].pieces[PAWN] & white_pawn_attacks;
bits64 black_protected = board->side[BLACK].pieces[PAWN] & black_pawn_attacks;
eval protected_diff = ED_ADD_WHITE("protected", BITS_COUNT(white_protected)) - ED_ADD_BLACK("protected", BITS_COUNT(black_protected));
mg_tot += ED_ADD_DIFF_MG("protected", protected_diff * 2);
eg_tot += ED_ADD_DIFF_EG("protected", protected_diff * 2);
bits64 white_passers = passed_pawns<WHITE>(white, black);
bits64 black_passers = passed_pawns<BLACK>(black, white);
eval whitepassers = BITS_COUNT(white_passers) + BITS_COUNT(white_passers & white_protected);
eval blackpassers = BITS_COUNT(black_passers) + BITS_COUNT(black_passers & black_protected);
eval passerdiff = ED_ADD_WHITE("passers", whitepassers) - ED_ADD_BLACK("passers", blackpassers);
mg_tot += ED_ADD_DIFF_MG("passers", passerdiff * 12);
eg_tot += ED_ADD_DIFF_EG("passers", passerdiff * 16);
eval whitedoubles = -BITS_COUNT(doubled_pawns(white));
eval blackdoubles = -BITS_COUNT(doubled_pawns(black));
eval doublediff = ED_ADD_WHITE("doubled", whitedoubles) - ED_ADD_BLACK("doubled", blackdoubles);
mg_tot += ED_ADD_DIFF_MG("doubled", doublediff * 8);
eg_tot += ED_ADD_DIFF_EG("doubled", doublediff * 8);
eval whitebackward = -BITS_COUNT(backward_pawns<WHITE>(white, black));
eval blackbackward = -BITS_COUNT(backward_pawns<BLACK>(black, white));
eval backwarddiff = ED_ADD_WHITE("backward", whitebackward) - ED_ADD_BLACK("backward", blackbackward);
mg_tot += ED_ADD_DIFF_MG("backward", backwarddiff * 8);
eg_tot += ED_ADD_DIFF_EG("backward", backwarddiff * 12);
eval whiteisolated = -BITS_COUNT(isolated_pawns(white));
eval blackisolated = -BITS_COUNT(isolated_pawns(black));
eval isolateddiff = ED_ADD_WHITE("isolated", whiteisolated) - ED_ADD_BLACK("isolated", blackisolated);
mg_tot += ED_ADD_DIFF_MG("isolated", isolateddiff * 8);
eg_tot += ED_ADD_DIFF_EG("isolated", isolateddiff * 12);
*mg += mg_tot;
*eg += eg_tot;
}
#endif /* eval_pawn_structure_h */