home / fornax / fornax-v4-0 / src / moving / movepick.hpp

movepick.hpp



//
//  movepick.hpp
//  fornax3
//
//  Created by Anders on 30/12/2020.
//

#ifndef movepick_h
#define movepick_h

#include "../board.h"
#include "../move.h"
#include "../eval/eval.hpp"
#include "../eval_defs.h"
#include "../eval/eval_piecetables.h"
#include "../parsing.hpp"

static inline eval movepick_debug_print(const char* topic, eval value) {
  printf("|%-20s | %5d |\n", topic, value);
  return value;
}
#define RECORD_MVAL(topic, value) (debug ? movepick_debug_print(topic, value) : value)

static move movepick_killer1[UINT8_MAX + 1] = { 0 };
static move movepick_killer2[UINT8_MAX + 1] = { 0 };

static inline void movepick_set_killer(uint8_t ply, evalmove m) {
  if (MOVE_VALUE(m) > EVAL_MOVEPICK_KILLER_VALUE) return;
  if (movepick_killer1[ply] != m) {
    movepick_killer2[ply] = movepick_killer1[ply];
    movepick_killer1[ply] = (move) m;
  }
}

template <color active, bool debug = false>
static constexpr eval movepick_eval(const Board* board, move m) {
  if (debug) printf("|topic                | value |\n");
  if (debug) printf("|---------------------+-------|\n");
  constexpr color opp = COLOR_OPPOSITE(active);
  constexpr const piecetable *a_mg_psqt = active ? &BLACK_MG_PIECETABLE : &WHITE_MG_PIECETABLE;
  constexpr const piecetable *a_eg_psqt = active ? &BLACK_EG_PIECETABLE : &WHITE_EG_PIECETABLE;
  const bits64 *attack_levels = board->side[opp].attackmask_levels;
  
  const square origin = MOVE_GET_ORIGIN(m);
  const square dest = MOVE_GET_DEST(m);
  const piecetype piece = board->piecemap[origin];
  const piecetype capture = board->piecemap[dest];
  const piecetype promotion = MOVE_GET_PROMOTION(m);
  
  bool is_bad_destination = BITS_TEST(attack_levels[piece], dest);
  assert(!(is_bad_destination && piece == KING));

  const eval piecevalue = EVAL_PIECE[piece];
  
  const eval origin_mg_psqt_score = (*a_mg_psqt)[piece][origin];
  const eval dest_mg_psqt_score = (*a_mg_psqt)[piece][dest];
  const eval origin_eg_psqt_score = (*a_eg_psqt)[piece][origin];
  const eval dest_eg_psqt_score = (*a_eg_psqt)[piece][dest];

  const eval mg_psqt = dest_mg_psqt_score - origin_mg_psqt_score;
  const eval eg_psqt = dest_eg_psqt_score - origin_eg_psqt_score;
  const eval psqt_tapered = eval_taper(board_get_phase(board), mg_psqt, eg_psqt);
  
  eval value = 0;
  value += RECORD_MVAL("PSQT", psqt_tapered);
  value += RECORD_MVAL("destination bad", -is_bad_destination * (piecevalue) / 2);
  if (promotion != KING) {
    value += RECORD_MVAL("promotion bonus", EVAL_PIECE[promotion]);
  }
  if (capture != NONE) {
    value += RECORD_MVAL("capture bonus", EVAL_PIECE[capture] - piecevalue / 8 + EVAL_MOVEPICK_CAPTURE_BONUS);
  }
  else if (piece == PAWN && SQUARE_X(origin) != SQUARE_X(dest)) {
    value += RECORD_MVAL("en passant bonus", EVAL_MOVEPICK_ENPASSANT_VALUE); // ep boost
  }
  if (debug) printf("|---------------------+-------|\n");
  return RECORD_MVAL("total", value);
  
}



template <color active>
static constexpr void movepick_annotate_list(const Board* board, evalmove moves[128], uint8_t size, move ttmove) {
  for (uint8_t n = 0; n < size; n++) {
    evalmove m = moves[n];
    
    eval value = movepick_eval<active, false>(board, (move) m);
    if ((move) m == ttmove) {
      value += EVAL_MOVEPICK_TT_VALUE;
    }
    else if ((move) m == movepick_killer1[board->ply]) {
      value += EVAL_MOVEPICK_KILLER_VALUE;
    }
    else if ((move) m == movepick_killer2[board->ply]) {
      value += EVAL_MOVEPICK_KILLER_VALUE;
    }
    
    moves[n] |= (unsigned int) (value << 16);
  }
}

static constexpr void movepick_annotate_ttmove(evalmove moves[128],
                                      uint8_t size,
                                      move ttmove) {
  if (!ttmove) return;
  for (uint8_t n = 0; n < size; n++) {
    move m = (move) moves[n];
    if (m != ttmove) continue;
    moves[n] += EVAL_PIECE_KINGS << 16;
  }
}

static constexpr evalmove movepick_find_best(evalmove moves[128], uint8_t size, uint8_t n) {
  eval best = INT16_MIN;
  uint8_t bi = 0;
  for (uint8_t i = n; i < size; i++) {
    evalmove m = moves[i];
    eval e = MOVE_VALUE(m);
    if (e > best) {
      best = e;
      bi = i;
    }
  }
  evalmove bm = moves[bi];
  moves[bi] = moves[n];
  return bm;
}

#endif /* movepick_h */