home / fornax / fornax-v4-0 / src / tt / zobrist.cpp

zobrist.cpp



//
//  zobrist.cpp
//  fornax3
//
//  Created by Anders on 25/12/2020.
//

#include <random>
#include "zobrist.hpp"
#include "board.h"
#include <stdarg.h>

ttkey* hashes;
#define SEED 0xAC20201003
void zobrist_init() {
  std::mt19937_64 eng(SEED); // 64-bit Mersenne Twister 19937
  std::uniform_int_distribution<ttkey> dist;
  
  hashes = (ttkey*) calloc(64 * 13, sizeof(ttkey));

  // pieces numbers
  for (int i = 0; i < 12 * 64; ++i) hashes[i] = dist(eng);

  // castling numbers
  hashes[12 * 64] = dist(eng);
  hashes[12 * 64 + 7] = dist(eng);
  hashes[12 * 64 + 56] = dist(eng);
  hashes[12 * 64 + 63] = dist(eng);

  // en passant numbers
  for (int i = 12 * 64 + 16; i < 12 * 64 + 24; ++i) hashes[i] = dist(eng);
  for (int i = 12 * 64 + 40; i < 12 * 64 + 48; ++i) hashes[i] = dist(eng);

  // "whose turn is it" number
  hashes[12 * 64 + 49] = dist(eng);
}

void zobrist_destroy() {
  free(hashes);
}

ttkey zobrist_compute_hash(const Board* b) {
  ttkey hash = 0;
  
  for (int i = 0; i < 6; i++) {
    ttkey bb = b->side[WHITE].pieces[i];
    while (bb) {
      square sq = bits_pop_trailing(&bb);
      hash ^= zobrist_get_piece<WHITE>((piecetype) i, sq);
    }
    bb =  b->side[BLACK].pieces[i];
    while (bb) {
      square sq = bits_pop_trailing(&bb);
      hash ^= zobrist_get_piece<BLACK>((piecetype) i, sq);
    }
  }
  if (b->active == BLACK) hash ^= zobrist_get_switchmove();
  const Plyinfo* info = &b->plyinfo[b->ply];
  if (info->castlingrights & BB_RIGHTS_WCK) hash ^= zobrist_get_castle(7);
  if (info->castlingrights & BB_RIGHTS_WCQ) hash ^= zobrist_get_castle(0);
  if (info->castlingrights & BB_RIGHTS_BCK) hash ^= zobrist_get_castle(63);
  if (info->castlingrights & BB_RIGHTS_BCQ) hash ^= zobrist_get_castle(56);
  if (info->enpassant) hash ^= zobrist_get_enpassant(info->enpassant);
  return hash;
}