I really appreciate the response from our contributors, but still there is a question unanswered floating on air. How do I implement the “MOVE” structure? Based on Bitboard approach?
In reality, there is no a common ground among chess engines. Some programmers will tell you go with a structure and store any move’s detail within, but, on the other side, others will tell you, go simple with just one data type (Integer, String, etc).
To be honest, in simple English means, USE whatever flavor you feel comfortable with and, not a subject related to best performance. So, based on that assumption, I will provide you how to implement both cases.
To make this simple, let’s break down what kind of information is needed to encode a move.
- Index of square destination
- Index of square origin
- Type of move (quiet, captures, evasions, en passant, castling, …)
Structure Approach

If you decide to go with a structure approach, you will have something similar to this:
struct Move {
Int from;
Int to;
Int moveType;
};
That will work if we have an enum for our moveType:
enum MoveType {
QUIET, CAPTURE, EVASION, ENPASSANT, CASTLING
};
The structure approach will do the work and, then you just need to create an array with that structure to store the list of generated moves. And that’s it; you have your container to store moves.
Single Data Type Approach
Suppose we decide to go with Integer type. How we can store the move information in one single integer? The response is, Bit manipulation (Duh!, we are using bitbaord representation).
The idea is really simple, let’s use partial portion of the Integer to store the “square origin”, and next to it, use it to store the “square destination” and last, insert the “Move Type” (call it flag if you want).
If we have an Integer that holds 16 bits, we can dissect it into the following:
0000 0000 0000 0000 – index of square origin
0000 0000 0000 0000 – index of square destination
0000 0000 0000 0000 – move type (flag)
We can use the first 6 bit to store the square origin.
0000 0000 0011 1111 – 6 bit for square origin
We can do the same with the rest. At the end you will have something like this:
0000 0000 0011 1111 – index of square origin
0000 1111 1100 0000 – index of squire destination
0011 0000 0000 0000 – move type (flag)
To put this into a better context, let assume we have a structure that represent each square:
enum Square {
SQ_A1, SQ_B1, SQ_C1, SQ_D1, SQ_E1, SQ_F1, SQ_G1, SQ_H1,
SQ_A2, SQ_B2, SQ_C2, SQ_D2, SQ_E2, SQ_F2, SQ_G2, SQ_H2,
SQ_A3, SQ_B3, SQ_C3, SQ_D3, SQ_E3, SQ_F3, SQ_G3, SQ_H3,
SQ_A4, SQ_B4, SQ_C4, SQ_D4, SQ_E4, SQ_F4, SQ_G4, SQ_H4,
SQ_A5, SQ_B5, SQ_C5, SQ_D5, SQ_E5, SQ_F5, SQ_G5, SQ_H5,
SQ_A6, SQ_B6, SQ_C6, SQ_D6, SQ_E6, SQ_F6, SQ_G6, SQ_H6,
SQ_A7, SQ_B7, SQ_C7, SQ_D7, SQ_E7, SQ_F7, SQ_G7, SQ_H7,
SQ_A8, SQ_B8, SQ_C8, SQ_D8, SQ_E8, SQ_F8, SQ_G8, SQ_H8
};
Imagine you have a pawn sitting on f2 and you need to move it to f4, and there is an enemy pawn on e4. This will raise the en passant flag, isn’t it?

So, we need to encode our pawn move from f2 to f4 and flag it as enpassant availability.
Pseudo code will be like this:
move = enpassant-flag + destination + origin;
Now we need to translate this to bit manipulation (shifting bits).
unsigned int move;
//insert square origin using 6 bits
move = (origin & 0x3f << 6); -the hex to mask 6 bits.
// insert square destination using also 6 bits
move = (destination & 0x3f);
//insert the flag
move = ((flag & 0xf) << 12);
// now putting everything together…
Move make_move(Square from, Square to, unsigned int flag) {
Return move = ((flag & 0xf) << 12) | (destination & 0x3f) | (origin & 0x3f) << 6;
}
Now you can call the method as follow:
moveList = make_move(SQ_F2, SQ_F4, ENPASSANT);
I hope this information will be useful to the public :)