diff --git a/src/chess.c b/src/chess.c index 3a904d9..c769c89 100644 --- a/src/chess.c +++ b/src/chess.c @@ -71,12 +71,65 @@ bool get_move(move_t *move) { return is_move_in_bounds(*move); } -bool perform_move(player_e player, move_t move) { - +bool compare_pos(pos_t a, pos_t b) { + return a.x == b.x && a.y == b.y; +} + +/** + * check the wanted pos_t against all valid move options + * of the current piece + */ +bool is_move_legal(move_t move) { + valid_move_t valid_moves[PIECE_COUNT] = DEFAULT_VALID_MOVES; + for (int i = 0; i < PIECE_COUNT; i++) { + for (int j = 0; + j < valid_moves[i].piece_move_count && + move.piece == valid_moves[i].piece; + j++ + ) { + pos_t new_pos = {move.from.x+move.to.x, move.from.y+move.to.y}; + if (compare_pos(new_pos, valid_moves[i].options[j]) == true) { + return true; + } + } + } + + return false; +} + +bool is_none(board_t board, pos_t pos) { + return board[pos.y][pos.x] == NONE; +} + +// the move can be: +// 1. legal x illegal +// 2. the 'to' pos could be occupied x non-occupied +// 2a. it could be capturable x non-capturable +bool validate_move(board_t board, move_t move) { + bool none = is_none(board, move.to); + bool move_legal = is_move_legal(move); + if (none == true && move_legal == true) { + // free ability to move + return true; + } else if (none == false && move_legal == true) { + // capturing + return true; + } else { + // otherwise, invalid move + return false; + } +} + +/** TODO: capturing and promotions */ +bool perform_move(board_t *board, player_e player, move_t move) { + if (validate_move(*board, move) == true) { + *board[move.to.y][move.to.x] = move.piece; // move piece to wanted place + *board[move.from.y][move.from.x] = NONE; // erase the remnants + } } end_condition_e check_edge_cases(board_t board) { - + } void announce_results(end_condition_e end_condition, player_e player) { diff --git a/src/chess.h b/src/chess.h index 8486d0a..a06b807 100644 --- a/src/chess.h +++ b/src/chess.h @@ -49,11 +49,6 @@ typedef struct { pos_t to; } move_t; -typedef struct { - int dirx; - int diry; -} relative_move_t; - // the default arrangment of pieces on the board #define BOARD_DEFAULT_CONFIG \ (board_t){\ @@ -68,7 +63,7 @@ typedef struct { typedef struct { piece_e piece; - relative_move_t moves[MAX_PIECE_MOVE_COUNT]; + pos_t options[MAX_PIECE_MOVE_COUNT]; unsigned int piece_move_count; } valid_move_t; @@ -90,27 +85,30 @@ typedef struct { * absolute x,y values -> e.g. the rook can move * up, down, left, right * n -> and then bounds & edge cases are checked */ -#define DEFAULT_VALID_MOVES \ -(valid_move_t[PIECE_COUNT]){\ - {NONE, (relative_move_t[0]){}, 0},\ - {PAWN, (relative_move_t[4]){\ - {0, -1}, {-1, -1}, {+1, -1}, {0, -2}\ +#define DEFAULT_VALID_MOVES (valid_move_t[PIECE_COUNT]){\ + {NONE, {}, 0},\ + {PAWN, {\ + { 0, -1}, {-1, -1}, {+1, -1}, { 0, -2}\ }, 4},\ - {ROOK, (relative_move_t[4]){\ - {0, -1}, {0, +1}, {-1, 0}, {+1, 0}\ + {ROOK, {\ + { 0, -1}, { 0, +1}, {-1, 0}, {+1, 0}\ }, 4},\ - {KNIGHT, (relative_move_t)[8], {\ + {KNIGHT, {\ {-1, -2}, {+1, -2}, {-2, -1}, {-2, +1},\ {+2, -1}, {+2, +1}, {-1, -2}, {-1, +2}\ }, 8},\ - {BISHOP, (relative_move_t[4]){\ + {BISHOP, {\ {-1, -1}, {-1, +1}, {+1, -1}, {+1, +1}\ }, 4},\ - {QUEEN, (relative_move_t[8]){\ - {0, -1}, {0, +1}, {-1, 0}, {+1, 0},\ + {QUEEN, {\ + {0, -1}, {0, +1}, {-1, 0}, {+1, 0},\ + {-1, -1}, {-1, +1}, {+1, -1}, {+1, +1}\ + }, 8},\ + {KING, {\ + { 0, -1}, { 0, +1}, {-1, 0}, {+1, 0},\ {-1, -1}, {-1, +1}, {+1, -1}, {+1, +1}\ }, 8}\ -}\ +} typedef enum { CHECKMATE, @@ -128,7 +126,7 @@ void select_player(player_e *player, unsigned int round_count); bool get_move(move_t *move); // performs the move if is it possible -bool perform_move(player_e player, move_t move); +bool perform_move(board_t *board, player_e player, move_t move); // checks for captures, prommotions and mates end_condition_e check_edge_cases(board_t board); diff --git a/src/main.c b/src/main.c index 50f696f..9d0d8ef 100644 --- a/src/main.c +++ b/src/main.c @@ -37,7 +37,7 @@ int main() { get_move(&move); - perform_move(player, move); + perform_move(&board, player, move); end_condition = check_edge_cases(board); if (end_condition == CHECKMATE || end_condition == STALEMATE) {