diff options
| author | Kai Stevenson <kai@kaistevenson.com> | 2023-03-19 23:20:53 -0700 |
|---|---|---|
| committer | Kai Stevenson <kai@kaistevenson.com> | 2023-03-19 23:20:53 -0700 |
| commit | e33dc4755fb08ed08f30b5e1af65457556d5bcb7 (patch) | |
| tree | c075e9c4f076a7772eb5c0665fbd137e2fd6c3ab /src/chesshelpers.c | |
| parent | 26321477ae47bbf5d89b651842d8295e9ea9ea5d (diff) | |
fscomch--communication between multiple chess processes
Diffstat (limited to 'src/chesshelpers.c')
| -rw-r--r-- | src/chesshelpers.c | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/src/chesshelpers.c b/src/chesshelpers.c new file mode 100644 index 0000000..b64a0f4 --- /dev/null +++ b/src/chesshelpers.c @@ -0,0 +1,154 @@ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#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]; + int captured = board.pieces[end.mx][end.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; + //check if move was an en passant capture + if(captured == 0 && origin.mx != end.mx) { + //kill the enemy pawn + board.pieces[end.mx][origin.my] = 0; + } + } + 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; + } +} +//returns true if a pawn that moved two squares would have been here if it moved one square +int would_have_been_pawn(board_t board, vector_t position, int color) { + if(board.lastPawnMove == position.mx) { + if((position.my == 6 && color == 0) || (position.my == 2 && color == 1)) { + return 1; + } + } + return 0; +} +//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; + } +} |
