home / fornax-v3-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_defs.h"
#include "../eval/eval_piecetables.h"
#include "../parsing.hpp"

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, move ttmove) {
  if (m == ttmove) return;
  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>
static constexpr void movepick_annotate(const Board* board, evalmove moves[128], uint8_t size, move ttmove) {
  constexpr color opp = COLOR_OPPOSITE(active);
  constexpr const piecetable *psqt = active ? &BLACK_MG_PIECETABLE : &WHITE_MG_PIECETABLE;
  
  bits64 attacks = board->side[opp].attackmask;
  
  for (uint8_t n = 0; n < size; n++) {
    evalmove m = moves[n];
    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_attacked_destination = BITS_TEST(attacks, dest);

    const eval piecevalue = EVAL_PIECE[piece];;
    
    const eval origin_psqt = (*psqt)[piece][origin];
    const eval dest_psqt = (*psqt)[piece][dest];
    
    eval value = 0;
    value -= is_attacked_destination * (piecevalue) / 2;
    value -= origin_psqt;
    value += dest_psqt;
    
    if (promotion != KING) {
      value += EVAL_PIECE[promotion];
    }
    if (capture != NONE) {
      value += EVAL_PIECE[capture] - piecevalue / 16 + EVAL_MOVEPICK_CAPTURE_BONUS;
    }
    else if (piece == PAWN && SQUARE_X(origin) != SQUARE_X(dest)) {
      value += EVAL_MOVEPICK_ENPASSANT_VALUE; // ep boost
    }
    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 */