From 38a5593be27363f5bda138bb67aa4a8ab16c4ffd Mon Sep 17 00:00:00 2001 From: ItsSypher <43073095+ItsSypher@users.noreply.github.com> Date: Mon, 7 Feb 2022 22:55:03 +0800 Subject: [PATCH 1/3] my attempt at blocking checks(not complete) --- .vscode/settings.json | 6 +++ src/board.c | 2 +- src/main.c | 4 +- src/piece.c | 116 +++++++++++++++++++++++++++--------------- src/piece.h | 2 +- 5 files changed, 84 insertions(+), 46 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..5c5bc28 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "files.associations": { + "algorithm": "c", + "string": "c" + } +} \ No newline at end of file diff --git a/src/board.c b/src/board.c index 559bf68..3277f2d 100644 --- a/src/board.c +++ b/src/board.c @@ -86,7 +86,7 @@ validate_move(position origin, position target, board * game, position * amoves) /* assign passed moves array, else calculate it */ position *valid_moves = amoves; if (valid_moves == NULL) { - valid_moves = moves(origin_cell.piece, origin, game->game, &game->game_flags); + valid_moves = moves(origin_cell.piece, origin, game->game, &game->game_flags, game->last_check_line); allocated_by_me = 1; } diff --git a/src/main.c b/src/main.c index 3087f56..5d948c8 100644 --- a/src/main.c +++ b/src/main.c @@ -109,7 +109,7 @@ main() * following checks */ free(moves(game_board->game[target.rank][target.file].piece, target, - game_board->game, &game_board->game_flags)); + game_board->game, &game_board->game_flags, game_board->last_check_line)); /* * we do not actually need those moves, so * that's why we just free them afterwards, @@ -172,7 +172,7 @@ main() * chosen piece */ amoves = moves(game_board->game[sel_row][sel_col].piece, coords_to_pos(sel_row, sel_col), - game_board->game, &game_board->game_flags); + game_board->game, &game_board->game_flags, game_board->last_check_line); /* if no moves have been returned, ignore */ if (amoves == NULL) break; diff --git a/src/piece.c b/src/piece.c index fc98d6a..5bde3cc 100644 --- a/src/piece.c +++ b/src/piece.c @@ -23,14 +23,15 @@ opposite(SIDE orig) { } uint8_t -check_if_king(position * valid_moves, int move_idx, cell game[SIZE_STD][SIZE_STD], +check_if_king(position * lcl, int move_idx, cell game[SIZE_STD][SIZE_STD], uint8_t game_flags){ - if (move_idx == 0 || valid_moves == NULL) + if (move_idx == 0 || lcl == NULL) return game_flags; + uint8_t flags = game_flags; - if (game[valid_moves[move_idx - 1].rank][valid_moves[move_idx - 1].file].piece != NULL && - game[valid_moves[move_idx - 1].rank][valid_moves[move_idx - 1].file].piece->ident == 'k') { - switch (game[valid_moves[move_idx - 1].rank][valid_moves[move_idx - 1].file].side) { + if (game[lcl[move_idx - 1].rank][lcl[move_idx - 1].file].piece != NULL && + game[lcl[move_idx - 1].rank][lcl[move_idx - 1].file].piece->ident == 'k') { + switch (game[lcl[move_idx - 1].rank][lcl[move_idx - 1].file].side) { case BLACK: flags |= FLAG_CHECK_BLACK; break; @@ -40,12 +41,15 @@ check_if_king(position * valid_moves, int move_idx, cell game[SIZE_STD][SIZE_STD default: break; } + } else { + lcl = NULL; + free(lcl); } return flags; } position * -rook_valid(position pos, cell game[SIZE_STD][SIZE_STD], uint8_t * game_flags) +rook_valid(position pos, cell game[SIZE_STD][SIZE_STD], uint8_t * game_flags, position * lcl) { const int max_length = (SIZE_STD - 1) * 2; /* a rook can move ( not * counting other pieces @@ -61,56 +65,69 @@ rook_valid(position pos, cell game[SIZE_STD][SIZE_STD], uint8_t * game_flags) * clarify that's * reserved for the * sentinel */ - int move_idx = 0; + lcl = malloc(sizeof(position)*SIZE_STD); + int move_idx = 0, lcl_move_idx = 0;; /* Line up */ for (int row = pos.rank + 1; row < SIZE_STD; row++) { if (game[row][pos.file].piece != NULL) { if (game[row][pos.file].side == opposite(game[pos.rank][pos.file].side)) { - valid_moves[move_idx++] = coords_to_pos(row, pos.file); + lcl[lcl_move_idx++] = coords_to_pos(row, pos.file); break; } break; } - valid_moves[move_idx++] = coords_to_pos(row, pos.file); + lcl[lcl_move_idx++] = coords_to_pos(row, pos.file); } - *game_flags = check_if_king(valid_moves, move_idx, game, *game_flags); + lcl[lcl_move_idx] = SENTINEL; + memcpy(valid_moves, lcl, (lcl_move_idx-1) * sizeof(position)); + *game_flags = check_if_king(lcl, lcl_move_idx, game, *game_flags); + move_idx+=lcl_move_idx; /* Line down */ for (int row = pos.rank - 1; row >= 0; row--) { if (game[row][pos.file].piece != NULL) { if (game[row][pos.file].side == opposite(game[pos.rank][pos.file].side)) { - valid_moves[move_idx++] = coords_to_pos(row, pos.file); + lcl[lcl_move_idx++] = coords_to_pos(row, pos.file); break; } break; } - valid_moves[move_idx++] = coords_to_pos(row, pos.file); + lcl[lcl_move_idx++] = coords_to_pos(row, pos.file); } - *game_flags = check_if_king(valid_moves, move_idx, game, *game_flags); + lcl[lcl_move_idx] = SENTINEL; + memcpy(valid_moves, lcl, (lcl_move_idx-1) * sizeof(position)); + *game_flags = check_if_king(lcl, lcl_move_idx, game, *game_flags); + move_idx+=lcl_move_idx-1; /* Line left */ for (int col = pos.file - 1; col >= 0; col--) { if (game[pos.rank][col].piece != NULL) { if (game[pos.rank][col].side == opposite(game[pos.rank][pos.file].side)) { - valid_moves[move_idx++] = coords_to_pos(pos.rank, col); + lcl[lcl_move_idx++] = coords_to_pos(pos.rank, col); break; } break; } - valid_moves[move_idx++] = coords_to_pos(pos.rank, col); + lcl[lcl_move_idx++] = coords_to_pos(pos.rank, col); } - *game_flags = check_if_king(valid_moves, move_idx, game, *game_flags); + lcl[lcl_move_idx] = SENTINEL; + memcpy(valid_moves + move_idx, lcl, (lcl_move_idx-1) * sizeof(position)); + *game_flags = check_if_king(lcl, lcl_move_idx, game, *game_flags); + move_idx+=lcl_move_idx; /* Line right */ for (int col = pos.file + 1; col < SIZE_STD; col++) { if (game[pos.rank][col].piece != NULL) { if (game[pos.rank][col].side == opposite(game[pos.rank][pos.file].side)) { - valid_moves[move_idx++] = coords_to_pos(pos.rank, col); + lcl[lcl_move_idx++] = coords_to_pos(pos.rank, col); break; } break; } - valid_moves[move_idx++] = coords_to_pos(pos.rank, col); + lcl[lcl_move_idx++] = coords_to_pos(pos.rank, col); } - *game_flags = check_if_king(valid_moves, move_idx, game, *game_flags); + lcl[lcl_move_idx] = SENTINEL; + memcpy(valid_moves + move_idx, lcl, (lcl_move_idx-1) * sizeof(position)); + *game_flags = check_if_king(lcl, lcl_move_idx, game, *game_flags); + move_idx+=lcl_move_idx; valid_moves[move_idx] = SENTINEL; return valid_moves; } @@ -141,7 +158,7 @@ knight_valid(position pos, cell game[SIZE_STD][SIZE_STD], uint8_t * game_flags) } position * -bishop_valid(position pos, cell game[SIZE_STD][SIZE_STD], uint8_t * game_flags) +bishop_valid(position pos, cell game[SIZE_STD][SIZE_STD], uint8_t * game_flags, position * lcl) { /* * we can approximate, in the worst case the bishop will take @@ -151,72 +168,87 @@ bishop_valid(position pos, cell game[SIZE_STD][SIZE_STD], uint8_t * game_flags) position *valid_moves = malloc(sizeof(position) * max_length + sizeof(position)); /* allocate vertical + * horizontal moves + * sentinel */ - int i = 1, move_idx = 0; + lcl = malloc(sizeof(position)*SIZE_STD); /* allocate one diagonal worst case scenario takes 7 cells */ + int i = 1, move_idx = 0, lcl_move_idx = 0; /* first diagonal: top right */ while (pos.rank + i < SIZE_STD && pos.file + i < SIZE_STD) { if (game[pos.rank + i][pos.file + i].piece != NULL) { if (game[pos.rank + i][pos.file + i].side == opposite(game[pos.rank][pos.file].side)) { - valid_moves[move_idx++] = coords_to_pos(pos.rank + i, pos.file + i); + lcl[lcl_move_idx++] = coords_to_pos(pos.rank + i, pos.file + i); break; } break; } - valid_moves[move_idx++] = coords_to_pos(pos.rank + i, pos.file + i); + lcl[lcl_move_idx++] = coords_to_pos(pos.rank + i, pos.file + i); i++; } - *game_flags = check_if_king(valid_moves, move_idx, game, *game_flags); + lcl[lcl_move_idx] = SENTINEL; + memcpy(valid_moves, lcl, (lcl_move_idx-1) * sizeof(position)); + *game_flags = check_if_king(lcl, lcl_move_idx, game, *game_flags); + move_idx+=lcl_move_idx-1; + /* second diagonal: top left */ - i = 1; + i = 1, lcl_move_idx=0; while (pos.rank + i < SIZE_STD && pos.file - i >= 0) { if (game[pos.rank + i][pos.file - i].piece != NULL) { if (game[pos.rank + i][pos.file - i].side == opposite(game[pos.rank][pos.file].side)) { - valid_moves[move_idx++] = coords_to_pos(pos.rank + i, pos.file - i); + lcl[lcl_move_idx++] = coords_to_pos(pos.rank + i, pos.file - i); break; } break; } - valid_moves[move_idx++] = coords_to_pos(pos.rank + i, pos.file - i); + lcl[lcl_move_idx++] = coords_to_pos(pos.rank + i, pos.file - i); i++; } - *game_flags = check_if_king(valid_moves, move_idx, game, *game_flags); + lcl[lcl_move_idx] = SENTINEL; + memcpy(valid_moves + move_idx, lcl, (lcl_move_idx-1) * sizeof(position)); + *game_flags = check_if_king(lcl, lcl_move_idx, game, *game_flags); + move_idx+=lcl_move_idx; + /* third diagonal: bottom left */ - i = 1; + i = 1, lcl_move_idx=0; while (pos.rank - i >= 0 && pos.file - i >= 0) { if (game[pos.rank - i][pos.file - i].piece != NULL) { if (game[pos.rank - i][pos.file - i].side == opposite(game[pos.rank][pos.file].side)) { - valid_moves[move_idx++] = coords_to_pos(pos.rank - i, pos.file - i); + lcl[lcl_move_idx++] = coords_to_pos(pos.rank - i, pos.file - i); break; } break; } - valid_moves[move_idx++] = coords_to_pos(pos.rank - i, pos.file - i); + lcl[lcl_move_idx++] = coords_to_pos(pos.rank - i, pos.file - i); i++; } - *game_flags = check_if_king(valid_moves, move_idx, game, *game_flags); + lcl[lcl_move_idx] = SENTINEL; + memcpy(valid_moves + move_idx, lcl, (lcl_move_idx-1) * sizeof(position)); + *game_flags = check_if_king(lcl, lcl_move_idx, game, *game_flags); + move_idx+=lcl_move_idx; /* fourth diagonal: bottom right */ i = 1; while (pos.rank - i >= 0 && pos.file + i < SIZE_STD) { if (game[pos.rank - i][pos.file + i].piece != NULL) { if (game[pos.rank - i][pos.file + i].side == opposite(game[pos.rank][pos.file].side)) { - valid_moves[move_idx++] = coords_to_pos(pos.rank - i, pos.file + i); + lcl[lcl_move_idx++] = coords_to_pos(pos.rank - i, pos.file + i); break; } break; } - valid_moves[move_idx++] = coords_to_pos(pos.rank - i, pos.file + i); + lcl[lcl_move_idx++] = coords_to_pos(pos.rank - i, pos.file + i); i++; } - *game_flags = check_if_king(valid_moves, move_idx, game, *game_flags); + lcl[lcl_move_idx] = SENTINEL; + memcpy(valid_moves + move_idx, lcl, (lcl_move_idx-1) * sizeof(position)); + *game_flags = check_if_king(lcl, lcl_move_idx, game, *game_flags); + move_idx+=lcl_move_idx; valid_moves[move_idx] = SENTINEL; return valid_moves; } position * -queen_valid(position pos, cell game[SIZE_STD][SIZE_STD], uint8_t * game_flags) +queen_valid(position pos, cell game[SIZE_STD][SIZE_STD], uint8_t * game_flags, position * last_check_line) { - position *bishop_moves = bishop_valid(pos, game, game_flags); - position *rook_moves = rook_valid(pos, game, game_flags); + position *bishop_moves = bishop_valid(pos, game, game_flags, last_check_line); + position *rook_moves = rook_valid(pos, game, game_flags, last_check_line); int bishop_moves_len, rook_moves_len; for (bishop_moves_len = 0; bishop_moves[bishop_moves_len].file != -1; bishop_moves_len++) ; @@ -306,20 +338,20 @@ pawn_valid(position pos, cell game[SIZE_STD][SIZE_STD], uint8_t * game_flags) } position * -moves(piece * piece, position pos, cell game[SIZE_STD][SIZE_STD], uint8_t * game_flags) +moves(piece * piece, position pos, cell game[SIZE_STD][SIZE_STD], uint8_t * game_flags, position *last_check_line) { switch (piece->ident) { case 'r': - return rook_valid(pos, game, game_flags); + return rook_valid(pos, game, game_flags, last_check_line); break; case 'b': - return bishop_valid(pos, game, game_flags); + return bishop_valid(pos, game, game_flags, last_check_line); break; case 'n': return knight_valid(pos, game, game_flags); break; case 'q': - return queen_valid(pos, game, game_flags); + return queen_valid(pos, game, game_flags, last_check_line); break; case 'k': return king_valid(pos, game, game_flags); diff --git a/src/piece.h b/src/piece.h index 50a0d6b..4f0c171 100644 --- a/src/piece.h +++ b/src/piece.h @@ -29,7 +29,7 @@ typedef struct { uint8_t flags; } cell; -position * moves(piece * piece, position pos, cell game[SIZE_STD][SIZE_STD], uint8_t * game_flags); +position * moves(piece * piece, position pos, cell game[SIZE_STD][SIZE_STD], uint8_t * game_flags, position *last_check_line); extern piece rook, bishop, knight, queen, pawn, king; position coords_to_pos(short rank, short file); piece *ident_to_piece(char ident); From 3481a29a412a57fa860f42df34afc25384f103ae Mon Sep 17 00:00:00 2001 From: Sypher <43073095+ItsSypher@users.noreply.github.com> Date: Mon, 7 Feb 2022 23:07:21 +0800 Subject: [PATCH 2/3] Update .gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 2f799b1..f8bb7b0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ build/ src/*.gch *~ -**/*~ \ No newline at end of file +**/*~ +.vscode From 140a4254fe0a475ca6e4fe1871e68ea4f5e4bbf4 Mon Sep 17 00:00:00 2001 From: Sypher <43073095+ItsSypher@users.noreply.github.com> Date: Mon, 7 Feb 2022 23:07:51 +0800 Subject: [PATCH 3/3] Delete .vscode directory --- .vscode/settings.json | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 5c5bc28..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "files.associations": { - "algorithm": "c", - "string": "c" - } -} \ No newline at end of file