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); } }