diff options
Diffstat (limited to 'chess.c')
| -rw-r--r-- | chess.c | 418 |
1 files changed, 0 insertions, 418 deletions
diff --git a/chess.c b/chess.c deleted file mode 100644 index f5881fe..0000000 --- a/chess.c +++ /dev/null @@ -1,418 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "vector.h" -#include "console.h" -#include "chesshelpers.h" -#include "chess.h" - -int main(int argc, char **argv) { - if(argc == 2) { - if(strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0) { - printf("Version 1.0.0\n"); - exit(0); - } - } - //set up the board - int boardA[8][8] = { - { rook + 6, pawn + 6, 0, 0, 0, 0, pawn, rook }, - { knight + 6, pawn + 6, 0, 0, 0, 0, pawn, knight }, - { bishop + 6, pawn + 6, 0, 0, 0, 0, pawn, bishop }, - { queen + 6, pawn + 6, 0, 0, 0, 0, pawn, queen }, - { king + 6, pawn + 6, 0, 0, 0, 0, pawn, king }, - { bishop + 6, pawn + 6, 0, 0, 0, 0, pawn, bishop }, - { knight + 6, pawn + 6, 0, 0, 0, 0, pawn, knight }, - { rook + 6, pawn + 6, 0, 0, 0, 0, pawn, rook } - }; - //convert the array to pointers - 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] = boardA[r][c]; - } - } - board_t board = init_board(pieces); - int turn = 0; - while(1) { - //draw the board, write some info - clear_screen(); - draw_board(board.pieces); - printf(turn == 0 ? "\nWhite's turn\n" : "\nBlack's turn\n"); - if(is_in_check(board, turn)) { - vectorpp_t allMoves = get_all_moves(board, turn, 0); - int checkmate = 0; - for(int i = 0; i < allMoves.length; i++) { - if(allMoves.vectorps[i].length > 0) { - checkmate = 0; - break; - } - else { - checkmate = 1; - } - } - if(checkmate) { - printf("You've been checkmated!\n"); - break; - } - else { - 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(); - int selectedPiece = board.pieces[selection.mx][selection.my]; - //check if the piece is of the right colour, and that there is a piece there - if(selectedPiece == 0 || (selectedPiece > 6 && turn == 0) || (selectedPiece <= 6 && turn == 1)) { - warn_user("Invalid selection!"); - continue; - } - printf("Selected piece: "); - printf("%d", selectedPiece); - printf("\n"); - vectorp_t moves = get_moves_final(board, selection, selectedPiece); - if(moves.length == 0) { - warn_user("That piece has no valid moves!"); - continue; - } - printf("Valid moves: "); - //write all the valid moves - for(int i = 0; i < moves.length; i++) { - char* readable_coords = get_move_name(board, selection, moves.vectors[i]); - printf(readable_coords); - free(readable_coords); - printf("; "); - } - printf("\nEnter the coordinates you would like to move that piece to, or enter < to go back\n"); - //get the selection for the location to move the piece to - vector_t target = user_input_pos(); - if(target.mx == -1) { - continue; - } - //check if target is in list of valid moves - int match = 0; - for(int i = 0; i < moves.length; i++) { - if(moves.vectors[i].mx == target.mx && moves.vectors[i].my == target.my) { - match = 1; - break; - } - } - if(!match) { - warn_user("Invalid move"); - continue; - } - board = make_move(board, selection, target); - free(moves.vectors); - printf("\n"); - turn = !turn; - } - return 0; -} -//this function returns moves that will place the player in check! -vectorp_t get_moves(board_t board, vector_t position, piece_t piece) { - int color = 0; - if(piece > 6) { - color = 1; - piece -= 6; - } - if(piece == pawn) { - return get_pawn_moves(board, position, color); - } - else if(piece == knight) { - return get_knight_moves(board, position, color); - } - 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); - } - else if(piece == king) { - return get_king_moves(board, position, color); - } - else { - return init_vectorp(0, 0); - } -} -//array of arrays representing all the moves each piece of color can make -//excludeKing flag prevents recursion with castling checks -vectorpp_t get_all_moves(board_t board, int color, int excludeKing) { - 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) && (!excludeKing || (board.pieces[v.mx][v.my] != king && board.pieces[v.mx][v.my] != king + 6))) { - allMoves[pieceCount] = get_moves(board, v, board.pieces[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(board_t board, int color) { - for(int r = 0; r < 8; r++) { - for(int c = 0; c < 8; c++) { - if(board.pieces[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(board_t board, 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, 1); - 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 moves that place you in check -vectorp_t get_moves_final(board_t board, 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++) { - board_t tempBoard = make_move(clone_board(board), position, moves.vectors[i]); - if(is_in_check(tempBoard, color)) { - invalidMoves[invalidMovesCount] = i; - invalidMovesCount++; - } - free(tempBoard.pieces); - } - vectorp_t finalMoves = remove_vectors(moves, invalidMoves, invalidMovesCount); - free(invalidMoves); - free(moves.vectors); - return finalMoves; -} -vectorp_t get_pawn_moves(board_t board, vector_t position, int color) { - vector_t* moves = malloc(6 * sizeof(vector_t)); - int moveCount = 0; - int forwardDir = (color == 0 ? -1 : 1); - vector_t move1 = init_vector(position.mx, position.my + forwardDir); - if(in_board(move1) && is_empty(board, move1)) { - moves[moveCount] = move1; - moveCount++; - if(position.my == (color == 0 ? 6 : 1)) { - vector_t move2 = init_vector(position.mx, position.my + (forwardDir * 2)); - if(is_empty(board, move2)) { - moves[moveCount] = move2; - moveCount++; - } - } - } - vector_t captureL = init_vector(position.mx - 1, position.my + forwardDir); - if(in_board(captureL) && (is_color(board, captureL, !color) || would_have_been_pawn(board, captureL, !color))) { - moves[moveCount] = captureL; - moveCount++; - } - vector_t captureR = init_vector(position.mx + 1, position.my + forwardDir); - if(in_board(captureR) && (is_color(board, captureR, !color) || would_have_been_pawn(board, captureR, !color))) { - moves[moveCount] = captureR; - moveCount++; - } - return init_vectorp(moves, moveCount); -} -vectorp_t get_knight_moves(board_t board, vector_t position, int color) { - vector_t* moves = malloc(8 * sizeof(vector_t)); - int moveCount = 0; - for(int i = 0; i < 8; i++) { - int h = ((i == 0 || i == 1) ? 2 : (i == 2 || i == 3) ? -2 : (i == 4 || i == 5) ? 1 : -1); - int v = ((i == 0 || i == 2) ? -1 : (i == 1 || i == 3) ? 1 : (i == 4 || i == 6) ? 2 : -2); - vector_t move = init_vector(position.mx + h, position.my + v); - if(in_board(move) && (is_empty(board, move) || is_color(board, move, !color))) { - moves[moveCount] = move; - moveCount++; - } - } - return init_vectorp(moves, moveCount); -} -vectorp_t get_bishop_moves(board_t board, 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 < 2 ? 1 : -1; - int v = (i == 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_rook_moves(board_t board, 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(board_t board, 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); -} -//TODO: don't allow king to move next to opposing king -vectorp_t get_king_moves(board_t board, vector_t position, int color) { - //TODO: change size to 8 - vector_t* moves = malloc(20 * 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 move = init_vector(position.mx + h, position.my + v); - if(in_board(move) && (is_empty(board, move) || is_color(board, move, !color))) { - moves[moveCount] = move; - moveCount++; - } - } - //castling - if(!is_in_check(board, color)) { - //kingside castling - if((color == 0 && board.whiteCanCastleKingside) || (color == 1 && board.blackCanCastleKingside)) { - //check that the squares are free - vector_t s1 = init_vector(5, color == 0 ? 7 : 0); - vector_t s2 = init_vector(6, color == 0 ? 7 : 0); - if(is_empty(board, s1) && is_empty(board, s2)) { - //check that the squares are not threatened - board_t tempBoard1 = make_move(clone_board(board), position, s1); - board_t tempBoard2 = make_move(clone_board(board), position, s2); - if(!is_in_check(tempBoard1, color) && !is_in_check(tempBoard2, color)) { - //add the move - moves[moveCount] = s2; - moveCount++; - } - free(tempBoard1.pieces); - free(tempBoard2.pieces); - } - } - //queenside castling - if((color == 0 && board.whiteCanCastleQueenside) || (color == 1 && board.blackCanCastleQueenside)) { - //check that the squares are free - vector_t s1 = init_vector(3, color == 0 ? 7 : 0); - vector_t s2 = init_vector(2, color == 0 ? 7 : 0); - if(is_empty(board, s1) && is_empty(board, s2)) { - //check that the squares are not threatened - board_t tempBoard1 = make_move(clone_board(board), position, s1); - board_t tempBoard2 = make_move(clone_board(board), position, s2); - if(!is_in_check(tempBoard1, color) && !is_in_check(tempBoard2, color)) { - //add the move - moves[moveCount] = s2; - moveCount++; - } - free(tempBoard1.pieces); - free(tempBoard2.pieces); - } - } - } - return init_vectorp(moves, moveCount); -} |
