From e8e00b9eb6e3979dd1066fc3a73f39565e8ec9cf Mon Sep 17 00:00:00 2001 From: Kai Stevenson Date: Tue, 6 Dec 2022 13:59:46 -0800 Subject: added rook and queen moves, added board color, changed board spacing, improved move naming --- chess.c | 168 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 145 insertions(+), 23 deletions(-) diff --git a/chess.c b/chess.c index 3657f63..7464497 100644 --- a/chess.c +++ b/chess.c @@ -1,5 +1,15 @@ #include #include +#include + +#define ANSI_COLOR_RED "\x1b[31m" +#define ANSI_COLOR_GREEN "\x1b[32m" +#define ANSI_COLOR_YELLOW "\x1b[33m" +#define ANSI_COLOR_BLUE "\x1b[34m" +#define ANSI_COLOR_MAGENTA "\x1b[35m" +#define ANSI_COLOR_CYAN "\x1b[36m" +#define ANSI_COLOR_RESET "\x1b[0m" + typedef enum { pawn = 1, knight = 2, @@ -29,65 +39,66 @@ vectorp_t init_vectorp(vector_t* vectors, int length) { return vectorP; } void draw_board(int board[8][8]) { - printf(" ABCDEFGH\n"); + printf(" A B C D E F G H\n"); + int tileColor = 1; for(int r = 0; r < 8; r++) { - char* line = calloc(10, sizeof(char)); + tileColor = !tileColor; + char* line = calloc(2 + (8 * 10), sizeof(char)); line[0] = '8' - r; line[1] = ' '; for(int c = 0; c < 8; c++) { + tileColor = !tileColor; + strcat(line, tileColor == 0 ? ANSI_COLOR_RED : ANSI_COLOR_RESET); if(board[c][r] <= 6) { switch(board[c][r]) { case 0: - line[c + 2] = ' '; + strcat(line, "# "); break; case pawn: - line[c + 2] = 'P'; + strcat(line, "P "); break; case knight: - line[c + 2] = 'N'; + strcat(line, "N "); break; case bishop: - line[c + 2] = 'B'; + strcat(line, "B "); break; case rook: - line[c + 2] = 'R'; + strcat(line, "R "); break; case queen: - line[c + 2] = 'Q'; + strcat(line, "Q "); break; case king: - line[c + 2] = 'K'; + strcat(line, "K "); break; } } else { switch(board[c][r] - 6) { - case 0: - line[c + 2] = ' '; - break; case pawn: - line[c + 2] = 'p'; + strcat(line, "p "); break; case knight: - line[c + 2] = 'n'; + strcat(line, "n "); break; case bishop: - line[c + 2] = 'b'; + strcat(line, "b "); break; case rook: - line[c + 2] = 'r'; + strcat(line, "r "); break; case queen: - line[c + 2] = 'q'; + strcat(line, "q "); break; case king: - line[c + 2] = 'k'; + strcat(line, "k "); break; } } } printf(line); - printf("\n"); + printf("\n" ANSI_COLOR_RESET); free(line); } } @@ -105,7 +116,6 @@ int is_color(int board[8][8], vector_t position, int color) { return board[position.mx][position.my] >= 7; } } -//0 is white, 1 is black vectorp_t get_pawn_moves(int board[8][8], vector_t position, int color) { vector_t* moves = malloc(6 * sizeof(vector_t)); int moveCount = 0; @@ -149,7 +159,7 @@ vectorp_t get_knight_moves(int board[8][8], vector_t position, int color) { return init_vectorp(moves, moveCount); } vectorp_t get_bishop_moves(int board[8][8], vector_t position, int color) { - vector_t* moves = malloc(13 * sizeof(vector_t)); + vector_t* moves = malloc(14 * sizeof(vector_t)); int moveCount = 0; for(int i = 0; i < 4; i++) { int h = i < 2 ? 1 : -1; @@ -179,6 +189,78 @@ vectorp_t get_bishop_moves(int board[8][8], vector_t position, int color) { } return init_vectorp(moves, moveCount); } +vectorp_t get_rook_moves(int board[8][8], vector_t position, int color) { + vector_t* moves = malloc(14 * sizeof(vector_t)); + int moveCount = 0; + for(int i = 0; i < 4; i++) { + int h = (i == 0 || i == 2) ? 0 : i == 1 ? 1 : -1; + int v = (i == 1 || i == 3) ? 0 : i == 2 ? 1 : -1; + vector_t checkPos = init_vector(position.mx, position.my); + for(int d = 0; d < 7; d++) { + checkPos.mx += h; + checkPos.my += v; + if(in_board(checkPos)) { + if(is_empty(board, checkPos)) { + moves[moveCount] = init_vector(checkPos.mx, checkPos.my); + moveCount++; + } + else if(is_color(board, checkPos, !color)) { + moves[moveCount] = init_vector(checkPos.mx, checkPos.my); + moveCount++; + break; + } + else { + break; + } + } + else { + break; + } + } + } + return init_vectorp(moves, moveCount); +} +vectorp_t get_queen_moves(int board[8][8], vector_t position, int color) { + vector_t* moves = malloc(28 * sizeof(vector_t)); + int moveCount = 0; + for(int i = 0; i < 8; i++) { + int h; + int v; + //diagonal moves + if(i < 4) { + h = i < 2 ? 1 : -1; + v = (i == 0 || i == 2) ? 1 : -1; + } + //straight moves + else { + h = (i == 4 || i == 6) ? 0 : i == 5 ? 1 : -1; + v = (i == 5 || i == 7) ? 0 : i == 6 ? 1 : -1; + } + vector_t checkPos = init_vector(position.mx, position.my); + for(int d = 0; d < 7; d++) { + checkPos.mx += h; + checkPos.my += v; + if(in_board(checkPos)) { + if(is_empty(board, checkPos)) { + moves[moveCount] = init_vector(checkPos.mx, checkPos.my); + moveCount++; + } + else if(is_color(board, checkPos, !color)) { + moves[moveCount] = init_vector(checkPos.mx, checkPos.my); + moveCount++; + break; + } + else { + break; + } + } + else { + break; + } + } + } + return init_vectorp(moves, moveCount); +} vectorp_t get_moves(int board[8][8], vector_t position, piece_t piece) { int color = 0; if(piece > 6) { @@ -194,6 +276,12 @@ vectorp_t get_moves(int board[8][8], vector_t position, piece_t piece) { else if(piece == bishop) { return get_bishop_moves(board, position, color); } + else if(piece == rook) { + return get_rook_moves(board, position, color); + } + else if(piece == queen) { + return get_queen_moves(board, position, color); + } } vector_t user_input_pos() { char* inputString = malloc(3 * sizeof(char)); @@ -220,11 +308,45 @@ vector_t user_input_pos() { //converts board coordinates into algebraic notation char* get_readable_coords(vector_t position) { char* output = malloc(3 * sizeof(char)); - output[0] = 'A' + position.mx; + output[0] = 'a' + position.mx; output[1] = '8' - position.my; output[2] = '\0'; return output; } +//gets the proper algebraic notation for the move +char* get_move_name(int board[8][8], vector_t origin, vector_t end) { + int piece = board[origin.mx][origin.my]; + if(piece > 6) { + piece -= 6; + } + if(piece != 1) { + char cPiece = piece == pawn ? 'P' : piece == knight ? 'N' : piece == bishop ? 'B' : piece == rook ? 'R' : piece == queen ? 'Q' : 'K'; + int isCapture = board[end.mx][end.my] != 0; + char* output = calloc(isCapture ? 5 : 4, sizeof(char)); + output[0] = cPiece; + if(isCapture) { + output[1] = 'x'; + } + char* rEnd = get_readable_coords(end); + strcat(output, rEnd); + free(rEnd); + output[isCapture ? 4 : 3] = '\0'; + return output; + } + else { + int isCapture = board[end.mx][end.my] != 0; + char* output = calloc(isCapture ? 5 : 3, sizeof(char)); + if(isCapture) { + output[0] = 'a' + origin.mx; + output[1] = 'x'; + } + char* rEnd = get_readable_coords(end); + strcat(output, rEnd); + free(rEnd); + output[isCapture ? 4 : 2] = '\0'; + return output; + } +} void clear_screen() { system("@cls||clear"); } @@ -273,7 +395,7 @@ int main() { printf("Valid moves: "); //write all the valid moves for(int i = 0; i < moves.length; i++) { - char* readable_coords = get_readable_coords(moves.vectors[i]); + char* readable_coords = get_move_name(board, selection, moves.vectors[i]); printf(readable_coords); free(readable_coords); printf("; "); -- cgit v1.3.1