## Architecture
### Basics
Every chess engine consists of 3 major parts:
- Move generator (which is tightly coupled with Board representation): Move generators
just generate all the possible moves for a given state.
- Evaluation: Evaluation tells our engine if a given state is good or bad for us. Is it worth
taking that piece? Should I move my pawn instead? etc.
- Search: A chess engine just dumbly creates every move and evaluates the position after
every move. Searching is about ruling out moves and ordering them to find the _best move_.
### Move generator
#### BitBoard
This engine uses a bitboard representation. A chess board got 8x8 squares, so a `u6`
number can represent the whole board.
You have to separate the pieces (pawn, knight, bishop, rook, queen, king) and colors, which
gives means 12 `u6` numbers.
It is also convenient to store the occupied squares for each side, that takes 2x`u6`.
see BitBoard and GameState in Board.zig
#### Attacks
Based on the rules for each piece You just generate all possibilities for a given square.
For leaper pieces (pawn, knight and king) it is not that hard, but the sliding pieces
(bishop, rook, and queen) have a lot of possibilities.
To calculate bishop and rook attacks the state of the art method is using
[Magic Bitboards](https://www.chessprogramming.org/Magic_Bitboards).
This engine uses the [Plain](https://www.chessprogramming.org/Magic_Bitboards#Plain) method,
which is the simplest one.
The Attacks.zig file contains everything for attacks. Note, that we have to initialize
bishop and rook attacks with `initSliderAttacks()` before using them with `getBishopAttacks()`,
`getRookAttacks()` and `genQueenAttacks()`.
The `findMagicNumber()` function finds magic numbers. You should only run that once and
just paste it in Your code, it makes no sense to regenerate the same numbers every time.
### Evaluation