From b40d016e676e5b72d01975be0629618c68c7b3c9 Mon Sep 17 00:00:00 2001 From: Odweta Date: Wed, 18 Feb 2026 17:35:21 +0100 Subject: [PATCH] maybe DONE???? (displaying the board is left though) --- src/chess.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 138 insertions(+), 11 deletions(-) diff --git a/src/chess.c b/src/chess.c index 8350afc..58de3ae 100644 --- a/src/chess.c +++ b/src/chess.c @@ -91,10 +91,7 @@ bool is_pos_oob(pos_t pos) { * of the current piece */ bool is_move_legal(move_t move) { - pos_t new_pos = { - move.from.x+move.to.x, - move.from.y+move.to.y - }; + pos_t new_pos = move.to; // OOB check if (is_pos_oob(new_pos)) { @@ -222,10 +219,7 @@ bool check_captures(board_t *board, player_e player, captured_t *captured, move_ // checks and sorts out a promotion edge case of a move bool check_promotions(board_t *board, player_e player, move_t *move) { - pos_t new_pos = { - move->from.x+move->to.x, - move->from.y+move->to.y - }; + pos_t new_pos = move->to; // white player achieved a promotion if (new_pos.y < 0 && player == WHITE && move->piece == WPAWN) { @@ -244,10 +238,143 @@ bool check_promotions(board_t *board, player_e player, move_t *move) { return false; } +// negative pos => no such piece is there +pos_t get_pos_of_piece(board_t board, piece_e piece) { + for (int i = 0; i < BOARD_VERTICAL; i++) { + for (int j = 0; j < BOARD_VERTICAL; j++) { + if (board[i][j] == piece) { + return (pos_t){j, i}; + } + } + } + + return (pos_t){-1, -1}; +} + +// if king's pos is in another piece's valid moves, it is endangered +bool is_king_endangered(board_t board, player_e player, move_t move) { + pos_t king_pos; + valid_move_t valid_moves[PIECE_COUNT] = DEFAULT_VALID_MOVES; + + switch (player) { + case WHITE: + king_pos = get_pos_of_piece(board, WKING); + switch (move.piece) { + case NONE: + case BPAWN: + case BKNIGHT: + case BKING: + 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++ + ) { + if ( + compare_pos( + king_pos, + valid_moves[i].options[j] + ) + ) { + return true; + } + } + } + break; + case BROOK: + case BBISHOP: + case BQUEEN: + 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++ + ) { + /** NOTE: BOARD_HORIZONTAL assuming HORIZONTAL & VERTICAL are the same */ + for (int k = 0; k < BOARD_HORIZONTAL; k++) { + if ( + compare_pos( + king_pos, + pos_multiply_scalar(valid_moves[i].options[j], k) + ) + ) { + return true; + } + } + } + } + break; + default: + break; + } + break; + case BLACK: + king_pos = get_pos_of_piece(board, BKING); + switch (move.piece) { + case NONE: + case WPAWN: + case WKNIGHT: + case WKING: + 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++ + ) { + if ( + compare_pos( + king_pos, + valid_moves[i].options[j] + ) + ) { + return true; + } + } + } + break; + case WROOK: + case WBISHOP: + case WQUEEN: + 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++ + ) { + /** NOTE: BOARD_HORIZONTAL assuming HORIZONTAL & VERTICAL are the same */ + for (int k = 0; k < BOARD_HORIZONTAL; k++) { + if ( + compare_pos( + king_pos, + pos_multiply_scalar(valid_moves[i].options[j], k) + ) + ) { + return true; + } + } + } + } + break; + default: + break; + } + break; + } + + return false; +} + // checks for mates /** FIXME: unimplemented */ -end_condition_e check_end() { - return CONTINUE; +end_condition_e check_end(board_t board, player_e player, move_t move) { + // here 'is_move_legal' is used as a determinator if a piece can move + if (is_king_endangered(board, player, move) && !is_move_legal(move)) { + return CHECKMATE; + } else if (!is_king_endangered(board, player, move) && !is_move_legal(move)) { + return STALEMATE; + } else { + return CONTINUE; + } } end_condition_e perform_move(board_t *board, player_e player, captured_t *captured, move_t move) { @@ -265,7 +392,7 @@ end_condition_e perform_move(board_t *board, player_e player, captured_t *captur *board[move.from.y][move.from.x] = NONE; // erase the remnants } - return check_end(); + return check_end(*board, player, move); } void announce_results(end_condition_e end_condition, player_e player) {