Reformat code with help of utility functions
This commit is contained in:
162
src/pieces.c
162
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;
|
||||
}
|
||||
|
||||
36
src/util.c
36
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
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user