home / fornax / fornax-v4-0 / src / board.h

board.h



//
//  board.h
//  fornax3
//
//  Created by Anders on 15/12/2020.
//

#ifndef board_h
#define board_h

#include "bits.h"
#include "eval_defs.h"

enum color : uint8_t {
  WHITE = 0,
  BLACK
};
#define COLOR_OPPOSITE(c) (color) ( 1 - c)

enum piecetype : uint8_t {
  KING,
  QUEEN,
  ROOK,
  BISHOP,
  KNIGHT,
  PAWN,
  NONE
};

template<direction dir>
constexpr static direction dir_opposite() {
  switch (dir) {
    case N: return S;
    case E: return W;
    case S: return N;
    case W: return E;
    case NE: return SW;
    case SE: return NW;
    case SW: return NE;
    case NW: return SE;
  }
}

typedef struct {
  uint64_t hash;
  bits64 enpassant;
  bits64 castlingrights;
  piecetype capture;
  uint8_t halfmovecount;
} Plyinfo;

typedef struct {
  piecetype piece;
  bits64 bits;
} Attackmap;

typedef struct {
  bits64 pieces[6];
  bits64 piecemask;

  // derived knowledge
  bits64 attackmask;
  bits64 attackmask_levels[6];
  Attackmap attackkmaps[16];
  uint8_t attackmapsize;

  // incrementally updated knowledge
  uint8_t eval_phase;
  eval eval_material;
  eval eval_mg_psqt;
  eval eval_eg_psqt;
} Side;

typedef struct {
  color active;
  color active_initial;// for pondering
  Side side[2];
  
  Plyinfo plyinfo[UINT8_MAX + 1];
  uint8_t ply;
  
  piecetype piecemap[64]; // for finding pieces during make/sort
  
} Board;


static constexpr bits64 board_get_king_attackmask(const Side* side) {
  return side->attackkmaps[side->attackmapsize - 1].bits;
}

static constexpr bits64 board_get_pawns_attackmask(const Side* side) {
  return side->attackkmaps[0].bits | side->attackkmaps[1].bits;
}

static constexpr uint8_t board_get_phase(const Board* board) {
  return board->side[WHITE].eval_phase + board->side[BLACK].eval_phase;
}

static constexpr uint8_t board_count_phase(const Side *side) {
  uint8_t count = 0;
  count += BITS_COUNT(side->pieces[QUEEN]) * EVAL_PHASE_QUEENS;
  count += BITS_COUNT(side->pieces[ROOK]) * EVAL_PHASE_ROOKS;
  count += BITS_COUNT(side->pieces[BISHOP]) * EVAL_PHASE_BISHOPS;
  count += BITS_COUNT(side->pieces[KNIGHT]) * EVAL_PHASE_KNIGHTS;
  return count;
}

static constexpr const Plyinfo* board_get_currinfo(const Board* board) {
  return &board->plyinfo[board->ply];
}

static constexpr Plyinfo* board_get_nextinfo(Board* board) {
  uint8_t next = board->ply + 1;
  return &board->plyinfo[next];
}

static constexpr const Plyinfo* board_get_previnfo(const Board* board) {
  uint8_t prev = board->ply - 1;
  return &board->plyinfo[prev];
}

static constexpr uint64_t board_get_hash(const Board* board) {
  return board_get_currinfo(board)->hash;
}

static constexpr piecetype board_get_piece(const Board *board, color color, square sq) {
  const Side* side = &board->side[color];

  uint8_t test = BITS_TEST(side->pieces[0], sq) * 6
  | BITS_TEST(side->pieces[1], sq) * 5
  | BITS_TEST(side->pieces[2], sq) * 4
  | BITS_TEST(side->pieces[3], sq) * 3
  | BITS_TEST(side->pieces[4], sq) * 2
  | BITS_TEST(side->pieces[5], sq) * 1;
  return (piecetype) (NONE - test);
}

static inline void board_put(Board *board, color color, square sq, piecetype type) {
  assert(board_get_piece(board, WHITE, sq) == NONE);
  assert(board_get_piece(board, BLACK, sq) == NONE);
  assert(type != NONE);
  board->piecemap[sq] = type;
  BITS_SET(board->side[color].pieces[type], sq);
}

#endif /* board_h */