#include #include #include #include "vector.h" #include "chesshelpers.h" board_t init_board(int** pieces) { board_t board; board.pieces = pieces; board.whiteCanCastleKingside = 1; board.whiteCanCastleQueenside = 1; board.blackCanCastleKingside = 1; board.blackCanCastleQueenside = 1; board.lastPawnMove = -1; return board; } //function applies side effects to board values like king move state board_t make_move(board_t board, vector_t origin, vector_t end) { int piece = board.pieces[origin.mx][origin.my]; board.pieces[origin.mx][origin.my] = 0; board.pieces[end.mx][end.my] = piece; //white king moved if(piece == king) { board.whiteCanCastleQueenside = 0; board.whiteCanCastleKingside = 0; //if the king moved farther than it normally could, move must have been castling. move the rook as well if(origin.mx == 4 && end.mx == 6) { board = make_move(board, init_vector(7, 7), init_vector(5, 7)); } else if(origin.mx == 4 && end.mx == 2) { board = make_move(board, init_vector(0, 7), init_vector(3, 7)); } } //white kingside rook moved else if(origin.mx == 7 && origin.my == 7) { board.whiteCanCastleKingside = 0; } //white queenside rook moved else if(origin.mx == 0 && origin.my == 7) { board.whiteCanCastleQueenside = 0; } //black king moved else if(piece == king + 6) { board.blackCanCastleQueenside = 0; board.blackCanCastleKingside = 0; //if the king moved farther than it normally could, move must have been castling. move the rook as well if(origin.mx == 4 && end.mx == 6) { board = make_move(board, init_vector(7, 0), init_vector(5, 0)); } else if(origin.mx == 4 && end.mx == 2) { board = make_move(board, init_vector(0, 0), init_vector(3, 0)); } } //black kingside rook moved else if(origin.mx == 7 && origin.my == 0) { board.blackCanCastleKingside = 0; } //black queenside rook moved else if(origin.mx == 0 && origin.my == 0) { board.blackCanCastleQueenside = 0; } //this is not an else if! lastPawnMove must be reset if(piece == pawn || piece == pawn + 6) { board.lastPawnMove = origin.mx; } else { //en passant no longer possible board.lastPawnMove = -1; } return board; } board_t clone_board(board_t board) { board_t newBoard = board; int** pieces = malloc(8 * sizeof(int*)); for(int r = 0; r < 8; r++) { pieces[r] = malloc(8 * sizeof(int)); for(int c = 0; c < 8; c++) { pieces[r][c] = board.pieces[r][c]; } } newBoard.pieces = pieces; return newBoard; } int in_board(vector_t position) { return position.mx < 8 && position.mx >= 0 && position.my < 8 && position.my >= 0; } int is_empty(board_t board, vector_t position) { return board.pieces[position.mx][position.my] == 0; } int is_color(board_t board, vector_t position, int color) { if(color == 0) { return board.pieces[position.mx][position.my] >= 1 && board.pieces[position.mx][position.my] <= 6; } else { return board.pieces[position.mx][position.my] >= 7; } } //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[1] = '8' - position.my; output[2] = '\0'; return output; } //gets the proper algebraic notation for the move char* get_move_name(board_t board, vector_t origin, vector_t end) { int piece = board.pieces[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.pieces[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.pieces[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; } }