190 lines
5.1 KiB
C
190 lines
5.1 KiB
C
#ifndef CHESS_H
|
|
#define CHESS_H
|
|
|
|
/* the "board" is the playable area on which
|
|
* pieces move. pieces are represented by numbers:
|
|
* 0 - no piece
|
|
* 1 - pawn
|
|
* 2 - rook
|
|
* 3 - knight
|
|
* 4 - bishop
|
|
* 5 - queen
|
|
* 6 - king
|
|
*/
|
|
|
|
#include <stdbool.h>
|
|
|
|
// board size constraints
|
|
#define BOARD_HORIZONTAL 8
|
|
#define BOARD_VERTICAL 8
|
|
|
|
// type abstractions
|
|
typedef enum { WHITE, BLACK } player_e;
|
|
|
|
typedef int board_t[BOARD_VERTICAL][BOARD_HORIZONTAL];
|
|
|
|
#define PIECE_COUNT 13 // how many unique pieces are there
|
|
#define MAX_PIECE_MOVE_COUNT 27 // the max possible num of options where to move in one moment
|
|
typedef enum {
|
|
NONE,
|
|
|
|
WPAWN,
|
|
WROOK,
|
|
WKNIGHT,
|
|
WBISHOP,
|
|
WQUEEN,
|
|
WKING,
|
|
|
|
BPAWN,
|
|
BROOK,
|
|
BKNIGHT,
|
|
BBISHOP,
|
|
BQUEEN,
|
|
BKING
|
|
} piece_e;
|
|
|
|
typedef struct {
|
|
int x;
|
|
int y;
|
|
} pos_t;
|
|
|
|
typedef struct {
|
|
// what
|
|
// where from
|
|
// where to
|
|
piece_e piece;
|
|
pos_t from;
|
|
pos_t to;
|
|
} move_t;
|
|
|
|
// the default arrangment of pieces on the board
|
|
// negative numbers are black, positive ones white
|
|
#define BOARD_DEFAULT_CONFIG \
|
|
(board_t){\
|
|
{ BROOK, BKNIGHT, BBISHOP, BQUEEN, BKING, BBISHOP, BKNIGHT, BROOK },\
|
|
{ BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN, BPAWN },\
|
|
{ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE },\
|
|
{ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE },\
|
|
{ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE },\
|
|
{ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE },\
|
|
{ WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN, WPAWN },\
|
|
{ WROOK, WKNIGHT, WBISHOP, WQUEEN, WKING, WBISHOP, WKNIGHT, WROOK }\
|
|
}
|
|
|
|
typedef struct {
|
|
piece_e piece;
|
|
pos_t options[MAX_PIECE_MOVE_COUNT];
|
|
unsigned int piece_move_count;
|
|
} valid_move_t;
|
|
|
|
/** FIXED: ALSO DEPENDS ON THE STATE OF THE GAME -
|
|
* e.g. a pawn cannot move two places in the middle
|
|
* of the game but can in the first round
|
|
* => ASSUME NO OTHER PIECES - then ALWAYS CHECK
|
|
* FOR PIECE COLLISIONS and FOR ROUND COUNT
|
|
* (pawn 1 || 2 move)
|
|
*/
|
|
|
|
/** MAYBE: consider the POV from both sides???!!! */
|
|
/**
|
|
* the NONE, PAWN, KNIGHT and KING pieces' relative_moves are
|
|
* treated like specific coordinates relative to their
|
|
* position,
|
|
* whereas the BISHOP, ROOK and QUEEN pieces' 'moves'
|
|
* are treated as *directions* in which they can move rather than
|
|
* absolute x,y values -> e.g. the rook can move
|
|
* up, down, left, right * n -> and then bounds & edge cases are checked
|
|
*/
|
|
#define DEFAULT_VALID_MOVES (valid_move_t[PIECE_COUNT]){\
|
|
{NONE, {}, 0},\
|
|
\
|
|
{WPAWN, {\
|
|
{ 0, -1}, {-1, -1}, {+1, -1}, { 0, -2}\
|
|
}, 4},\
|
|
{WROOK, {\
|
|
{ 0, -1}, { 0, +1}, {-1, 0}, {+1, 0}\
|
|
}, 4},\
|
|
{WKNIGHT, {\
|
|
{-1, -2}, {+1, -2}, {-2, -1}, {-2, +1},\
|
|
{+2, -1}, {+2, +1}, {-1, -2}, {-1, +2}\
|
|
}, 8},\
|
|
{WBISHOP, {\
|
|
{-1, -1}, {-1, +1}, {+1, -1}, {+1, +1}\
|
|
}, 4},\
|
|
{WQUEEN, {\
|
|
{0, -1}, {0, +1}, {-1, 0}, {+1, 0},\
|
|
{-1, -1}, {-1, +1}, {+1, -1}, {+1, +1}\
|
|
}, 8},\
|
|
{WKING, {\
|
|
{ 0, -1}, { 0, +1}, {-1, 0}, {+1, 0},\
|
|
{-1, -1}, {-1, +1}, {+1, -1}, {+1, +1}\
|
|
}, 8},\
|
|
\
|
|
{BPAWN, {\
|
|
{ 0, -1}, {-1, -1}, {+1, -1}, { 0, -2}\
|
|
}, 4},\
|
|
{BROOK, {\
|
|
{ 0, -1}, { 0, +1}, {-1, 0}, {+1, 0}\
|
|
}, 4},\
|
|
{BKNIGHT, {\
|
|
{-1, -2}, {+1, -2}, {-2, -1}, {-2, +1},\
|
|
{+2, -1}, {+2, +1}, {-1, -2}, {-1, +2}\
|
|
}, 8},\
|
|
{BBISHOP, {\
|
|
{-1, -1}, {-1, +1}, {+1, -1}, {+1, +1}\
|
|
}, 4},\
|
|
{BQUEEN, {\
|
|
{0, -1}, {0, +1}, {-1, 0}, {+1, 0},\
|
|
{-1, -1}, {-1, +1}, {+1, -1}, {+1, +1}\
|
|
}, 8},\
|
|
{BKING, {\
|
|
{ 0, -1}, { 0, +1}, {-1, 0}, {+1, 0},\
|
|
{-1, -1}, {-1, +1}, {+1, -1}, {+1, +1}\
|
|
}, 8}\
|
|
}
|
|
|
|
/**
|
|
* states in which the game can end
|
|
* CONTINUE => the game does not end, it continues
|
|
* CHECKMATE => one side wins
|
|
* STALEMATE => it's a draw
|
|
*/
|
|
typedef enum {
|
|
CONTINUE,
|
|
CHECKMATE,
|
|
STALEMATE
|
|
} end_condition_e;
|
|
|
|
/**
|
|
* a tracker for which pieces have been captured by who
|
|
* white contains opponent pieces WHITE have been captured by them
|
|
* black contains opponent pieces BLACK have been captured by them
|
|
*/
|
|
#define PIECE_COUNT_CAPTURABLE_PER_PLAYER 15 // 2*8 - 1
|
|
typedef struct {
|
|
piece_e white[PIECE_COUNT_CAPTURABLE_PER_PLAYER];
|
|
unsigned int white_n;
|
|
piece_e black[PIECE_COUNT_CAPTURABLE_PER_PLAYER];
|
|
unsigned int black_n;
|
|
} captured_t;
|
|
|
|
// initializes the board with the default configuration of pieces
|
|
void init_board(board_t *board);
|
|
|
|
// selects the player to currently play
|
|
// if it is the first round, it selects white
|
|
void select_player(player_e *player, unsigned int round_count);
|
|
|
|
// listens for a command to make a move by the currently playing player
|
|
bool get_move(move_t *move);
|
|
|
|
// performs the move if is it possible
|
|
end_condition_e perform_move(board_t *board, player_e player, captured_t *captured, move_t move);
|
|
|
|
// if there is one of the mates, end the game and show who has won
|
|
void announce_results(end_condition_e end_condition, player_e player);
|
|
|
|
// shows a guide to help players understand the move prompt system
|
|
void show_help();
|
|
|
|
#endif // CHESS_H
|