Reformat code with help of utility functions
This commit is contained in:
@@ -11,8 +11,8 @@ typedef ptrdiff_t index_t;
|
|||||||
|
|
||||||
#define BOARD_SIZE ((index_t)(8 * 8))
|
#define BOARD_SIZE ((index_t)(8 * 8))
|
||||||
|
|
||||||
#define WHITE 1
|
#define WHITE ((tile_t)1)
|
||||||
#define BLACK -1
|
#define BLACK ((tile_t)-1)
|
||||||
|
|
||||||
#define E ((tile_t)0) ///< empty tile
|
#define E ((tile_t)0) ///< empty tile
|
||||||
#define K ((tile_t)1) ///< king
|
#define K ((tile_t)1) ///< king
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
int64_t get_sign(int64_t n);
|
||||||
bool tile_empty(tile_t t);
|
bool tile_empty(tile_t t);
|
||||||
index_t abs_index(index_t i);
|
index_t abs_index(index_t i);
|
||||||
index_t column(index_t i);
|
index_t column(index_t i);
|
||||||
index_t row(index_t i);
|
index_t row(index_t i);
|
||||||
tile_t abs_tile(tile_t t);
|
tile_t abs_tile(tile_t t);
|
||||||
|
tile_t get_color(tile_t t);
|
||||||
bool same_color(tile_t a, tile_t b);
|
bool same_color(tile_t a, tile_t b);
|
||||||
bool opposite_color(tile_t a, tile_t b);
|
bool opposite_color(tile_t a, tile_t b);
|
||||||
|
|||||||
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 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 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 knight_move_ok(index_t from, index_t to);
|
||||||
bool pawn_move_ok(const tile_t board[BOARD_SIZE],
|
bool pawn_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to);
|
||||||
index_t from,
|
|
||||||
index_t to,
|
|
||||||
int player);
|
|
||||||
bool queen_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);
|
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
|
* Check if move is a valid pawn move
|
||||||
*
|
*
|
||||||
* \param board Array of tiles representing chess board state
|
* \param board Array of tiles representing chess board state
|
||||||
* \param from Index of board piece starts at
|
* \param from Index of board piece starts at
|
||||||
* \param to Index of board piece wants to move to
|
* \param to Index of board piece wants to move to
|
||||||
* \param player Player to move
|
|
||||||
*
|
*
|
||||||
* \return true if move is valid, false otherwise
|
* \return true if move is valid, false otherwise
|
||||||
*/
|
*/
|
||||||
bool pawn_move_ok(const tile_t board[BOARD_SIZE],
|
bool pawn_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to)
|
||||||
index_t from,
|
|
||||||
index_t to,
|
|
||||||
int player)
|
|
||||||
{
|
{
|
||||||
const index_t diff = (to - from) * -player;
|
const index_t direction = -1 * get_color(board[from]),
|
||||||
|
diff = (to - from) * direction;
|
||||||
|
|
||||||
switch (diff) {
|
switch (diff) {
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case ROW: /* single move */
|
case ROW: /* single move */
|
||||||
return tile_empty(board[to]);
|
return tile_empty(board[to]);
|
||||||
|
|
||||||
case ROW - 1:
|
case ROW - COL: /* diagonal attack */
|
||||||
case ROW + 1: /* diagonal attack */
|
case ROW + COL:
|
||||||
return opposite_color(board[to], board[from]);
|
return opposite_color(board[to], board[from]);
|
||||||
|
|
||||||
case 2 * ROW: /* double move */
|
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);
|
&& (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)
|
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);
|
// clang-format off
|
||||||
const index_t row_diff = row(to) - row(from);
|
const index_t col_diff = column(to) - column(from),
|
||||||
|
row_diff = row(to) - row(from),
|
||||||
const index_t x_step = col_diff / abs_index(col_diff);
|
x = get_sign(col_diff),
|
||||||
const index_t y_step = ROW * row_diff / abs_index(row_diff);
|
y = get_sign(row_diff) * ROW,
|
||||||
const index_t step = x_step + y_step;
|
step = x + y;
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
if (abs_index(col_diff) != abs_index(row_diff))
|
if (abs_index(col_diff) != abs_index(row_diff))
|
||||||
return false;
|
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)
|
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 col_diff = column(to) - column(from),
|
||||||
const index_t row_diff = row(to - from);
|
row_diff = row(to - from);
|
||||||
|
|
||||||
if (row_diff > 0 && col_diff > 0)
|
if (row_diff > 0 && col_diff > 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
index_t step = row_diff ? ROW * row_diff / abs_index(row_diff) :
|
const index_t step =
|
||||||
col_diff / abs_index(col_diff);
|
row_diff ? ROW * get_sign(row_diff) : get_sign(col_diff);
|
||||||
|
|
||||||
for (index_t p = from + step; p != to; p += step)
|
for (index_t p = from + step; p != to; p += step)
|
||||||
if (! tile_empty(board[p]))
|
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)
|
bool knight_move_ok(index_t from, index_t to)
|
||||||
{
|
{
|
||||||
const index_t c = abs_index(column(to) - column(from));
|
const index_t x = abs_index(column(to) - column(from)),
|
||||||
const index_t r = abs_index(row(to - 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)
|
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_x = abs_index(column(to) - column(from)),
|
||||||
const index_t abs_row_diff = abs_index(row(to) - row(from));
|
abs_y = abs_index(row(to) - row(from));
|
||||||
|
|
||||||
|
// TODO: check if move causes check
|
||||||
(void)board;
|
(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)
|
return diagonal_move_ok(board, from, to)
|
||||||
|| cardinal_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 "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
|
* Calculate the absolute value of an index_t value
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user