aboutsummaryrefslogtreecommitdiff
path: root/src/board/board.hpp
blob: 35e21964d7a5ae69fd6cbd82764c2bea8d46585b (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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#ifndef SRC_BOARD_H_
#define SRC_BOARD_H_

#include <cstdint>
#include <unordered_map>

enum PieceType : std::uint8_t {
  NONEPIECE,
  PAWN,
  KNIGHT,
  BISHOP,
  ROOK,
  QUEEN,
  KING,
};

enum GameState : std::uint8_t {
  TURN,
  WHITE_WON,
  BLACK_WON,
  DRAW,
};

struct Piece {
  bool color = false;
  PieceType type = NONEPIECE;
};

struct Position {
  int rank = 0;
  int file = 0;

  bool operator==(const Position &) const = default;
};

/*
 * Maybe we can try to be efficent with memory by using a byte (char) or
 * something like that let me brainstorm a little
 *
 * first two bits can be promotion flag because there are 4 posible options:
 * NONE BISHOP ROOK QUEEN
 * but wait none it not requided because its only applied
 * when on last rank
 * but that doesnt help becuase we cant have three options
 * ok so first 2 bits for promotion flag
 * like this ZZYYYYYY with ZZ being the promotion flag
 * 00 for none piece
 * 01 for queen
 * 10 for rook
 * 11 for bishop
 * these valuesa are abritrari
 * so we have other 6 bytes which doesnt work that well because we need to store
 * two 64 bit numbers one for "From" and second for "To"
 * so wait how much is a 64 for bit
 * 2 * 2 = 4 (2 bits)
 * 4 * 2 = 8 (3 bits)
 * 8 * 2 = 16 (4 bits)
 * 16 * 2 = 32 (5 bits)
 * 32 * 2 = 64 (6 bits)
 * so six bits that means that we can only store one posiiton we need a 2 + 6 *
 * 2 (14) bits of value to represent it but wait when promotion flag isnt 0 we
 * know its last rank oh but we dont know if from white or black perpective so
 * 14 bits is required let me search if there is a way to store that data
 * alright search done result seams that best way is to use 16 bit interger
 * which look like good solution and we have 2 bits left if we want to add more
 * things here is a diagram for it uint16_t: XXFFFFFFTTTTTT XX for promotion
 * flag F for from position T for to position so we can try first writing a
 * helper function for working with it then replace existing move struct
 */

struct Move {
  Position From;
  Position To;

  PieceType promotion = NONEPIECE;
  bool operator==(const Move &other) const {
    return From == other.From && To == other.To && promotion == other.promotion;
  }
};

enum Flag : std::uint8_t { EXACT, LOWERBOUND, UPPERBOUND };

struct TranspositionsEntry {
  int depth = -1;
  int Eval = 0;
  Flag flag = EXACT;
  Move bestMove = {};
};
struct Game {
  Piece pieces[64];
  uint64_t PieceBitboard = 0; // used for quicly iterating over all squares
  uint64_t WhitePieceBitboard = 0;
  uint64_t BlackPieceBitboard = 0;
  uint64_t PieceBitboards[2][7] = {};
  bool turn = true; // 1 white; 0 black
  bool whiteCastleKing = false;
  bool whiteCastleQueen = false;
  bool blackCastleKing = false;
  bool blackCastleQueen = false;
  int halfMoveClock = 0;
  int MoveClock = 0;
  Position enPassant;
  bool canEnpassant = false;
  GameState state = TURN;
  std::unordered_map<uint64_t, int> ThreeFoldMap;
  std::unordered_map<uint64_t, TranspositionsEntry> *Transpositions = nullptr;
};

struct UndoMove {
  Piece movedPiece;
  Piece capturedPiece;

  Position from;
  Position to;

  bool wasEnPassantCapture = false;
  Position enPassantCapturedSquare;
  Piece enPassantCapturedPiece;

  bool oldTurn;
  bool oldCanEnpassant;
  Position oldEnPassant;

  bool OldWhiteCastleKing;
  bool OldWhiteCastleQueen;
  bool OldBlackCastleKing;
  bool OldBlackCastleQueen;

  int oldHalfMoveClock;
  int oldMoveClock;
  uint64_t ZobristKey;
  GameState oldState;

  // castling
  bool wasCastle = false;
  bool CastledSide = false; // 0 for queen side, 1 for king side
};

int PositionToIndex(Position i);
UndoMove MakeMove(Move move, Game *g);
void UnMakeMove(UndoMove undo, Game *g);

Position FindKing(Game *g, bool white);
void UpdateHelpers(Game *g);
#endif /* SRC_BOARD_H_ */