From f7a3feaacdab2f198c665ee11ff14a63ac84718e Mon Sep 17 00:00:00 2001 From: Kai Stevenson Date: Wed, 7 Dec 2022 12:28:09 -0800 Subject: added check detection, ran into problem with pointer/array syntax as arguments --- chess.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- chesshelpers.c | 10 +++++++- chesshelpers.h | 1 + vector.c | 31 ++++++++++++++++++++++++ vector.h | 8 +++++++ 5 files changed, 122 insertions(+), 2 deletions(-) diff --git a/chess.c b/chess.c index 13145f9..c48315c 100644 --- a/chess.c +++ b/chess.c @@ -150,6 +150,7 @@ vectorp_t get_queen_moves(int board[8][8], vector_t position, int color) { } return init_vectorp(moves, moveCount); } +//this function returns moves that will place the player in check! vectorp_t get_moves(int board[8][8], vector_t position, piece_t piece) { int color = 0; if(piece > 6) { @@ -172,6 +173,74 @@ vectorp_t get_moves(int board[8][8], vector_t position, piece_t piece) { return get_queen_moves(board, position, color); } } +//array of arrays representing all the moves each piece of color can make +vectorpp_t get_all_moves(int board[8][8], int color) { + vectorp_t* allMoves = malloc(16 * sizeof(vectorp_t)); + int pieceCount = 0; + for(int r = 0; r < 8; r++) { + for(int c = 0; c < 8; c++) { + vector_t v = init_vector(c, r); + if(is_color(board, v, color)) { + allMoves[pieceCount] = get_moves(board, v, board[c][r]); + pieceCount++; + } + } + } + allMoves = realloc(allMoves, pieceCount * sizeof(vectorp_t)); + return init_vectorpp(allMoves, pieceCount); +} +//returns the position of color's king +vector_t get_king_position(int board[8][8], int color) { + for(int r = 0; r < 8; r++) { + for(int c = 0; c < 8; c++) { + if(board[c][r] == (king + color * 6)) { + return init_vector(c, r); + } + } + } +} +//returns true if the player of color is currently in check +int is_in_check(int board[8][8], int color) { + int returnV = 0; + vector_t kingPos = get_king_position(board, color); + //get all the moves for the opponent + vectorpp_t allMoves = get_all_moves(board, !color); + for(int i = 0; i < allMoves.length; i++) { + vectorp_t moves = allMoves.vectorps[i]; + for(int j = 0; j < moves.length; j++) { + if(moves.vectors[j].mx == kingPos.mx && moves.vectors[j].my == kingPos.my) { + returnV = 1; + } + } + free(moves.vectors); + } + free(allMoves.vectorps); + return returnV; +} +//this function removes ALL illegal moves +vectorp_t get_moves_final(int board[8][8], vector_t position, piece_t piece) { + int color = 0; + if(piece > 6) { + color = 1; + } + vectorp_t moves = get_moves(board, position, piece); + //try making that move, see if it puts the player in check + int* invalidMoves = malloc(moves.length * sizeof(int)); + int invalidMovesCount = 0; + for(int i = 0; i < moves.length; i++) { + int** tempBoard = clone_board(board); + board[moves.vectors[i].mx][moves.vectors[i].my] = piece; + if(is_in_check(tempBoard, color)) { + invalidMoves[invalidMovesCount]; + invalidMovesCount++; + } + free(tempBoard); + } + vectorp_t finalMoves = remove_vectors(moves, invalidMoves, invalidMovesCount); + free(invalidMoves); + free(moves.vectors); + return finalMoves; +} int main() { int board[8][8] = { { rook + 6, pawn + 6, 0, 0, 0, 0, pawn, rook }, @@ -189,6 +258,9 @@ int main() { clear_screen(); draw_board(board); printf(turn == 0 ? "\nWhite's turn\n" : "\nBlack's turn\n"); + if(is_in_check(board, turn)) { + printf("You're in check!\n"); + } printf("Enter the coordinates of the piece you want to move\n"); //get the selection for the piece to be moved vector_t selection = user_input_pos(); @@ -201,7 +273,7 @@ int main() { printf("Selected piece: "); printf("%d", selectedPiece); printf("\n"); - vectorp_t moves = get_moves(board, selection, selectedPiece); + vectorp_t moves = get_moves_final(board, selection, selectedPiece); if(moves.length == 0) { warn_user("That piece has no valid moves!"); continue; diff --git a/chesshelpers.c b/chesshelpers.c index ed2ad89..a0caadd 100644 --- a/chesshelpers.c +++ b/chesshelpers.c @@ -59,4 +59,12 @@ char* get_move_name(int board[8][8], vector_t origin, vector_t end) { return output; } } - +int** clone_board(int board[8][8]) { + int** newBoard = malloc(8 * 8 * sizeof(int)); + for(int r = 0; r < 8; r++) { + for(int c = 0; c < 8; c++) { + newBoard[c][r] = board[c][r]; + } + } + return newBoard; +} diff --git a/chesshelpers.h b/chesshelpers.h index 57a6440..0f1de34 100644 --- a/chesshelpers.h +++ b/chesshelpers.h @@ -14,4 +14,5 @@ int is_empty(int board[8][8], vector_t position); int is_color(int board[8][8], vector_t position, int color); char* get_readable_coords(vector_t position); char* get_move_name(int board[8][8], vector_t origin, vector_t end); +int** clone_board(int board[8][8]); #endif diff --git a/vector.c b/vector.c index b9d2fe4..61b0e81 100644 --- a/vector.c +++ b/vector.c @@ -1,3 +1,4 @@ +#include #include "vector.h" vector_t init_vector(int mx, int my) { vector_t vector; @@ -11,3 +12,33 @@ vectorp_t init_vectorp(vector_t* vectors, int length) { vectorP.length = length; return vectorP; } +vectorp_t remove_vector(vectorp_t vectorp, int index) { + vector_t* vectors = malloc((vectorp.length - 1) * sizeof(vector_t)); + for(int i = 0; i < vectorp.length - 1; i++) { + int correctedIndex = i > index ? i - 1 : i; + if(i != index) { + vectors[correctedIndex] = vectorp.vectors[i]; + } + } + return init_vectorp(vectors, vectorp.length - 1); +} +vectorp_t remove_vectors(vectorp_t vectorp, int* indexes, int indexCount) { + vector_t* vectors = malloc((vectorp.length - indexCount) * sizeof(vector_t)); + int correctedIndex = 0; + for(int i = 0; i < vectorp.length - 1; i++) { + for(int j = 0; j < indexCount; j++) { + if(i == indexes[j]) { + continue; + } + } + vectors[correctedIndex] = vectorp.vectors[i]; + correctedIndex++; + } + return init_vectorp(vectors, vectorp.length - 1); +} +vectorpp_t init_vectorpp(vectorp_t* vectorps, int length) { + vectorpp_t vectorPP; + vectorPP.vectorps = vectorps; + vectorPP.length = length; + return vectorPP; +} diff --git a/vector.h b/vector.h index 7289249..ea2ddcd 100644 --- a/vector.h +++ b/vector.h @@ -10,4 +10,12 @@ typedef struct VectorP { int length; } vectorp_t; vectorp_t init_vectorp(vector_t* vectors, int length); +//removes a vector from vectorp +vectorp_t remove_vector(vectorp_t vectorp, int index); +vectorp_t remove_vectors(vectorp_t vectorp, int* indexes, int indexCount); +typedef struct VectorPP { + vectorp_t* vectorps; + int length; +} vectorpp_t; +vectorpp_t init_vectorpp(vectorp_t* vectorps, int length); #endif -- cgit v1.3.1