From 4155ed3e8796458591b145c7a7cbd0ae8cce1cda Mon Sep 17 00:00:00 2001 From: Ole Morud Date: Sun, 26 Mar 2023 19:14:59 +0200 Subject: [PATCH] Reformat code with help of utility functions --- include/common.h | 4 +- include/util.h | 2 + src/pieces.c | 162 +++++++++++++++++++++++------------------------ src/util.c | 36 +++++++++++ 4 files changed, 120 insertions(+), 84 deletions(-) diff --git a/include/common.h b/include/common.h index 2417250..54e6d53 100644 --- a/include/common.h +++ b/include/common.h @@ -11,8 +11,8 @@ typedef ptrdiff_t index_t; #define BOARD_SIZE ((index_t)(8 * 8)) -#define WHITE 1 -#define BLACK -1 +#define WHITE ((tile_t)1) +#define BLACK ((tile_t)-1) #define E ((tile_t)0) ///< empty tile #define K ((tile_t)1) ///< king diff --git a/include/util.h b/include/util.h index a027e04..e0adfd8 100644 --- a/include/util.h +++ b/include/util.h @@ -1,9 +1,11 @@ #include "common.h" +int64_t get_sign(int64_t n); bool tile_empty(tile_t t); index_t abs_index(index_t i); index_t column(index_t i); index_t row(index_t i); tile_t abs_tile(tile_t t); +tile_t get_color(tile_t t); bool same_color(tile_t a, tile_t b); bool opposite_color(tile_t a, tile_t b); diff --git a/src/pieces.c b/src/pieces.c index 102b1b9..88611e8 100644 --- a/src/pieces.c +++ b/src/pieces.c @@ -7,44 +7,90 @@ bool cardinal_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to); bool diagonal_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to); bool king_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to); bool knight_move_ok(index_t from, index_t to); -bool pawn_move_ok(const tile_t board[BOARD_SIZE], - index_t from, - index_t to, - int player); +bool pawn_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to); bool queen_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to); bool rook_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to); +/** + * Check if a move is valid + * + * \param board Pointer to list of tiles representing board state + * \param from Tile to move piece from + * \param to Tile to move piece to + * \param player The current player to move + * + * \return true if move is valid, false otherwise + * */ +bool move_ok(const tile_t board[BOARD_SIZE], + index_t from, + index_t to, + int player) +{ + /* player must own piece it moves */ + if (board[from] * player < 0) + return false; + + /* empty tiles can't be moved */ + if (tile_empty(board[from])) + return false; + + /* player can't take their own pieces or move a piece onto itself */ + if (same_color(board[from], board[to])) + return false; + + /* check piece specific moves */ + switch (abs_tile(board[from])) { + case P: + return pawn_move_ok(board, from, to); + + case B: + return bishop_move_ok(board, from, to); + + case R: + return rook_move_ok(board, from, to); + + case N: + return knight_move_ok(from, to); + + case K: + return king_move_ok(board, from, to); + + case Q: + return queen_move_ok(board, from, to); + } + + return false; +} + /** * Check if move is a valid pawn move * * \param board Array of tiles representing chess board state * \param from Index of board piece starts at * \param to Index of board piece wants to move to - * \param player Player to move * * \return true if move is valid, false otherwise */ -bool pawn_move_ok(const tile_t board[BOARD_SIZE], - index_t from, - index_t to, - int player) +bool pawn_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to) { - const index_t diff = (to - from) * -player; + const index_t direction = -1 * get_color(board[from]), + diff = (to - from) * direction; switch (diff) { - default: - return false; - case ROW: /* single move */ return tile_empty(board[to]); - case ROW - 1: - case ROW + 1: /* diagonal attack */ + case ROW - COL: /* diagonal attack */ + case ROW + COL: return opposite_color(board[to], board[from]); case 2 * ROW: /* double move */ - return tile_empty(board[to]) && tile_empty(board[from - ROW * player]) + return tile_empty(board[to]) + && tile_empty(board[from + ROW * direction]) && (row(from) == 1 || row(from) == 6); + + default: /* any other move is illegal */ + return false; } } @@ -59,12 +105,13 @@ bool pawn_move_ok(const tile_t board[BOARD_SIZE], */ bool diagonal_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to) { - const index_t col_diff = column(to) - column(from); - const index_t row_diff = row(to) - row(from); - - const index_t x_step = col_diff / abs_index(col_diff); - const index_t y_step = ROW * row_diff / abs_index(row_diff); - const index_t step = x_step + y_step; + // clang-format off + const index_t col_diff = column(to) - column(from), + row_diff = row(to) - row(from), + x = get_sign(col_diff), + y = get_sign(row_diff) * ROW, + step = x + y; + // clang-format on if (abs_index(col_diff) != abs_index(row_diff)) return false; @@ -87,14 +134,14 @@ bool diagonal_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to) */ bool cardinal_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to) { - const index_t col_diff = column(to) - column(from); - const index_t row_diff = row(to - from); + const index_t col_diff = column(to) - column(from), + row_diff = row(to - from); if (row_diff > 0 && col_diff > 0) return false; - index_t step = row_diff ? ROW * row_diff / abs_index(row_diff) : - col_diff / abs_index(col_diff); + const index_t step = + row_diff ? ROW * get_sign(row_diff) : get_sign(col_diff); for (index_t p = from + step; p != to; p += step) if (! tile_empty(board[p])) @@ -141,10 +188,10 @@ bool rook_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to) */ bool knight_move_ok(index_t from, index_t to) { - const index_t c = abs_index(column(to) - column(from)); - const index_t r = abs_index(row(to - from)); + const index_t x = abs_index(column(to) - column(from)), + y = abs_index(row(to - from)); - return (c == 1 && r == 2) || (c == 2 && r == 1); + return (x == 1 && y == 2) || (x == 2 && y == 1); } /** @@ -158,12 +205,13 @@ bool knight_move_ok(index_t from, index_t to) */ bool king_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to) { - const index_t abs_col_diff = abs_index(column(to) - column(from)); - const index_t abs_row_diff = abs_index(row(to) - row(from)); + const index_t abs_x = abs_index(column(to) - column(from)), + abs_y = abs_index(row(to) - row(from)); + // TODO: check if move causes check (void)board; - return abs_col_diff <= 1 && abs_row_diff <= 1; + return abs_x <= 1 && abs_y <= 1; } /** @@ -180,53 +228,3 @@ bool queen_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to) return diagonal_move_ok(board, from, to) || cardinal_move_ok(board, from, to); } - -/** - * Check if a move is valid - * - * \param board Pointer to list of tiles representing board state - * \param from Tile to move piece from - * \param to Tile to move piece to - * \param player The current player to move - * - * \return true if move is valid, false otherwise - * */ -bool move_ok(const tile_t board[BOARD_SIZE], - index_t from, - index_t to, - int player) -{ - /* player must own piece it moves */ - if (board[from] * player < 0) - return false; - - if (tile_empty(board[from])) - return false; - - /* player can't take own pieces or move piece onto itself*/ - if (same_color(board[from], board[to])) - return false; - - /* check piece specific moves */ - switch (abs_tile(board[from])) { - case P: - return pawn_move_ok(board, from, to, player); - - case B: - return bishop_move_ok(board, from, to); - - case R: - return rook_move_ok(board, from, to); - - case N: - return knight_move_ok(from, to); - - case K: - return king_move_ok(board, from, to); - - case Q: - return queen_move_ok(board, from, to); - } - - return false; -} diff --git a/src/util.c b/src/util.c index da66c03..eb58453 100644 --- a/src/util.c +++ b/src/util.c @@ -1,6 +1,42 @@ #include "util.h" +#include "common.h" + +/** + * Get sign of a number + * + * \param n positive or negative integer + * + * \return 1 if number is positive + * -1 if number is negative + * 0 if number is zero + */ +int64_t get_sign(int64_t n) +{ + if (n == 0) + return 0; + + if (n >= 0) + return 1; + + return -1; +} + +/** + * Get the color of a tile + * + * \param t tile to check + * + * \return WHITE (1) if tile is white, + * BLACK (-1) if tile is black, + * 0 if the tile is empty + */ +tile_t get_color(tile_t t) +{ + return (tile_t)get_sign(t); +} + /** * Calculate the absolute value of an index_t value *