From de77196cccce4152947a097a800882789cd67ff9 Mon Sep 17 00:00:00 2001 From: Daniel Weber Date: Wed, 18 Sep 2024 21:00:39 -0400 Subject: [PATCH 1/6] Starting to add fenstrings --- src/game_logic/fen_strings.c | 111 ++++++++++++++++++++++ src/game_logic/fen_strings.h | 10 ++ src/game_logic/game_state.c | 4 +- src/game_logic/game_state.h | 3 +- src/game_logic/piece_logic/king.c | 18 ++-- src/game_logic/piece_logic/piece_logic.c | 4 +- src/pc_app/game.cpp | 4 + src/pc_app/user_interface_abstraction.cpp | 49 +++++----- 8 files changed, 161 insertions(+), 42 deletions(-) create mode 100644 src/game_logic/fen_strings.c create mode 100644 src/game_logic/fen_strings.h diff --git a/src/game_logic/fen_strings.c b/src/game_logic/fen_strings.c new file mode 100644 index 0000000..12ef827 --- /dev/null +++ b/src/game_logic/fen_strings.c @@ -0,0 +1,111 @@ +#include "fen_strings.h" +#include "game_state.h" +#include "string.h" +#include "assert.h" + +char fen_string[200]; +int fen_idx = 0; + +static void fen_append(char val) +{ + assert(fen_idx < (int)sizeof(fen_string)); + fen_string[fen_idx] = val; + fen_idx++; +} + +char * fen_string_get_state(void) +{ + memset(fen_string, (int)' ', sizeof(fen_string)); + fen_idx = 0; + Game_State_t * state = Board_get_game_state(); + for (int row = 0; row < 8; row++) + { + int consec_empty = 0; + for (int column = 0; column < 8; column++) + { + if((state->board_pieces[row * 8 + column] == SQUARE_EMPTY)) + { + consec_empty++; + if (column == 7) { + fen_append((char)('0' + consec_empty)); + } + } + else + { + char ret_val; + if (consec_empty != 0) + { + fen_append((char)('0' + consec_empty)); + consec_empty = 0; + } + switch (state->board_pieces[row * 8 + column]) + { + case PAWN_WHITE: + fen_append('P'); + break; + case PAWN_BLACK: + fen_append('p'); + break; + case KING_WHITE: + fen_append('K'); + break; + case KING_BLACK: + fen_append('k'); + break; + case ROOK_WHITE: + fen_append('R'); + break; + case ROOK_BLACK: + fen_append('r'); + break; + case KNIGHT_WHITE: + fen_append('N'); + break; + case KNIGHT_BLACK: + fen_append('n'); + break; + case BISHOP_WHITE: + fen_append('B'); + break; + case BISHOP_BLACK: + fen_append('b'); + break; + case QUEEN_WHITE: + fen_append('Q'); + break; + case QUEEN_BLACK: + fen_append('q'); + break; + } + } + } + fen_append('/'); + } + fen_append(' '); + if (state->player_turn) { + fen_append('w'); + } + else{ + fen_append('b'); + } + fen_append(' '); + char options[2][2] = {{'K', 'Q'}, {'k', 'q'}}; + bool castle = true; + for(int color = 0; color < 2; color++){ + for(int k_q = 0; k_q < 2; k_q++){ + if(state->castling_allowed[color][k_q]) + { + castle = false; + fen_append(options[color][k_q]); + } + } + } + if (!castle) { + fen_append('-'); + } + + + fen_append(' '); + fen_append('\0'); + return fen_string; +} diff --git a/src/game_logic/fen_strings.h b/src/game_logic/fen_strings.h new file mode 100644 index 0000000..ba88ebd --- /dev/null +++ b/src/game_logic/fen_strings.h @@ -0,0 +1,10 @@ +#ifdef __cplusplus +extern "C" { +#endif + +char * fen_string_get_state(void); +void fen_string_set_state(void); + +#ifdef __cplusplus +} +#endif diff --git a/src/game_logic/game_state.c b/src/game_logic/game_state.c index 61fd49c..42d2d7d 100644 --- a/src/game_logic/game_state.c +++ b/src/game_logic/game_state.c @@ -327,9 +327,9 @@ void game_state_init(void) } } -Game_State_t Board_get_game_state(void) +Game_State_t * Board_get_game_state(void) { - return Game_State; + return &Game_State; } diff --git a/src/game_logic/game_state.h b/src/game_logic/game_state.h index 0e24237..5fa061c 100644 --- a/src/game_logic/game_state.h +++ b/src/game_logic/game_state.h @@ -59,8 +59,7 @@ void game_state_init(void); void Board_Changed(uint8_t current_binary_board[8]); bool Set_Light(uint8_t piece, uint8_t row, uint8_t column, uint8_t state); void clear_board_state(void); -void Board_get_lights_and_state(uint8_t * board_lights, uint8_t * board_state); -Game_State_t Board_get_game_state(void); +Game_State_t * Board_get_game_state(void); #ifdef __cplusplus } diff --git a/src/game_logic/piece_logic/king.c b/src/game_logic/piece_logic/king.c index cebcf4e..2ba52d2 100644 --- a/src/game_logic/piece_logic/king.c +++ b/src/game_logic/piece_logic/king.c @@ -1,4 +1,5 @@ #include "king.h" +#include "game_state.h" #include "piece_logic.h" static uint8_t King_Locations[2u][2u] = {{7,4}, {0,4}}; @@ -32,6 +33,7 @@ bool Check_If_Move_Caused_Check(uint8_t piece, uint8_t row, uint8_t column, Game 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)) { King_Locations[white_black_idx][0u] = row; @@ -40,17 +42,13 @@ void Check_If_Moving_King(uint8_t row, uint8_t column, Game_State_t * game_state game_state->castling_allowed[white_black_idx][1u] = false; } // Disable the castling of the corresponding side if the rook is being moved. - else if (((game_state->selected_peice == ROOK_WHITE) && (row == 7u)) - || ((game_state->selected_peice == ROOK_BLACK) && (row == 0u))) + if (game_state->board_pieces[inverse_idx*7*8+7] == SQUARE_EMPTY) { - if (column == 0u) - { - game_state->castling_allowed[white_black_idx][0u] = false; - } - else if (column == 7u) - { - game_state->castling_allowed[white_black_idx][1u] = false; - } + game_state->castling_allowed[white_black_idx][0u] = false; + } + if (game_state->board_pieces[inverse_idx*8*7+0] == SQUARE_EMPTY) + { + game_state->castling_allowed[white_black_idx][1u] = false; } } diff --git a/src/game_logic/piece_logic/piece_logic.c b/src/game_logic/piece_logic/piece_logic.c index 59f6613..ef499bf 100644 --- a/src/game_logic/piece_logic/piece_logic.c +++ b/src/game_logic/piece_logic/piece_logic.c @@ -490,7 +490,7 @@ bool Mark_Potential_Moves(uint8_t piece, uint8_t column, uint8_t row, Game_State if (square_is_safe(row, column, game_state)) { // Queen side castle - if(game_state->castling_allowed[white_black_idx][0u] && (game_state->board_pieces[kings_row*8+1u] == SQUARE_EMPTY) + if(game_state->castling_allowed[white_black_idx][1u] && (game_state->board_pieces[kings_row*8+1u] == SQUARE_EMPTY) && (game_state->board_pieces[kings_row*8+2u] == SQUARE_EMPTY) && (game_state->board_pieces[kings_row*8+3u]) == SQUARE_EMPTY) { //First Check to see if the king will pass through check @@ -503,7 +503,7 @@ bool Mark_Potential_Moves(uint8_t piece, uint8_t column, uint8_t row, Game_State } // King side castle - if (game_state->castling_allowed[white_black_idx][1u] && (game_state->board_pieces[kings_row*8+5u] == SQUARE_EMPTY) && (game_state->board_pieces[kings_row*8+6u] == SQUARE_EMPTY)) + if (game_state->castling_allowed[white_black_idx][0u] && (game_state->board_pieces[kings_row*8+5u] == SQUARE_EMPTY) && (game_state->board_pieces[kings_row*8+6u] == SQUARE_EMPTY)) { //First Check to see if the king will pass through check if(square_is_safe(kings_row, 5u, game_state) && square_is_safe(kings_row, 6u, game_state)) diff --git a/src/pc_app/game.cpp b/src/pc_app/game.cpp index 6578388..0e17d15 100644 --- a/src/pc_app/game.cpp +++ b/src/pc_app/game.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -7,6 +8,7 @@ #include #include #include "game_state.h" +#include "fen_strings.h" #include "user_interface_abstraction.h" static clock_t start_time, end_time; @@ -50,6 +52,8 @@ int begin_game(SDL_Renderer *renderer, SDL_Window *win) end_time = clock(); clock_t t = end_time - start_time; + char * fen = fen_string_get_state(); + SDL_Log(fen); SDL_Log("No. of clicks %ld clicks (%f seconds) to process the incoming click.\n", t, ((float)t) / CLOCKS_PER_SEC); } else diff --git a/src/pc_app/user_interface_abstraction.cpp b/src/pc_app/user_interface_abstraction.cpp index 7187b31..28a17e0 100644 --- a/src/pc_app/user_interface_abstraction.cpp +++ b/src/pc_app/user_interface_abstraction.cpp @@ -28,10 +28,10 @@ static uint8_t Current_Binary_Board[8] = {0}; * clearly indicating which player won. * * @param p_renderer Sdl Renderer - * @param board_state board state + * @param game_state->board_pieces board state * @param game_state games state */ -static void ui_draw_end_game(SDL_Renderer *p_renderer, uint8_t * board_state, Game_State_t game_state) +static void ui_draw_end_game(SDL_Renderer *p_renderer, Game_State_t * game_state) { SDL_SetRenderTarget(p_renderer, Board_Texture); SDL_SetRenderDrawColor(p_renderer, 0x7f, 0x7f, 0x7f, 0); @@ -50,8 +50,8 @@ static void ui_draw_end_game(SDL_Renderer *p_renderer, uint8_t * board_state, Ga Rectangle.h = square_size; uint8_t white_color[4] = {0xFF, 0xFF, 0x00, 0x00}; uint8_t black_color[4] = {0xFF, 0xFF, 0x00, 0x00}; - if (!game_state.error_detected){ - if(game_state.player_turn) + if (!game_state->error_detected){ + if(game_state->player_turn) { white_color[0] = 0x00; white_color[1] = 0xFF; white_color[2] = 0x00; white_color[3] = 0x00; black_color[0] = 0xFF; black_color[1] = 0x00; black_color[2] = 0x00; black_color[3] = 0x00; @@ -69,10 +69,10 @@ static void ui_draw_end_game(SDL_Renderer *p_renderer, uint8_t * board_state, Ga Rectangle.x = starting_x; for (size_t i = 0; i < 8; i++) { - if((board_state[j*8+i] & 0x0Fu) != SQUARE_EMPTY) + if((game_state->board_pieces[j*8+i] & 0x0Fu) != SQUARE_EMPTY) { uint8_t * render_color; - if((board_state[j*8+i] % 2u) == 0u ) + if((game_state->board_pieces[j*8+i] % 2u) == 0u ) { render_color = white_color; } @@ -83,7 +83,7 @@ static void ui_draw_end_game(SDL_Renderer *p_renderer, uint8_t * board_state, Ga SDL_SetRenderDrawColor(p_renderer, render_color[0], render_color[1], render_color[2], render_color[3]); SDL_RenderFillRect(p_renderer, &Rectangle); SDL_SetRenderDrawColor(p_renderer, 0x85, 0x5E, 0x42, 0x00); - SDL_RenderCopy(p_renderer, bitmapTextures[(board_state[j*8+i] & 0x0Fu)], NULL, &Rectangle); + SDL_RenderCopy(p_renderer, bitmapTextures[(game_state->board_pieces[j*8+i] & 0x0Fu)], NULL, &Rectangle); } else if (((i % 2) + (j % 2)) == 1) { @@ -109,7 +109,7 @@ static void ui_draw_end_game(SDL_Renderer *p_renderer, uint8_t * board_state, Ga * @param *p_renderer pointer to the renderer object: * @retval None */ -static void ui_draw_board(SDL_Renderer *p_renderer, uint8_t * board_lights, uint8_t * board_state) +static void ui_draw_board(SDL_Renderer *p_renderer, Game_State_t * game_state) { SDL_SetRenderTarget(p_renderer, Board_Texture); SDL_SetRenderDrawColor(p_renderer, 0x7f, 0x7f, 0x7f, 0); @@ -131,31 +131,31 @@ static void ui_draw_board(SDL_Renderer *p_renderer, uint8_t * board_lights, uint Rectangle.x = starting_x; for (size_t i = 0; i < 8; i++) { - if ((board_lights[j*8+i] == POTENTIAL_MOVE) || (board_lights[j*8+i] == POTENTIAL_CASTLE)) + if ((game_state->board_state[j*8+i] == POTENTIAL_MOVE) || (game_state->board_state[j*8+i] == POTENTIAL_CASTLE)) { SDL_SetRenderDrawColor(p_renderer, 0x00, 0xFF, 0x00, 0x00); SDL_RenderFillRect(p_renderer, &Rectangle); SDL_SetRenderDrawColor(p_renderer, 0x85, 0x5E, 0x42, 0x00); } - else if ((board_lights[j*8+i] == POTENTIAL_TAKE) || (board_lights[j*8+i] == PIECE_NEEDS_TO_BE_HERE) || (board_lights[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)) { SDL_SetRenderDrawColor(p_renderer, 0xFF, 0x00, 0x00, 0x00); SDL_RenderFillRect(p_renderer, &Rectangle); SDL_SetRenderDrawColor(p_renderer, 0x85, 0x5E, 0x42, 0x00); } - else if (board_lights[j*8+i] == PIECE_ORIGIN) + else if (game_state->board_state[j*8+i] == PIECE_ORIGIN) { SDL_SetRenderDrawColor(p_renderer, 0xFF, 0x00, 0xFF, 0x00); SDL_RenderFillRect(p_renderer, &Rectangle); SDL_SetRenderDrawColor(p_renderer, 0x85, 0x5E, 0x42, 0x00); } - else if (board_lights[j*8+i] == ERROR_MOVE) + else if (game_state->board_state[j*8+i] == ERROR_MOVE) { SDL_SetRenderDrawColor(p_renderer, 0xFF, 0xFF, 0x00, 0x00); SDL_RenderFillRect(p_renderer, &Rectangle); SDL_SetRenderDrawColor(p_renderer, 0x85, 0x5E, 0x42, 0x00); } - else if (board_lights[j*8+i] == CONVERTING_PAWN) + else if (game_state->board_state[j*8+i] == CONVERTING_PAWN) { SDL_SetRenderDrawColor(p_renderer, 0xFF, 0x3B, 0x7A, 0x57); SDL_RenderFillRect(p_renderer, &Rectangle); @@ -170,9 +170,9 @@ static void ui_draw_board(SDL_Renderer *p_renderer, uint8_t * board_lights, uint /* code */ } - if((board_state[j*8+i] & 0x0Fu) != SQUARE_EMPTY) + if((game_state->board_pieces[j*8+i] & 0x0Fu) != SQUARE_EMPTY) { - SDL_RenderCopy(p_renderer, bitmapTextures[(board_state[j*8+i] & 0x0Fu)], NULL, &Rectangle); + SDL_RenderCopy(p_renderer, bitmapTextures[(game_state->board_pieces[j*8+i] & 0x0Fu)], NULL, &Rectangle); } Rectangle.x += square_size; @@ -191,13 +191,13 @@ static void ui_draw_board(SDL_Renderer *p_renderer, uint8_t * board_lights, uint Rectangle.y = starting_y; for (size_t i = 0; i < 8; i++) { - if (board_lights[j*8+i] == PIECE_NEEDS_TO_BE_HERE) + if (game_state->board_state[j*8+i] == PIECE_NEEDS_TO_BE_HERE) { SDL_SetRenderDrawColor(p_renderer, 0xFF, 0x00, 0x00, 0x00); SDL_RenderFillRect(p_renderer, &Rectangle); SDL_SetRenderDrawColor(p_renderer, 0x6F, 0x6F, 0x6F, 0x00); } - else if (board_lights[j*8+i] == ERROR_MOVE) + else if (game_state->board_state[j*8+i] == ERROR_MOVE) { SDL_SetRenderDrawColor(p_renderer, 0xFF, 0xFF, 0x00, 0x00); SDL_RenderFillRect(p_renderer, &Rectangle); @@ -210,9 +210,9 @@ static void ui_draw_board(SDL_Renderer *p_renderer, uint8_t * board_lights, uint - if ((board_state[j*8+i] & 0x0Fu) != SQUARE_EMPTY) + if ((game_state->board_pieces[j*8+i] & 0x0Fu) != SQUARE_EMPTY) { - SDL_RenderCopy(p_renderer, bitmapTextures[(board_state[j*8+i] & 0x0Fu)], NULL, &Rectangle); + SDL_RenderCopy(p_renderer, bitmapTextures[(game_state->board_pieces[j*8+i] & 0x0Fu)], NULL, &Rectangle); } @@ -236,17 +236,14 @@ static void ui_draw_board(SDL_Renderer *p_renderer, uint8_t * board_lights, uint void ui_redraw_board(SDL_Renderer *p_renderer) { - uint8_t board_lights[8*8]; - uint8_t board_state[8*8]; - Game_State_t game_state = Board_get_game_state(); - Board_get_lights_and_state(board_lights, board_state); - if(game_state.game_over) + Game_State_t * game_state = Board_get_game_state(); + if(game_state->game_over) { - ui_draw_end_game(p_renderer, board_state, game_state); + ui_draw_end_game(p_renderer, game_state); } else { - ui_draw_board(p_renderer, board_lights, board_state); + ui_draw_board(p_renderer, game_state); } } -- 2.45.2 From fafdad72902c9877904338a3a95d15edad9d5580 Mon Sep 17 00:00:00 2001 From: Daniel Weber Date: Wed, 18 Sep 2024 21:04:00 -0400 Subject: [PATCH 2/6] Bug fix with finstring --- src/game_logic/fen_strings.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game_logic/fen_strings.c b/src/game_logic/fen_strings.c index 12ef827..212a3ae 100644 --- a/src/game_logic/fen_strings.c +++ b/src/game_logic/fen_strings.c @@ -90,12 +90,12 @@ char * fen_string_get_state(void) } fen_append(' '); char options[2][2] = {{'K', 'Q'}, {'k', 'q'}}; - bool castle = true; + bool castle = false; for(int color = 0; color < 2; color++){ for(int k_q = 0; k_q < 2; k_q++){ if(state->castling_allowed[color][k_q]) { - castle = false; + castle = true; fen_append(options[color][k_q]); } } -- 2.45.2 From 05b46e116a2c1f33b167f7c2626605bb854c6799 Mon Sep 17 00:00:00 2001 From: Daniel Weber Date: Thu, 19 Sep 2024 22:53:57 -0400 Subject: [PATCH 3/6] Tweaks --- src/game_logic/fen_strings.c | 2 +- src/pc_app/game.cpp | 4 ---- src/pc_app/main.cpp | 4 ---- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/game_logic/fen_strings.c b/src/game_logic/fen_strings.c index 212a3ae..b55d45c 100644 --- a/src/game_logic/fen_strings.c +++ b/src/game_logic/fen_strings.c @@ -79,7 +79,7 @@ char * fen_string_get_state(void) } } } - fen_append('/'); + if (row != 7) fen_append('/'); } fen_append(' '); if (state->player_turn) { diff --git a/src/pc_app/game.cpp b/src/pc_app/game.cpp index 0e17d15..8096788 100644 --- a/src/pc_app/game.cpp +++ b/src/pc_app/game.cpp @@ -107,7 +107,3 @@ int begin_game(SDL_Renderer *renderer, SDL_Window *win) } return 0; } -//g++ main.cpp -o blah `sdl2-config --cflags --libs` -/* -g++ main.cpp -IC:\Users\Daniel\Documents\Projects\i686-w64-mingw32\include\SDL2 -LC:\Users\Daniel\Documents\Projects\i686-w64-mingw32\lib -w -Wl,-subsystem,windows -lmingw32 -lSDL2main -lSDL2 -o SDLMain -*/ diff --git a/src/pc_app/main.cpp b/src/pc_app/main.cpp index 35229e6..b87b4df 100644 --- a/src/pc_app/main.cpp +++ b/src/pc_app/main.cpp @@ -47,7 +47,3 @@ int main( int argc, const char* argv[] ) SDL_DestroyWindow(win); return 0; } -//g++ main.cpp -o blah `sdl2-config --cflags --libs` -/* -g++ main.cpp -IC:\Users\Daniel\Documents\Projects\i686-w64-mingw32\include\SDL2 -LC:\Users\Daniel\Documents\Projects\i686-w64-mingw32\lib -w -Wl,-subsystem,windows -lmingw32 -lSDL2main -lSDL2 -o SDLMain -*/ -- 2.45.2 From 2c68726ab2e00a9546fc61824e6c54a486a966c9 Mon Sep 17 00:00:00 2001 From: Daniel Weber Date: Sun, 22 Sep 2024 06:19:16 -0400 Subject: [PATCH 4/6] 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); -- 2.45.2 From e8885b01e302c5a3978c613c3617701bf376dc11 Mon Sep 17 00:00:00 2001 From: Daniel Weber Date: Sun, 29 Sep 2024 21:07:07 -0400 Subject: [PATCH 5/6] Adding Test dir --- CMakeLists.txt | 38 +++-------------------- src/CMakeLists.txt | 32 +++++++++++++++++++ src/game_logic/fen_strings.h | 2 +- test/CMakeLists.txt | 50 ++++++++++++++++++++++++++++++ test/game_logic/test_game_state.cc | 12 +++++++ test/hello_test.cc | 10 ++++++ 6 files changed, 110 insertions(+), 34 deletions(-) create mode 100644 src/CMakeLists.txt create mode 100644 test/CMakeLists.txt create mode 100644 test/game_logic/test_game_state.cc create mode 100644 test/hello_test.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index bb27396..bc70db2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,33 +1,5 @@ -cmake_minimum_required(VERSION 3.8) - -project(Chess C CXX) - -find_package(SDL2 REQUIRED) - -file(GLOB_RECURSE cpp_sources - CONFIGURE_DEPENDS - "src/*.cpp") - -file(GLOB_RECURSE c_sources - CONFIGURE_DEPENDS - "src/*.c") - -file (GLOB_RECURSE headers CONFIGURE_DEPENDS "src/*.h") - -set (include_dirs "") -foreach (_headerFile ${headers}) - get_filename_component(_dir ${_headerFile} PATH) - list (APPEND include_dirs ${_dir}) -endforeach() - -add_executable(Chess ${cpp_sources} ${c_sources}) -set_target_properties(Chess PROPERTIES CXX_STANDARD 17) # set standard level -target_include_directories(Chess PRIVATE ${include_dirs}) -target_compile_options(Chess PRIVATE - -Wall -Wextra -Wredundant-decls -Wcast-align - -Wshadow -Wnon-virtual-dtor - -Wunused -Woverloaded-virtual -Wpedantic -Wconversion - -Wsign-conversion -Wmisleading-indentation - -Wnull-dereference -Wformat=2 -) -target_link_libraries(Chess SDL2::SDL2) +cmake_minimum_required(VERSION 3.8) +project(Chess C CXX) + +add_subdirectory(src) +add_subdirectory(test) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..344f2d8 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,32 @@ +cmake_minimum_required(VERSION 3.8) + + +find_package(SDL2 REQUIRED) + +file(GLOB_RECURSE cpp_sources + CONFIGURE_DEPENDS + "./*.cpp") + +file(GLOB_RECURSE c_sources + CONFIGURE_DEPENDS + "./*.c") + +file (GLOB_RECURSE headers CONFIGURE_DEPENDS "./*.h") + +set (include_dirs "") +foreach (_headerFile ${headers}) + get_filename_component(_dir ${_headerFile} PATH) + list (APPEND include_dirs ${_dir}) +endforeach() + +add_executable(Chess ${cpp_sources} ${c_sources}) +set_target_properties(Chess PROPERTIES CXX_STANDARD 17) # set standard level +target_include_directories(Chess PRIVATE ${include_dirs}) +target_compile_options(Chess PRIVATE + -Wall -Wextra -Wredundant-decls -Wcast-align + -Wshadow -Wnon-virtual-dtor + -Wunused -Woverloaded-virtual -Wpedantic -Wconversion + -Wsign-conversion -Wmisleading-indentation + -Wnull-dereference -Wformat=2 +) +target_link_libraries(Chess SDL2::SDL2) diff --git a/src/game_logic/fen_strings.h b/src/game_logic/fen_strings.h index ba88ebd..16f0cb5 100644 --- a/src/game_logic/fen_strings.h +++ b/src/game_logic/fen_strings.h @@ -3,7 +3,7 @@ extern "C" { #endif char * fen_string_get_state(void); -void fen_string_set_state(void); +void fen_string_set_state(char *); #ifdef __cplusplus } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..2e8c618 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,50 @@ + +find_package(SDL2 REQUIRED) + +include(FetchContent) +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/refs/tags/v1.15.2.zip +) +FetchContent_MakeAvailable(googletest) + +enable_testing() + +file(GLOB_RECURSE cpp_sources + CONFIGURE_DEPENDS + "../src/*.cpp") + +list(REMOVE_ITEM cpp_sources + "../src/pc_app/main.cpp") + +file(GLOB_RECURSE test_sources + CONFIGURE_DEPENDS + "*.cc") + +file(GLOB_RECURSE c_sources + CONFIGURE_DEPENDS + "../src/*.c") + +file (GLOB_RECURSE headers CONFIGURE_DEPENDS "../src/*.h") +set (include_dirs "") +foreach (_headerFile ${headers}) + get_filename_component(_dir ${_headerFile} PATH) + list (APPEND include_dirs ${_dir}) +endforeach() + +add_executable( + hello_test + # ${cpp_sources} + ${test_sources} + ${c_sources} +) +target_include_directories(hello_test PRIVATE ${include_dirs}) +target_link_libraries( + hello_test + GTest::gtest_main + SDL2::SDL2 +) + +include(GoogleTest) +gtest_discover_tests(hello_test) + diff --git a/test/game_logic/test_game_state.cc b/test/game_logic/test_game_state.cc new file mode 100644 index 0000000..68b7155 --- /dev/null +++ b/test/game_logic/test_game_state.cc @@ -0,0 +1,12 @@ +#include +#include "game_state.h" +#include "fen_strings.h" + +// Demonstrate some basic assertions. +TEST(GameLogic, initialized_state) { + // Expect two strings not to be equal. + game_state_init(); + char * test_data = fen_string_get_state(); + EXPECT_STREQ(test_data, "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -"); +} + diff --git a/test/hello_test.cc b/test/hello_test.cc new file mode 100644 index 0000000..9432d54 --- /dev/null +++ b/test/hello_test.cc @@ -0,0 +1,10 @@ +#include + +// Demonstrate some basic assertions. +TEST(HelloTest, BasicAssertions) { + // Expect two strings not to be equal. + EXPECT_STRNE("hello", "world"); + // Expect equality. + EXPECT_EQ(7 * 6, 42); +} + -- 2.45.2 From 734ae5509fc625e5a519b6d2a7bc33b67b71767e Mon Sep 17 00:00:00 2001 From: Daniel Weber Date: Fri, 4 Oct 2024 21:28:49 -0400 Subject: [PATCH 6/6] Adding drone builds --- .drone.yml | 49 +++++++++++++++++++++++++++++++++++++++++++++ Dockerfile | 6 ++++++ test/CMakeLists.txt | 8 ++++---- test/hello_test.cc | 10 --------- 4 files changed, 59 insertions(+), 14 deletions(-) create mode 100644 .drone.yml create mode 100644 Dockerfile delete mode 100644 test/hello_test.cc diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..7455469 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,49 @@ +kind: pipeline +type: docker +name: chessboard + +trigger: + branch: + - main + event: + - push + +steps: +- name: build + image: git.pipsquire.com/djweber12/Chess_Board_Sim:latest + commands: + - cmake -S . -B build + - cmake --build build + +--- +kind: pipeline +type: docker +name: chessboard_builder + +trigger: + branch: + - main + event: + - push + +steps: + - name: docker + image: plugins/docker + settings: + repo: git.pipsquire.com/djweber12/Chess_Board_Sim + registry: git.pipsquire.com + username: + from_secret: docker_username + password: + from_secret: docker_password + +# +# - name: test +# image: foo:latest +# commands: +# - cmake -s . -b build +# - cmake --build build +# +# volumes: +# - name: dockersock + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a513d5b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,6 @@ +FROM ubuntu:22.04 + +run apt-get update && \ + apt-get install -y libsdl2-dev libsdl2-2.0-0 cmake g++ && \ + apt-get clean + diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2e8c618..2619554 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -33,18 +33,18 @@ foreach (_headerFile ${headers}) endforeach() add_executable( - hello_test + chess_test # ${cpp_sources} ${test_sources} ${c_sources} ) -target_include_directories(hello_test PRIVATE ${include_dirs}) +target_include_directories(chess_test PRIVATE ${include_dirs}) target_link_libraries( - hello_test + chess_test GTest::gtest_main SDL2::SDL2 ) include(GoogleTest) -gtest_discover_tests(hello_test) +gtest_discover_tests(chess_test) diff --git a/test/hello_test.cc b/test/hello_test.cc deleted file mode 100644 index 9432d54..0000000 --- a/test/hello_test.cc +++ /dev/null @@ -1,10 +0,0 @@ -#include - -// Demonstrate some basic assertions. -TEST(HelloTest, BasicAssertions) { - // Expect two strings not to be equal. - EXPECT_STRNE("hello", "world"); - // Expect equality. - EXPECT_EQ(7 * 6, 42); -} - -- 2.45.2