From 2c68726ab2e00a9546fc61824e6c54a486a966c9 Mon Sep 17 00:00:00 2001 From: Daniel Weber Date: Sun, 22 Sep 2024 06:19:16 -0400 Subject: [PATCH] Finalizing En Passant functionality --- src/game_logic/fen_strings.c | 14 +++++- src/game_logic/game_state.c | 60 ++++++++++++++++------- src/game_logic/game_state.h | 6 ++- src/game_logic/piece_logic/king.c | 2 +- src/game_logic/piece_logic/pawn.c | 25 ++++++++-- src/game_logic/piece_logic/pawn.h | 1 + src/pc_app/user_interface_abstraction.cpp | 6 ++- 7 files changed, 88 insertions(+), 26 deletions(-) diff --git a/src/game_logic/fen_strings.c b/src/game_logic/fen_strings.c index b55d45c..29cd632 100644 --- a/src/game_logic/fen_strings.c +++ b/src/game_logic/fen_strings.c @@ -103,9 +103,19 @@ char * fen_string_get_state(void) if (!castle) { fen_append('-'); } - - fen_append(' '); + + if(state->en_passant < 0) + { + fen_append('-'); + } + else + { + fen_append((char)('a'+(state->en_passant % 8))); + fen_append((char)('0'+(state->en_passant / 8))); + } + + fen_append('\0'); return fen_string; } diff --git a/src/game_logic/game_state.c b/src/game_logic/game_state.c index 42d2d7d..2e44bd7 100644 --- a/src/game_logic/game_state.c +++ b/src/game_logic/game_state.c @@ -13,8 +13,9 @@ static Game_State_t Game_State = { .turn_state = BEGINNING, .board_state = {0}, .board_pieces = {0}, - .selected_peice = SQUARE_EMPTY, + .selected_piece = SQUARE_EMPTY, .castling_allowed = {{true, true},{true, true}}, + .en_passant = -1, }; static uint8_t Error_Count = 0u; static bool Check[2u] = {false, false}; @@ -90,18 +91,18 @@ static void Board_Square_Was_Toggled(uint8_t row_idx, uint8_t col_idx) { if (Game_State.board_state[row_idx*8+col_idx] == PIECE_ORIGIN) { - Game_State.board_pieces[row_idx*8+col_idx] = Game_State.selected_peice; - Game_State.selected_peice = SQUARE_EMPTY; + Game_State.board_pieces[row_idx*8+col_idx] = Game_State.selected_piece; + Game_State.selected_piece = SQUARE_EMPTY; clear_board_state(); Game_State.turn_state = BEGINNING; } else if (Game_State.board_state[row_idx*8+col_idx] == PIECE_NEEDS_TO_BE_HERE) { - Game_State.board_pieces[row_idx*8+col_idx] = Game_State.selected_peice; - Game_State.selected_peice = SQUARE_EMPTY; + Game_State.board_pieces[row_idx*8+col_idx] = Game_State.selected_piece; + Game_State.selected_piece = SQUARE_EMPTY; Game_State.board_state[row_idx*8+col_idx] = LIGHT_OFF; - if (Game_State.selected_peice == SQUARE_EMPTY) + if (Game_State.selected_piece == SQUARE_EMPTY) { Game_State.turn_state = BEGINNING; Game_State.player_turn = !Game_State.player_turn; @@ -133,9 +134,10 @@ static void Board_Square_Was_Toggled(uint8_t row_idx, uint8_t col_idx) { if ((Game_State.board_pieces[row_idx*8+col_idx] != SQUARE_EMPTY) && (white_team(Game_State.board_pieces[row_idx*8+col_idx]) == Game_State.player_turn)) { - Game_State.selected_peice = Game_State.board_pieces[row_idx*8+col_idx]; + Game_State.selected_piece = Game_State.board_pieces[row_idx*8+col_idx]; Game_State.board_pieces[row_idx*8+col_idx] = SQUARE_EMPTY; - (void)Mark_Potential_Moves(Game_State.selected_peice, col_idx, row_idx, &Game_State); + (void)Mark_Potential_Moves(Game_State.selected_piece, col_idx, row_idx, &Game_State); + Game_State.selected_piece_origin = row_idx*8+col_idx; Game_State.board_state[row_idx*8+col_idx] = PIECE_ORIGIN; Game_State.turn_state = IN_PROGRESS; } @@ -158,8 +160,9 @@ static void Board_Square_Was_Toggled(uint8_t row_idx, uint8_t col_idx) { Check_If_Moving_King(row_idx, col_idx, &Game_State); Check_If_Converting_Pawn(row_idx, col_idx, &Game_State); - Game_State.board_pieces[row_idx*8+col_idx] = Game_State.selected_peice; - Game_State.selected_peice = SQUARE_EMPTY; + Game_State.board_pieces[row_idx*8+col_idx] = Game_State.selected_piece; + Game_State.selected_piece = SQUARE_EMPTY; + Mark_En_Passant_Target(row_idx*8+col_idx, &Game_State); clear_board_state(); Switch_Turns(); } @@ -172,16 +175,16 @@ static void Board_Square_Was_Toggled(uint8_t row_idx, uint8_t col_idx) } else if (Game_State.board_state[row_idx*8+col_idx] == PIECE_ORIGIN) { - Game_State.board_pieces[row_idx*8+col_idx] = Game_State.selected_peice; - Game_State.selected_peice = SQUARE_EMPTY; + Game_State.board_pieces[row_idx*8+col_idx] = Game_State.selected_piece; + Game_State.selected_piece = SQUARE_EMPTY; clear_board_state(); Game_State.turn_state = BEGINNING; } else if (Game_State.board_state[row_idx*8+col_idx] == POTENTIAL_CASTLE) { Check_If_Moving_King(row_idx, col_idx, &Game_State); - Game_State.board_pieces[row_idx*8+col_idx] = Game_State.selected_peice; - Game_State.selected_peice = SQUARE_EMPTY; + Game_State.board_pieces[row_idx*8+col_idx] = Game_State.selected_piece; + Game_State.selected_piece = SQUARE_EMPTY; clear_board_state(); if(col_idx == 2u) { @@ -199,9 +202,24 @@ static void Board_Square_Was_Toggled(uint8_t row_idx, uint8_t col_idx) } } + else if (Game_State.board_state[row_idx*8+col_idx] == EN_PASSANT) + { + Game_State.board_pieces[row_idx*8+col_idx] = Game_State.selected_piece; + Game_State.selected_piece = SQUARE_EMPTY; + clear_board_state(); + if(row_idx == 2u) + { + Game_State.board_state[row_idx*8+col_idx+8] = EN_PASSANT_REMOVE; + } + else if(row_idx == 5u) + { + Game_State.board_state[row_idx*8+col_idx-8] = EN_PASSANT_REMOVE; + } + Game_State.turn_state = FINALIZING; + } else if (Game_State.board_state[row_idx*8+col_idx] == PIECE_NEEDS_TO_BE_REMOVED) { - Game_State.selected_peice = Game_State.board_pieces[row_idx*8+col_idx]; + Game_State.selected_piece = Game_State.board_pieces[row_idx*8+col_idx]; Game_State.board_pieces[row_idx*8+col_idx] = SQUARE_EMPTY; Game_State.board_state[row_idx*8+col_idx] = LIGHT_OFF; Game_State.turn_state = FINALIZING; @@ -221,10 +239,16 @@ static void Board_Square_Was_Toggled(uint8_t row_idx, uint8_t col_idx) { Check_If_Moving_King(row_idx, col_idx, &Game_State); Check_If_Converting_Pawn(row_idx, col_idx, &Game_State); - Game_State.board_pieces[row_idx*8+col_idx] = Game_State.selected_peice; - Game_State.selected_peice = SQUARE_EMPTY; + Game_State.board_pieces[row_idx*8+col_idx] = Game_State.selected_piece; + Game_State.selected_piece = SQUARE_EMPTY; Game_State.board_state[row_idx*8+col_idx] = LIGHT_OFF; } + else if (Game_State.board_state[row_idx*8+col_idx] == EN_PASSANT_REMOVE) + { + Game_State.board_pieces[row_idx*8+col_idx] = SQUARE_EMPTY; + Game_State.board_state[row_idx*8+col_idx] = LIGHT_OFF; + + } else { if(!Converting_Pawn_If_Applicable(row_idx, col_idx, &Game_State)) @@ -235,7 +259,7 @@ static void Board_Square_Was_Toggled(uint8_t row_idx, uint8_t col_idx) } } - if (Game_State.selected_peice == SQUARE_EMPTY) + if (Game_State.selected_piece == SQUARE_EMPTY) { Switch_Turns(); } diff --git a/src/game_logic/game_state.h b/src/game_logic/game_state.h index 5fa061c..66d0cd3 100644 --- a/src/game_logic/game_state.h +++ b/src/game_logic/game_state.h @@ -19,6 +19,8 @@ enum Board_States_t { POTENTIAL_CASTLE, PIECE_NEEDS_TO_BE_REMOVED, CONVERTING_PAWN, + EN_PASSANT, + EN_PASSANT_REMOVE, }; #define PAWN_WHITE 0u @@ -51,8 +53,10 @@ typedef struct { Turn_State_t turn_state; uint8_t board_state[8*8]; uint8_t board_pieces[8*8]; - uint8_t selected_peice; + uint8_t selected_piece; + uint8_t selected_piece_origin; bool castling_allowed[2u][2u]; + int en_passant; }Game_State_t; void game_state_init(void); diff --git a/src/game_logic/piece_logic/king.c b/src/game_logic/piece_logic/king.c index 2ba52d2..f6de249 100644 --- a/src/game_logic/piece_logic/king.c +++ b/src/game_logic/piece_logic/king.c @@ -34,7 +34,7 @@ void Check_If_Moving_King(uint8_t row, uint8_t column, Game_State_t * game_state { uint8_t white_black_idx = game_state->player_turn ? 0u : 1u; uint8_t inverse_idx = game_state->player_turn ? 1u : 0u; - if((game_state->selected_peice == KING_WHITE) || (game_state->selected_peice == KING_BLACK)) + if((game_state->selected_piece == KING_WHITE) || (game_state->selected_piece == KING_BLACK)) { King_Locations[white_black_idx][0u] = row; King_Locations[white_black_idx][1u] = column; diff --git a/src/game_logic/piece_logic/pawn.c b/src/game_logic/piece_logic/pawn.c index 95a1f65..844c2f8 100644 --- a/src/game_logic/piece_logic/pawn.c +++ b/src/game_logic/piece_logic/pawn.c @@ -11,12 +11,12 @@ void Check_If_Converting_Pawn(uint8_t row, uint8_t column, Game_State_t * game_s uint8_t white_black_idx = game_state->player_turn ? 0u : 1u; Converting_Pawn = false; - if((game_state->selected_peice == PAWN_WHITE) || (game_state->selected_peice == PAWN_BLACK)) + if((game_state->selected_piece == PAWN_WHITE) || (game_state->selected_piece == PAWN_BLACK)) { if((row == 0u) || (row == 7u)) { - game_state->selected_peice = game_state->player_turn ? QUEEN_WHITE : QUEEN_BLACK; - Pawn_Converted_To = game_state->selected_peice; + game_state->selected_piece = game_state->player_turn ? QUEEN_WHITE : QUEEN_BLACK; + Pawn_Converted_To = game_state->selected_piece; Converting_Pawn = true; Converting_Pawn_Row_Col[0] = row; Converting_Pawn_Row_Col[1] = column; @@ -89,5 +89,24 @@ bool pawn_take(uint8_t piece, uint8_t row, uint8_t column, Game_State_t * game_s { ret_val = Set_Light(piece, row, column, POTENTIAL_TAKE); } + else if (game_state->en_passant == row*8+column) { + ret_val = Set_Light(piece, row, column, EN_PASSANT); + } return ret_val; } + +void Mark_En_Passant_Target(uint8_t location, Game_State_t * game_state) +{ + if ((game_state->selected_piece_origin / 8 == 1) || (game_state->selected_piece_origin / 8 == 6)) + { + if (((game_state->board_pieces[location] == PAWN_BLACK) && ((location / 8) == 3)) || + ((game_state->board_pieces[location] == PAWN_WHITE) && ((location / 8) == 4))) + { + int offset = game_state->player_turn ? 8 : -8; + game_state->en_passant = location + offset; + return; + } + } + game_state->en_passant = -1; +} + diff --git a/src/game_logic/piece_logic/pawn.h b/src/game_logic/piece_logic/pawn.h index a450834..74635b0 100644 --- a/src/game_logic/piece_logic/pawn.h +++ b/src/game_logic/piece_logic/pawn.h @@ -5,3 +5,4 @@ void Check_If_Converting_Pawn(uint8_t row, uint8_t column, Game_State_t * game_s bool Converting_Pawn_If_Applicable(uint8_t row, uint8_t column, Game_State_t * game_state); bool pawn_move(uint8_t piece, uint8_t row, uint8_t column, Game_State_t * game_state); bool pawn_take(uint8_t piece, uint8_t row, uint8_t column, Game_State_t * game_state); +void Mark_En_Passant_Target(uint8_t location, Game_State_t * game_state); diff --git a/src/pc_app/user_interface_abstraction.cpp b/src/pc_app/user_interface_abstraction.cpp index 28a17e0..ae07e8a 100644 --- a/src/pc_app/user_interface_abstraction.cpp +++ b/src/pc_app/user_interface_abstraction.cpp @@ -137,7 +137,11 @@ static void ui_draw_board(SDL_Renderer *p_renderer, Game_State_t * game_state) SDL_RenderFillRect(p_renderer, &Rectangle); SDL_SetRenderDrawColor(p_renderer, 0x85, 0x5E, 0x42, 0x00); } - else if ((game_state->board_state[j*8+i] == POTENTIAL_TAKE) || (game_state->board_state[j*8+i] == PIECE_NEEDS_TO_BE_HERE) || (game_state->board_state[j*8+i] == PIECE_NEEDS_TO_BE_REMOVED)) + else if ((game_state->board_state[j*8+i] == POTENTIAL_TAKE) + || (game_state->board_state[j*8+i] == PIECE_NEEDS_TO_BE_HERE) + || (game_state->board_state[j*8+i] == PIECE_NEEDS_TO_BE_REMOVED) + || (game_state->board_state[j*8+i] == EN_PASSANT_REMOVE) + || (game_state->board_state[j*8+i] == EN_PASSANT)) { SDL_SetRenderDrawColor(p_renderer, 0xFF, 0x00, 0x00, 0x00); SDL_RenderFillRect(p_renderer, &Rectangle);