Make Move

The makemove() (refer board.c) function does 3 things:

1. Update all parameters of the position depending upon the move -

Make move has to change all parameters of the position according to the move.

It makes extensive use of the move_type to determine the type of move and make all changes accordingly.

Following are comments on various parameters that are changed.

Piece Placement parameters:

For piece placement it is the general 2 steps:

piece[move_to] = piece[move_from] /* Update destination square with originating square*/

piece[move_from] = EMPTY /* empty the originating square*/

Same 2 steps for colour array.

However it is different for other type of moves.

1. Castling - It is the only move involving movement of more than 1 piece (rook as well as king) in a single move. Therefore it has to be handled separately.

2. En-Passant - The captured pawn does not exist on the destination square. Hence different code is needed to empty the square on which captured pawn existed.

3. Promotion - In case of promotion the piece on destination square is different from the piece on originating square (a pawn)

Non - piece placement parameters:

1. En-passant flag is generated if the move is a pawn double move. Else for any other move it is changed to -1 (whatever it might be previously)

2. side to move is changed

3. ply is increased

4. castling flags are changed brilliantly (using bit ANDing trick)

The code for updating parameters is self explanatory.

2. Store various parameters of the chess position before updating them -

Before the non-piece placement parameters are changed by make move, they are pushed on a stack.

This is so that the unmake move can quickly copy those parameters back rather than determining them on the fly.

This increases performance.

Why is not the whole board copied before make move so that un-make can simply copy everything back?

Because it would be more load to copy all the 64 squares of 2 arrays - piece and color

Processing of piece placement is faster and soft parameters which are few in number are just copied (for storage) and fetched later (for retrieval)

Also note that we have to anyway copy 3 pieces of information - castling rights, en-passant square and captured piece

Everything else can be interpreted from the move and un-make can be processed on-the-fly

In the code, a data structure hist_dat is used to store this.

Refer defs.c for the definition of the structure:

typedef struct {

move m;

int capture;

int castle;

int ep;

int fifty;

int hash;

} hist_t;

Then refer data.c for the history stack array

hist_t hist_dat[HIST_STACK];

There is 1 more variable used called hply which is used as a tracker for history stack array.

3. Rule checking:

Since pseudo-legal moves are generated by the move generator - the make_move function also further checks the legality of the moves.

Based on this it returns a value of true or false.

The complex rules for which the move maker checks are:

1. Castle (king should not be in check, castle squares should be empty and unattacked)

2. King in check (any move which leaves your king in check is illegal)

Hence we need some sort of "attack detection" to check for castling (castling squares should not be under attack) and king in check.

Secondly, the "king in check" rule is determined by actually making the move and checking whether the king is attacked.

This is done using the function BOOL attack(int sq, int s) (refer board.c)

It takes a legal chess square and the side and returns true if the side attacks the square.

The code for this is similar to move generation.

Finally a move is made then attack detection is called for king.

If king is detected in check, the move is taken back and "false" is returned by move maker.