06-chess/assignment/chess.c
2024-11-06 22:59:32 +01:00

192 lines
No EOL
6.5 KiB
C

/*----------------------------------------------------------
* HTBLA-Leonding / 2IHIF
* ---------------------------------------------------------
* Description:
* Implementation of basic chess functions.
* ----------------------------------------------------------
*/
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#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;
}