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 */