reformat and refactor a bit
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
bool tile_empty(tile_t t);
|
bool tile_empty(tile_t t);
|
||||||
index_t abs_pos(index_t p);
|
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);
|
||||||
|
|||||||
41
src/chess.c
41
src/chess.c
@@ -5,30 +5,32 @@
|
|||||||
|
|
||||||
#include <ctype.h> /* isalpha, isdigit ... */
|
#include <ctype.h> /* isalpha, isdigit ... */
|
||||||
#include <locale.h> /* setlocale */
|
#include <locale.h> /* setlocale */
|
||||||
|
#include <stdint.h> /* uint64_t */
|
||||||
#include <stdio.h> /* printf, scanf */
|
#include <stdio.h> /* printf, scanf */
|
||||||
#include <string.h> /* memcpy */
|
#include <string.h> /* memcpy */
|
||||||
|
|
||||||
|
#define CLEAR_SCREEN() printf("\033[2J")
|
||||||
|
|
||||||
int do_turn(int turn_no, tile_t board[BOARD_SIZE]);
|
int do_turn(int turn_no, tile_t board[BOARD_SIZE]);
|
||||||
void init_board(tile_t board[BOARD_SIZE]);
|
void init_board(tile_t board[BOARD_SIZE]);
|
||||||
index_t input_to_index(char input[2]);
|
index_t input_to_index(char input[2]);
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
int turn = 0;
|
|
||||||
|
|
||||||
setlocale(LC_ALL, "C.UTF-8");
|
setlocale(LC_ALL, "C.UTF-8");
|
||||||
|
|
||||||
tile_t board[8 * 8] = { 0 };
|
tile_t board[BOARD_SIZE] = { 0 };
|
||||||
|
|
||||||
init_board(board);
|
init_board(board);
|
||||||
|
|
||||||
|
int turn = 0;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
printf("\033[2J"); // clear screen
|
CLEAR_SCREEN();
|
||||||
print_board(board);
|
print_board(board);
|
||||||
|
|
||||||
// turn increments on valid inputs,
|
// turn increments on valid inputs,
|
||||||
// otherwise refreshes screen
|
turn += do_turn(turn, board);
|
||||||
turn = do_turn(turn, board);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -59,7 +61,7 @@ void init_board(tile_t board[BOARD_SIZE])
|
|||||||
* \param turn_no Turn number
|
* \param turn_no Turn number
|
||||||
* \param board Pointer to list of tiles representing board state
|
* \param board Pointer to list of tiles representing board state
|
||||||
*
|
*
|
||||||
* \return turn+1 if successful, turn+0 if invalid input from player
|
* \return (int)1 if successful, (int)0 if invalid input from player
|
||||||
* */
|
* */
|
||||||
int do_turn(int turn_no, tile_t board[BOARD_SIZE])
|
int do_turn(int turn_no, tile_t board[BOARD_SIZE])
|
||||||
{
|
{
|
||||||
@@ -75,7 +77,7 @@ int do_turn(int turn_no, tile_t board[BOARD_SIZE])
|
|||||||
from = input_to_index(input);
|
from = input_to_index(input);
|
||||||
|
|
||||||
if (from == -1)
|
if (from == -1)
|
||||||
return turn_no;
|
return 0;
|
||||||
|
|
||||||
printf("\nto: ");
|
printf("\nto: ");
|
||||||
scanf(" %2s", input);
|
scanf(" %2s", input);
|
||||||
@@ -83,16 +85,16 @@ int do_turn(int turn_no, tile_t board[BOARD_SIZE])
|
|||||||
to = input_to_index(input);
|
to = input_to_index(input);
|
||||||
|
|
||||||
if (to == -1)
|
if (to == -1)
|
||||||
return turn_no;
|
return 0;
|
||||||
|
|
||||||
if (! move_ok(board, from, to, turn_no % 2 ? BLACK : WHITE))
|
if (! move_ok(board, from, to, turn_no % 2 ? BLACK : WHITE))
|
||||||
return turn_no;
|
return 0;
|
||||||
|
|
||||||
board[to] = board[from];
|
board[to] = board[from];
|
||||||
board[from] = E;
|
board[from] = E;
|
||||||
|
|
||||||
/* increment to make it next turn */
|
/* increment to make it next turn */
|
||||||
return turn_no+1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -100,21 +102,22 @@ int do_turn(int turn_no, tile_t board[BOARD_SIZE])
|
|||||||
*
|
*
|
||||||
* \param input string of length 2 representing tile, e.g. "A3"
|
* \param input string of length 2 representing tile, e.g. "A3"
|
||||||
*
|
*
|
||||||
|
* \return index value on valid input, -1 on invalid input
|
||||||
|
*
|
||||||
* */
|
* */
|
||||||
index_t input_to_index(char input[2])
|
index_t input_to_index(char input[2])
|
||||||
{
|
{
|
||||||
int x = -1, y = -1, c;
|
int x = -1, y = -1;
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
c = input[i];
|
const char c = input[i];
|
||||||
|
|
||||||
if (isalpha(c))
|
const char v = isalpha(c) ? toupper(c) : c;
|
||||||
c = toupper(input[0]);
|
|
||||||
|
|
||||||
if ('A' <= c && c <= 'H')
|
if ('A' <= v && v <= 'H')
|
||||||
x = c - 'A';
|
x = v - 'A';
|
||||||
else if ('1' <= c && c <= '8')
|
else if ('1' <= v && v <= '8')
|
||||||
y = c - '1';
|
y = v - '1';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x != -1 && y != -1)
|
if (x != -1 && y != -1)
|
||||||
|
|||||||
79
src/pieces.c
79
src/pieces.c
@@ -2,31 +2,27 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
bool
|
bool bishop_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to);
|
||||||
bishop_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
|
bool diagonal_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to);
|
||||||
cardinal_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
|
bool knight_move_ok(index_t from, index_t to);
|
||||||
diagonal_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to);
|
bool pawn_move_ok(const tile_t board[BOARD_SIZE],
|
||||||
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 from,
|
||||||
index_t to,
|
index_t to,
|
||||||
int player);
|
int player);
|
||||||
bool
|
bool queen_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to);
|
||||||
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);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true 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
|
* \param player Player to move
|
||||||
|
*
|
||||||
|
* \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 from,
|
||||||
@@ -53,22 +49,24 @@ bool pawn_move_ok(const tile_t board[BOARD_SIZE],
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if `to` is on a diagonal line of `from`, false otherwise
|
* Check if `to` is on a diagonal line of `from`
|
||||||
*
|
*
|
||||||
* \param board Array of tiles representing chess board state
|
* \param board Array of tiles representing chess board state
|
||||||
* \param from Index of board piece is at
|
* \param from Index of board piece is at
|
||||||
* \param to Index of board piece tries to move to
|
* \param to Index of board piece tries to move to
|
||||||
|
*
|
||||||
|
* \return true if \p to is on a diagonal line of \p from
|
||||||
*/
|
*/
|
||||||
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);
|
const index_t col_diff = column(to) - column(from);
|
||||||
const index_t row_diff = row(to) - row(from);
|
const index_t row_diff = row(to) - row(from);
|
||||||
|
|
||||||
const index_t x_step = col_diff / abs_pos(col_diff);
|
const index_t x_step = col_diff / abs_index(col_diff);
|
||||||
const index_t y_step = ROW * row_diff / abs_pos(row_diff);
|
const index_t y_step = ROW * row_diff / abs_index(row_diff);
|
||||||
const index_t step = x_step + y_step;
|
const index_t step = x_step + y_step;
|
||||||
|
|
||||||
if (abs_pos(col_diff) != abs_pos(row_diff))
|
if (abs_index(col_diff) != abs_index(row_diff))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (index_t p = from + step; p != to; p += step)
|
for (index_t p = from + step; p != to; p += step)
|
||||||
@@ -79,23 +77,24 @@ bool diagonal_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if index `to` is on a cardinal line of `from`, false otherwise
|
* Check if index `to` is on a cardinal line of `from`
|
||||||
*
|
*
|
||||||
* \param board Array of tiles representing chess board state
|
* \param board Array of tiles representing chess board state
|
||||||
* \param from Index of board piece is at
|
* \param from Index of board piece is at
|
||||||
* \param to Index of board piece tries to move to
|
* \param to Index of board piece tries to move to
|
||||||
|
*
|
||||||
|
* \return true if \p to and \p from share a column or row
|
||||||
*/
|
*/
|
||||||
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) - row(from);
|
const index_t row_diff = row(to - from);
|
||||||
|
|
||||||
/* cardinal moves means one direction has to be zero */
|
|
||||||
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_pos(row_diff) :
|
index_t step = row_diff ? ROW * row_diff / abs_index(row_diff) :
|
||||||
col_diff / abs_pos(col_diff);
|
col_diff / abs_index(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]))
|
||||||
@@ -105,11 +104,13 @@ bool cardinal_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if move is a valid bishop move
|
* Check if move is a valid bishop 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 is at
|
* \param from Index of board piece is at
|
||||||
* \param to Index of board piece tries to move to
|
* \param to Index of board piece tries to move to
|
||||||
|
*
|
||||||
|
* \return true if move is valid, false otherwise
|
||||||
*/
|
*/
|
||||||
bool bishop_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to)
|
bool bishop_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to)
|
||||||
{
|
{
|
||||||
@@ -117,11 +118,13 @@ bool bishop_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if move is a valid rook move
|
* Check if move is a valid rook 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 is at
|
* \param from Index of board piece is at
|
||||||
* \param to Index of board piece tries to move to
|
* \param to Index of board piece tries to move to
|
||||||
|
*
|
||||||
|
* \return true if move is valid, false otherwise
|
||||||
*/
|
*/
|
||||||
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)
|
||||||
{
|
{
|
||||||
@@ -129,30 +132,34 @@ bool rook_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if move is a valid knight move
|
* Check if move is a valid knight move
|
||||||
*
|
*
|
||||||
* \param from Index of board piece is at
|
* \param from Index of board piece is at
|
||||||
* \param to Index of board piece tries to move to
|
* \param to Index of board piece tries to move to
|
||||||
|
*
|
||||||
|
* \return true if move is valid, false otherwise
|
||||||
*/
|
*/
|
||||||
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_pos(column(to) - column(from));
|
const index_t c = abs_index(column(to) - column(from));
|
||||||
const index_t r = abs_pos(row(to - from));
|
const index_t r = abs_index(row(to - from));
|
||||||
|
|
||||||
return (c == 1 && r == 2) || (c == 2 && r == 1);
|
return (c == 1 && r == 2) || (c == 2 && r == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if move is a valid king move
|
* Check if move is a valid king 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 is at
|
* \param from Index of board piece is at
|
||||||
* \param to Index of board piece tries to move to
|
* \param to Index of board piece tries to move to
|
||||||
|
*
|
||||||
|
* \return true if move is valid, false otherwise
|
||||||
*/
|
*/
|
||||||
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_pos(column(to) - column(from));
|
const index_t abs_col_diff = abs_index(column(to) - column(from));
|
||||||
const index_t abs_row_diff = abs_pos(row(to) - row(from));
|
const index_t abs_row_diff = abs_index(row(to) - row(from));
|
||||||
|
|
||||||
(void)board;
|
(void)board;
|
||||||
|
|
||||||
@@ -160,11 +167,13 @@ bool king_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if move is a valid queen move
|
* Check if move is a valid queen 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 is at
|
* \param from Index of board piece is at
|
||||||
* \param to Index of board piece tries to move to
|
* \param to Index of board piece tries to move to
|
||||||
|
*
|
||||||
|
* \return true if move is valid, false otherwise
|
||||||
*/
|
*/
|
||||||
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)
|
||||||
{
|
{
|
||||||
@@ -173,12 +182,14 @@ bool queen_move_ok(const tile_t board[BOARD_SIZE], index_t from, index_t to)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if a move is valid, false otherwise
|
* Check if a move is valid
|
||||||
*
|
*
|
||||||
* \param board Pointer to list of tiles representing board state
|
* \param board Pointer to list of tiles representing board state
|
||||||
* \param from Tile to move piece from
|
* \param from Tile to move piece from
|
||||||
* \param to Tile to move piece to
|
* \param to Tile to move piece to
|
||||||
* \param player The current player to move
|
* \param player The current player to move
|
||||||
|
*
|
||||||
|
* \return true if move is valid, false otherwise
|
||||||
* */
|
* */
|
||||||
bool move_ok(const tile_t board[BOARD_SIZE],
|
bool move_ok(const tile_t board[BOARD_SIZE],
|
||||||
index_t from,
|
index_t from,
|
||||||
|
|||||||
36
src/util.c
36
src/util.c
@@ -2,22 +2,26 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the absolute value of an index_t value
|
* Calculate the absolute value of an index_t value
|
||||||
*
|
*
|
||||||
* \param p positive or negative index_t
|
* \param p positive or negative index_t
|
||||||
|
*
|
||||||
|
* \return the absolute value of p
|
||||||
*/
|
*/
|
||||||
index_t abs_pos(index_t p)
|
index_t abs_index(index_t i)
|
||||||
{
|
{
|
||||||
if (p < 0)
|
if (i < 0)
|
||||||
return -1 * p;
|
return -1 * i;
|
||||||
|
|
||||||
return p;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the absolute value of a tile_t value
|
* Calculate the absolute value of a tile_t value
|
||||||
*
|
*
|
||||||
* \param t positive or negative tile_t
|
* \param t positive or negative tile_t
|
||||||
|
*
|
||||||
|
* \return the absolute value of t
|
||||||
* */
|
* */
|
||||||
tile_t abs_tile(tile_t t)
|
tile_t abs_tile(tile_t t)
|
||||||
{
|
{
|
||||||
@@ -28,9 +32,11 @@ tile_t abs_tile(tile_t t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if tile is empty, false otherwise
|
* Check if tile is has no piece on it
|
||||||
*
|
*
|
||||||
* \param t tile to check if empty
|
* \param t tile to check if empty
|
||||||
|
*
|
||||||
|
* \return true if tile is empty, false otherwise
|
||||||
* */
|
* */
|
||||||
bool tile_empty(tile_t t)
|
bool tile_empty(tile_t t)
|
||||||
{
|
{
|
||||||
@@ -38,9 +44,11 @@ bool tile_empty(tile_t t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns row number of 1D board index
|
* Get row of index
|
||||||
*
|
*
|
||||||
* \param i index to get row number of
|
* \param i index to get row number of
|
||||||
|
*
|
||||||
|
* \return row number of i
|
||||||
* */
|
* */
|
||||||
index_t row(index_t i)
|
index_t row(index_t i)
|
||||||
{
|
{
|
||||||
@@ -48,9 +56,11 @@ index_t row(index_t i)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns column number of board index
|
* Get column of index
|
||||||
*
|
*
|
||||||
* \param i index to get column number of
|
* \param i index to get column number of
|
||||||
|
*
|
||||||
|
* \return column number of i
|
||||||
* */
|
* */
|
||||||
index_t column(index_t i)
|
index_t column(index_t i)
|
||||||
{
|
{
|
||||||
@@ -58,10 +68,12 @@ index_t column(index_t i)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if a and b are tiles of opposite color, false otherwise
|
* Check if two tiles have pieces of the opposite color
|
||||||
*
|
*
|
||||||
* \param a Tile to compare
|
* \param a Tile to compare
|
||||||
* \param b Tile to compare it with
|
* \param b Tile to compare it with
|
||||||
|
*
|
||||||
|
* \return true if a and b are opposite colors, false otherwise
|
||||||
* */
|
* */
|
||||||
bool opposite_color(tile_t a, tile_t b)
|
bool opposite_color(tile_t a, tile_t b)
|
||||||
{
|
{
|
||||||
@@ -69,10 +81,12 @@ bool opposite_color(tile_t a, tile_t b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if a and b are pieces of the same color, false otherwise
|
* Check if two tiles have pieces of the same color
|
||||||
*
|
*
|
||||||
* \param a Tile to compare
|
* \param a Tile to compare
|
||||||
* \param b Tile to compare it with
|
* \param b Tile to compare it with
|
||||||
|
*
|
||||||
|
* \return true if a and b are opposite colors, false otherwise
|
||||||
* */
|
* */
|
||||||
bool same_color(tile_t a, tile_t b)
|
bool same_color(tile_t a, tile_t b)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user