|
|
@ -471,26 +471,41 @@ Position* board_get_rook_moves(const Board* board, const Tile* rook_tile, unsign |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
Checks if a move is legal on this board. |
|
|
|
Checks if a move is legal or not (and reason) on this board. |
|
|
|
|
|
|
|
|
|
|
|
Returns 1 - if the move is legal, 0 - otherwise |
|
|
|
Returns MoveLegality |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
int board_is_move_legal(const Board* board, Move move) { |
|
|
|
MoveLegality board_is_move_legal(const Board* board, Move move, Color color_plays) { |
|
|
|
// Check if the tiles are not out of bounds
|
|
|
|
// Check if the tiles are not out of bounds
|
|
|
|
if (!board_is_tile_in_bounds(board, move.origin) ||
|
|
|
|
if (!board_is_tile_in_bounds(board, move.origin) ||
|
|
|
|
!board_is_tile_in_bounds(board, move.target) |
|
|
|
!board_is_tile_in_bounds(board, move.target) |
|
|
|
) { |
|
|
|
) { |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
return ILLOUTOFBOUNDS; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Check if there is a piece at all
|
|
|
|
// Check if there is a piece at all
|
|
|
|
if (board_get_tile(board, move.origin)->piece.type == NONE) { |
|
|
|
if (board_get_tile(board, move.origin)->piece.type == NONE) { |
|
|
|
return 0; |
|
|
|
return ILLNOPIECE; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Tile* origin_tile = board_get_tile(board, move.origin); |
|
|
|
Tile* origin_tile = board_get_tile(board, move.origin); |
|
|
|
Tile* target_tile = board_get_tile(board, move.target); |
|
|
|
Tile* target_tile = board_get_tile(board, move.target); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check if the piece is of the player's color
|
|
|
|
|
|
|
|
if (origin_tile->piece.color != color_plays) { |
|
|
|
|
|
|
|
return ILLNOTYOURPIECE; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// See if the target tile is of the allied color
|
|
|
|
|
|
|
|
if (tile_is_occupied(*target_tile)) { |
|
|
|
|
|
|
|
// The tile is occupied
|
|
|
|
|
|
|
|
if (target_tile->piece.color == color_plays) { |
|
|
|
|
|
|
|
// The pieces are allied, can't go there!
|
|
|
|
|
|
|
|
return ILLSAMECOLOR; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check based on the piece type
|
|
|
|
// Check based on the piece type
|
|
|
|
Piece origin_piece = origin_tile->piece;
|
|
|
|
Piece origin_piece = origin_tile->piece;
|
|
|
@ -498,23 +513,14 @@ int board_is_move_legal(const Board* board, Move move) { |
|
|
|
case KING: { |
|
|
|
case KING: { |
|
|
|
if (position_distance(move.origin, move.target) > 1) { |
|
|
|
if (position_distance(move.origin, move.target) > 1) { |
|
|
|
// Too far away
|
|
|
|
// Too far away
|
|
|
|
return 0; |
|
|
|
return ILLINVALIDPIECEMOVEMENT; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// See if the target tile is occupied or not
|
|
|
|
return LEGAL; |
|
|
|
if (tile_is_occupied(*target_tile)) { |
|
|
|
|
|
|
|
// The tile is occupied
|
|
|
|
|
|
|
|
if (target_tile->piece.color == origin_piece.color) { |
|
|
|
|
|
|
|
// The pieces are allied, can't go there
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 1; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
case QUEEN: { |
|
|
|
case QUEEN: { |
|
|
|
return 1; |
|
|
|
return LEGAL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
case ROOK: { |
|
|
|
case ROOK: { |
|
|
@ -532,49 +538,54 @@ int board_is_move_legal(const Board* board, Move move) { |
|
|
|
{ |
|
|
|
{ |
|
|
|
// This position is allowed to be moved to
|
|
|
|
// This position is allowed to be moved to
|
|
|
|
free(legal_positions); |
|
|
|
free(legal_positions); |
|
|
|
return 1; |
|
|
|
return LEGAL; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
free(legal_positions); |
|
|
|
free(legal_positions); |
|
|
|
return 0; |
|
|
|
return LEGAL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
case KNIGHT: { |
|
|
|
case KNIGHT: { |
|
|
|
return 1; |
|
|
|
return LEGAL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
case BISHOP: { |
|
|
|
case BISHOP: { |
|
|
|
return 1; |
|
|
|
return LEGAL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
case PAWN: { |
|
|
|
case PAWN: { |
|
|
|
return 1; |
|
|
|
return LEGAL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
default: { |
|
|
|
default: { |
|
|
|
// Non reachable
|
|
|
|
// Non reachable
|
|
|
|
return 0; |
|
|
|
return LEGAL; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
Moves piece from one place to other,
|
|
|
|
Moves piece from one place to other, does not
|
|
|
|
checking whether it is a legal move or not. |
|
|
|
check if move is legal or not. |
|
|
|
|
|
|
|
|
|
|
|
Returns 1 if a move has been successfully done, |
|
|
|
Returns 1 if move has been successfully done, 0 - otherwise |
|
|
|
0 - if it is an illegal move |
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
int board_process_move(Board* board, Move move) { |
|
|
|
int board_make_move(Board* board, Move move) { |
|
|
|
if (!board_is_move_legal(board, move)) { |
|
|
|
if (!board) { |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// The tiles are legal, no need to re-check
|
|
|
|
|
|
|
|
Tile* tile_origin = board_get_tile(board, move.origin); |
|
|
|
Tile* tile_origin = board_get_tile(board, move.origin); |
|
|
|
|
|
|
|
if (!tile_origin) { |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Tile* tile_target = board_get_tile(board, move.target); |
|
|
|
Tile* tile_target = board_get_tile(board, move.target); |
|
|
|
|
|
|
|
if (!tile_target) { |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Move the piece from one tile to another
|
|
|
|
// Move the piece from one tile to another
|
|
|
|
tile_target->piece = tile_origin->piece; |
|
|
|
tile_target->piece = tile_origin->piece; |
|
|
|