Reformat code with help of utility functions

This commit is contained in:
Ole Morud
2023-03-26 19:14:59 +02:00
committed by Ole Morud
parent 44c2ae5290
commit 4155ed3e87
4 changed files with 120 additions and 84 deletions

View File

@@ -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;
}

View File

@@ -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
*