aboutsummaryrefslogtreecommitdiff
path: root/src/zobrist.cpp
blob: 20ac5e9e184df6d7bf681f435231d7def11cbef0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include "zobrist.hpp"
#include "board/board.hpp"

#include <random>

uint64_t PieceKeys[2][7][64];
uint64_t SideKey;
uint64_t CastleKeys[16];
uint64_t EnPassantKeys[8];

void InitZobrist() {
  std::mt19937_64 rng(1234567); // fixed seed

  for (int color = 0; color < 2; color++) {
    for (int piece = 0; piece < 7; piece++) {
      for (int square = 0; square < 64; square++) {
        PieceKeys[color][piece][square] = rng();
      }
    }
  }

  SideKey = rng();

  for (int i = 0; i < 16; i++) {
    CastleKeys[i] = rng();
  }

  for (int i = 0; i < 8; i++) {
    EnPassantKeys[i] = rng();
  }
}

uint64_t GenerateZobristKey(Game *b) {
  uint64_t key = 0;

  for (int square = 0; square < 64; square++) {
    Piece p = b->pieces[square];

    if (p.type == NONEPIECE)
      continue;

    key ^= PieceKeys[p.color][p.type][square];
  }

  // side to move
  if (b->turn)
    key ^= SideKey;

  // castling
  int castle = 0;

  if (b->whiteCastleKing)
    castle |= 1;

  if (b->whiteCastleQueen)
    castle |= 2;

  if (b->blackCastleKing)
    castle |= 4;

  if (b->blackCastleQueen)
    castle |= 8;

  key ^= CastleKeys[castle];

  // en passant
  if (b->canEnpassant) {
    key ^= EnPassantKeys[b->enPassant.file];
  }

  return key;
}