You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This chapter documents the implementation of the following techniques used to improve the chess engine:
3
+
This chapter documents the implementation of the following techniques used to improve the playing strenght of the chess engine:
4
4
5
-
\begin{itemize}[itemsep=1pt]
5
+
\begin{itemize}[itemsep=2pt]
6
6
\item Transposition tables with zobrist hashing.
7
7
\item Move generator with magic bitboards and PEXT instructions.
8
8
\item Evaluation with king safety and piece mobility parameters.
9
9
\item Multithread search.
10
10
\item Search with Late move Reductions.
11
11
\end{itemize}
12
+
13
+
\newpage
14
+
12
15
\section{Transposition table}\label{sec:tt}
13
16
14
17
\noindent As discused in the previous chapter (see~\cref{sec:iterativeDeepening}), the basic implementation of the chess engine generates a large amount of redundant calculations due to the iterative deepening approach and also the concept of transpositions: situations in which the same board position is reached through different sequences of moves in the game tree.
15
-
\noindent~\cref{fig:transposition_example} illustrates a position that can arise through multiple move orders. Where the white king could go to the g3 square from multiple paths.
18
+
\noindent the Following image illustrates a position that can arise through multiple move orders. Where the white king could go to the g3 square from multiple paths.
\noindent Taking advantage of dynamic programming, we create a look-up table of chess positions and its evaluation. So if we encounter the same position again, the evaluation is already precalculated. However, we ask ourselves the following question: how much space does the look-up table take up if there are an astronomical amount of chess positions? What we can do is assign a hash to each position and make the table index the last bits of the hash. The larger the table, the less likely access collisions will be. We also want a hash that is fast to calculate and has collision-reducing properties.
33
36
~\cite{TranspositionTable}
34
37
35
-
\vspace{1em}
38
+
\vspace{2em}
36
39
37
40
\noindent\parbox{\textwidth}{The complete implementation can be found in\\\texttt{include\textbackslash{}utilities\textbackslash{}transposition\_table.hpp}.}
38
41
42
+
\newpage
43
+
39
44
\subsection*{Zobrist hashing}
40
45
41
46
Zobrist Hashing is a technique to transform a board position of arbitrary size into a number of a set length, with an equal distribution over all possible numbers invented by Albert Zobrist~\cite{ZobristHashing}.
@@ -45,9 +50,9 @@ \subsection*{Zobrist hashing}
45
50
\noindent To generate a 64-bit hash for a position, the following steps are followed:
46
51
47
52
\begin{enumerate}
48
-
\item Pseudorandom 64-bit numbers are generated for each possible feature of a position:
53
+
\item Pseudorandom 64-bit numbers are generated for various features of a position:
49
54
\begin{enumerate}
50
-
\item One number for each piece type on each square — 12 pieces x 64 squares = 768 numbers.
55
+
\item One number for each piece type on each square (12 pieces x 64 squares).
51
56
\item One number to indicate the side to move is black.
52
57
\item Four numbers to represent castling rights (kingside and queenside for both white and black).
53
58
\item Eight numbers to represent the file of an available \textit{en passant} square.
@@ -164,7 +169,7 @@ \subsection*{Magic bitboards}
164
169
\item The final multiplication must produce a unique index for each possible blocker configuration. The way to ensure the uniqueness is by brute force testing.
165
170
\end{itemize}
166
171
167
-
\noindentAs illustrated in~\cref{fig:magics_position}, we aim to compute the legal moves of the white rook in the given position. In practice, the only pieces that truly block the rook's path are those marked with a red circle.
172
+
\noindentWe aim to compute the legal moves of the white rook in the given position. In practice, the only pieces that truly block the rook's path are those marked with a red circle.
168
173
169
174
\vspace{1em}
170
175
@@ -178,7 +183,7 @@ \subsection*{Magic bitboards}
178
183
color=red, markfields={d6,f4,d2},
179
184
color=green, markfields={c4,b4,a4,e4,d5,d3}
180
185
]
181
-
\caption{Chess position with white rook legal moves in green and blockers in red.}\label{fig:magics_position}
186
+
\caption*{Chess position with white rook legal moves in green and blockers in red.}\label{fig:magics_position}
182
187
\end{figure}
183
188
184
189
\subsection*{Magic number generation}
@@ -189,7 +194,7 @@ \subsection*{Magic number generation}
189
194
190
195
\subsection*{Index calculation}
191
196
192
-
\noindent First, we mask out all pieces outside the rook's attack pattern or on the board borders, as shown in~\cref{fig:magic_preprocessing}.
197
+
\noindent First, we mask out all pieces outside the rook's attack pattern or on the board borders, as shown i the image below.
\caption{Pre-processing of the blockers bitboard}\label{fig:magic_preprocessing}
219
+
\caption*{Pre-processing of the blockers bitboard}\label{fig:magic_preprocessing}
215
220
\end{figure}
216
221
217
-
\noindentAs illustrated in~\cref{fig:magic_multiplication}, the masked blockers bitboard is then multiplied by the magic number. The result retains only the three relevant pawns that obstruct the rook's movement, pushing them toward the most significant bits.
222
+
\noindentThe masked blockers bitboard is then multiplied by the magic number. The result retains only the three relevant pawns that obstruct the rook's movement, pushing them toward the most significant bits.
\caption{Multiplication by magic number to produce an index}\label{fig:magic_multiplication}
246
+
\caption*{Multiplication by magic number to produce an index}\label{fig:magic_multiplication}
242
247
\end{figure}
243
248
244
249
\noindent Next, we compress the index toward the least significant bits by shifting right by \(\,64-\)\texttt{relevant\_squares}. The number of relevant squares varies per board square;~\cref{fig:rook_relevant_squares} shows this for the rook:
\noindent The \texttt{PEXT} (Parallel Bits Extract) instruction—available on modern x86\_64 CPUs—extracts bits from a source operand according to a mask and packs them into the lower bits of the destination operand~\cite{PextInstruction}. It is ideally suited for computing our table index.
306
+
\noindent The \texttt{PEXT} (Parallel Bits Extract) is an instructionavailable on modern CPUs. They extracts bits from a source operand according to a mask and packs them into the lower bits of the destination operand~\cite{PextInstruction}. It is ideally suited for computing our table index.
\caption{Example of the \texttt{PEXT} instruction.}\label{fig:pext_instruction_example}
313
318
\end{figure}
314
319
315
-
\noindent For our previous example (see~\cref{fig:magics_position}), we only need the full bitboard of blockers and the rook’s attack pattern (excluding the borders to reduce space), as illustrated in~\cref{fig:pext_bitboards}.
320
+
\noindent For our previous example (see~\cref{fig:magics_position}), we only need the full bitboard of blockers and the rook's attack pattern (excluding the borders to reduce space), as illustrated below.
\item Otherwise, the engine falls back to the magic bitboards approach using multiplication and bit shifts.
359
364
\end{itemize}
360
365
361
-
\newpage
362
-
363
366
\section{Evaluation with king safety and piece mobility}
364
367
365
368
While material count is the fundamental part for evaluating a chess position, human players also consider strategic and positional factors such as pawn structure, piece activity and king safety. We extend the evaluation function by incorporating additional parameters. These enhancements aim to produce a more accurate assessment of the position.
@@ -437,6 +440,7 @@ \subsection*{Piece mobility}
437
440
]
438
441
\end{center}
439
442
443
+
\newpage
440
444
\section{Multithreaded search}
441
445
442
446
This version of search follows Young Brothers Wait Concept, which is a parallel search algorithm designed to optimize the distribution of work among multiple threads.
\noindent In~\cref{fig:pvsplitting}, the gray circle and square nodes are considered part of the principal variation, while the remaining white nodes are processed in parallel by multiple threads.
0 commit comments