/*---------------------------------------------------------- * HTBLA-Leonding / 2IHIF * --------------------------------------------------------- * Description: * Implementation of basic chess functions. * ---------------------------------------------------------- */ #include #include #include #include "chess.h" #include "chess_printer.h" int abs(int value) { if(value < 0) { return -value; } return value; } struct ChessPiece get_piece(ChessBoard chess_board, File file, Rank rank) { if (file < 'a' || file > 'h' || rank < 1 || rank > 8) { struct ChessPiece empty = {NO_COLOR, NoPiece}; return empty; } return chess_board[file - 'a'][rank - 1].piece; } struct ChessSquare* get_square(ChessBoard chess_board, File file, Rank rank) { if (file < 'a' || file > 'h' || rank < 1 || rank > 8) { return NULL; } return &chess_board[file - 'a'][rank - 1]; } bool squares_share_pawns_move(Color color, MoveType move, File filePiece1, Rank rankPiece1, File filePiece2, Rank rankPiece2) { if ((color == White && rankPiece1 < 2) || (color == Black && rankPiece1 > 7)) { return false; } int rank_diff = rankPiece2 - rankPiece1; int file_diff = filePiece2 - filePiece1; if (color == White) { if (move == NormalMove) { return (rank_diff == 1 && file_diff == 0) || (rank_diff == 2 && file_diff == 0 && rankPiece1 == 2); } else if (move == CaptureMove) { return rank_diff == 1 && abs(file_diff) == 1; } } else if (color == Black) { if (move == NormalMove) { return (rank_diff == -1 && file_diff == 0) || (rank_diff == -2 && file_diff == 0 && rankPiece1 == 7); } else if (move == CaptureMove) { return rank_diff == -1 && abs(file_diff) == 1; } } return false; } void init_chess_board(ChessBoard chess_board) { for (int i = 0; i < CHESSBOARD_LENGTH; i++) { for (int j = 0; j < CHESSBOARD_LENGTH; j++) { chess_board[i][j].is_occupied = false; chess_board[i][j].piece.color = NO_COLOR; chess_board[i][j].piece.type = NoPiece; } } } void setup_chess_board(ChessBoard chess_board) { init_chess_board(chess_board); struct ChessPiece white_pawn = {White, Pawn}; struct ChessPiece white_rook = {White, Rook}; struct ChessPiece white_knight = {White, Knight}; struct ChessPiece white_bishop = {White, Bishop}; struct ChessPiece white_queen = {White, Queen}; struct ChessPiece white_king = {White, King}; struct ChessPiece black_pawn = {Black, Pawn}; struct ChessPiece black_rook = {Black, Rook}; struct ChessPiece black_knight = {Black, Knight}; struct ChessPiece black_bishop = {Black, Bishop}; struct ChessPiece black_queen = {Black, Queen}; struct ChessPiece black_king = {Black, King}; for (File file = 'a'; file <= 'h'; file++) { add_piece(chess_board, file, 2, white_pawn); add_piece(chess_board, file, 7, black_pawn); } add_piece(chess_board, 'a', 1, white_rook); add_piece(chess_board, 'h', 1, white_rook); add_piece(chess_board, 'b', 1, white_knight); add_piece(chess_board, 'g', 1, white_knight); add_piece(chess_board, 'c', 1, white_bishop); add_piece(chess_board, 'f', 1, white_bishop); add_piece(chess_board, 'd', 1, white_queen); add_piece(chess_board, 'e', 1, white_king); add_piece(chess_board, 'a', 8, black_rook); add_piece(chess_board, 'h', 8, black_rook); add_piece(chess_board, 'b', 8, black_knight); add_piece(chess_board, 'g', 8, black_knight); add_piece(chess_board, 'c', 8, black_bishop); add_piece(chess_board, 'f', 8, black_bishop); add_piece(chess_board, 'd', 8, black_queen); add_piece(chess_board, 'e', 8, black_king); } bool is_square_occupied(ChessBoard chess_board, File file, Rank rank) { return chess_board[file - 'a'][rank - 1].is_occupied; } bool squares_share_file(File file1, Rank rank1, File file2, Rank rank2) { if (file1 < 'a' || file1 > 'h' || file2 < 'a' || file2 > 'h' || rank1 < 1 || rank1 > 8 || rank2 < 1 || rank2 > 8) { return false; } return file1 == file2; } bool squares_share_rank(File file1, Rank rank1, File file2, Rank rank2) { if (file1 < 'a' || file1 > 'h' || file2 < 'a' || file2 > 'h' || rank1 < 1 || rank1 > 8 || rank2 < 1 || rank2 > 8) { return false; } return rank1 == rank2; } bool squares_share_diagonal(File file1, Rank rank1, File file2, Rank rank2) { if (file1 < 'a' || file1 > 'h' || file2 < 'a' || file2 > 'h' || rank1 < 1 || rank1 > 8 || rank2 < 1 || rank2 > 8) { return false; } return abs(file1 - file2) == abs(rank1 - rank2); } bool squares_share_knights_move(File file1, Rank rank1, File file2, Rank rank2) { int file_difference = abs(file1 - file2); int rank_difference = abs(rank1 - rank2); bool move_1 = (file_difference == 1 && rank_difference == 2); bool move_2 = (file_difference == 2 && rank_difference == 1); return move_1 || move_2; } bool squares_share_queens_move(File file1, Rank rank1, File file2, Rank rank2) { bool same_file = squares_share_file(file1, rank1, file2, rank2); bool same_rank = squares_share_rank(file1, rank1, file2, rank2); bool same_diagonal = squares_share_diagonal(file1, rank1, file2, rank2); return same_file || same_rank || same_diagonal; } bool squares_share_kings_move(File file1, Rank rank1, File file2, Rank rank2) { int file_difference = abs(file1 - file2); int rank_difference = abs(rank1 - rank2); bool same_file = file_difference <= 1; bool same_rank = rank_difference <= 1; return same_file && same_rank; } bool is_piece(struct ChessPiece piece, Color color, PieceType type) { return piece.color == color && piece.type == type; } bool add_piece(ChessBoard chess_board, File file, Rank rank, struct ChessPiece piece) { if (file < 'a' || file > 'h' || rank < 1 || rank > 8 || is_square_occupied(chess_board, file, rank)) { return false; } chess_board[file - 'a'][rank - 1].is_occupied = true; chess_board[file - 'a'][rank - 1].piece = piece; return true; } bool remove_piece(ChessBoard chess_board, File file, Rank rank) { if (!is_square_occupied(chess_board, file, rank)) { return false; } chess_board[file - 'a'][rank - 1].is_occupied = false; chess_board[file - 'a'][rank - 1].piece.color = NO_COLOR; chess_board[file - 'a'][rank - 1].piece.type = NoPiece; return true; }