home / fornax / fornax-v4-0 / src / moving / derived_knowledge.cpp

derived_knowledge.cpp



//
// Created by Anders on 09/08/2022.
//

#include "derived_knowledge.h"
#include "movegen.hpp"
#include "../bits.h"

template<color col>
static constexpr bits64 piece_mask(const Board* board) {
  const bits64* pieces = board->side[col].pieces;
  return pieces[KING] | pieces[QUEEN] | pieces[ROOK] | pieces[BISHOP] | pieces[KNIGHT] | pieces[PAWN];
}

template <piecetype type, color active>
static constexpr void populate_attack_maps(bits64* mask, Attackmap** cursor, bits64 pieces, bits64 occupants) {
  while (pieces) {
    square sq = bits_pop_trailing(&pieces);
    bits64 bits = movegen_get_attacks<type>(sq, occupants);
    *mask |= bits;
    *(*cursor)++ = {type, bits};
  }
}

template<color col>
static void populate_attacks(Board* board) {
  constexpr color opp = COLOR_OPPOSITE(col);
  Side* col_side = &board->side[col];
  Side* opp_side = &board->side[opp];
  bits64 occupants = (col_side->piecemask | opp_side->piecemask) ^ opp_side->pieces[KING];
  Attackmap* cursor = col_side->attackkmaps;

  bits64* pieces = col_side->pieces;

  bits64 up =  bits_shift<col ? S : N>(pieces[PAWN]);
  bits64 east = (bits_shift_guarded<W>(up));
  bits64 west = (bits_shift_guarded<E>(up));
  col_side->attackmask = east | west;

  *cursor++ = {PAWN, east};
  *cursor++ = {PAWN, west};
  col_side->attackmask_levels[PAWN] = 0;
  col_side->attackmask_levels[KNIGHT] = col_side->attackmask;
  col_side->attackmask_levels[BISHOP] = col_side->attackmask;
  populate_attack_maps<BISHOP, col>(&col_side->attackmask, &cursor, pieces[BISHOP], occupants);
  populate_attack_maps<KNIGHT, col>(&col_side->attackmask, &cursor, pieces[KNIGHT], occupants);
  col_side->attackmask_levels[ROOK] = col_side->attackmask;
  populate_attack_maps<ROOK, col>(&col_side->attackmask, &cursor, pieces[ROOK], occupants);
  col_side->attackmask_levels[QUEEN] = col_side->attackmask;
  populate_attack_maps<QUEEN, col>(&col_side->attackmask, &cursor, pieces[QUEEN], occupants);
  populate_attack_maps<KING, col>(&col_side->attackmask, &cursor, pieces[KING], occupants);
  col_side->attackmask_levels[KING] = col_side->attackmask;

  col_side->attackmapsize = (uint8_t) (cursor - col_side->attackkmaps);
  assert(col_side->attackmapsize <= 16);
}

void derived_knowledge_compute(Board *board) {
  board->side[WHITE].piecemask = piece_mask<WHITE>(board);
  board->side[BLACK].piecemask = piece_mask<BLACK>(board);
  populate_attacks<WHITE>(board);
  populate_attacks<BLACK>(board);
}