diff options
author | boa <boa@pm.me> | 2021-02-01 02:36:55 +0100 |
---|---|---|
committer | boa <boa@pm.me> | 2021-02-01 02:36:55 +0100 |
commit | b690bace22189a8953825b5f121ad0d271b4de3f (patch) | |
tree | 32501f64efc6bf78d3ed6087e953ab7976bb4898 | |
parent | 9654b87ee25af52ae957a339e5053dabd45e4e9f (diff) | |
download | ajedrez-b690bace22189a8953825b5f121ad0d271b4de3f.tar.gz |
checkmate
-rwxr-xr-x | chess | bin | 26312 -> 35880 bytes | |||
-rw-r--r-- | chess.c | 144 |
2 files changed, 97 insertions, 47 deletions
Binary files differ @@ -1,4 +1,4 @@ -// do what the fuck you want +// TODO: recatoring, debugging and stalemate #include <arpa/inet.h> #include <stdbool.h> @@ -23,6 +23,7 @@ int abs(int a) { return -1 * a; } +typedef enum result { r_no, r_win, r_stalemate } result; typedef enum piece_type { p_no, p_pawn = 'P', @@ -33,6 +34,17 @@ typedef enum piece_type { p_king = 'K' } piece_type; +typedef struct pos { + int x; + int y; +} pos; + +typedef struct move { + pos f; + pos t; + piece p; +} move; + typedef struct piece { piece_type p; color c; @@ -44,8 +56,10 @@ int *c_fd = &w_fd; // current fd bool moved_king[2] = {false, false}; bool moved_rook_l[2] = {false, false}; bool moved_rook_r[2] = {false, false}; +int pawnx = -1, pawny = -1; -bool is_valid(); +bool in_check(color c, int cx, int cy); +bool is_valid(int from_x, int from_y, int to_x, int to_y); void print_table(); void setup_table(); void play_game(); @@ -99,9 +113,13 @@ void print_table() { } bool in_check(color c, int cx, int cy) { + printf("c: %d, %d, %d\n", c, cx, cy); for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { + if (cx == x && cy == y) + continue; if (table[x][y].c != c && is_valid(x, y, cx, cy)) { + printf("true check\n"); return true; } } @@ -137,45 +155,54 @@ void setup_table() { table[5][0] = (piece){p_bishop, c_w}; table[6][0] = (piece){p_knight, c_w}; table[7][0] = (piece){p_rook, c_w}; - for (int x = 0; x < 8; x++) - table[x][1] = (piece){p_pawn, c_w}; + // for (int x = 0; x < 8; x++) + // table[x][1] = (piece){p_pawn, c_w}; - table[0][7] = (piece){p_rook, c_b}; - table[1][7] = (piece){p_knight, c_b}; - table[2][7] = (piece){p_bishop, c_b}; + // table[0][7] = (piece){p_rook, c_b}; + // table[1][7] = (piece){p_knight, c_b}; + // table[2][7] = (piece){p_bishop, c_b}; table[3][7] = (piece){p_king, c_b}; - table[4][7] = (piece){p_queen, c_b}; - table[5][7] = (piece){p_bishop, c_b}; - table[6][7] = (piece){p_knight, c_b}; - table[7][7] = (piece){p_rook, c_b}; - for (int x = 0; x < 8; x++) - table[x][6] = (piece){p_pawn, c_b}; + // table[4][7] = (piece){p_queen, c_b}; + // table[5][7] = (piece){p_bishop, c_b}; + // table[6][7] = (piece){p_knight, c_b}; + // table[7][7] = (piece){p_rook, c_b}; + // for (int x = 0; x < 8; x++) + // table[x][6] = (piece){p_pawn, c_b}; } int is_inside(int i) { return i >= 0 && i < 8; } -bool is_checkmate(color c) { +result is_checkmate(color c) { int kx = -1, ky = -1; for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { if (table[x][y].p == p_king && table[x][y].c == c) { kx = x; ky = y; + goto out; } } } +out: + printf("k: %d %d\n", kx, ky); + if (kx == -1 || ky == -1) + return r_no; if (!in_check(c, kx, ky)) { - return false; + printf("k not in check\n"); + return r_no; } + printf("k in check\n"); for (int y = -1; y <= 1; y++) { for (int x = -1; x <= 1; x++) { if (x == 0 && y == 0) continue; - if (is_valid(kx, ky, kx + x, ky + y) && !in_check(c, kx + x, ky + y)) { - return false; + if (is_valid(kx, ky, kx + x, ky + y) && is_inside(ky + y) && + is_inside(kx + x) && !in_check(c, kx + x, ky + y)) { + return r_no; } } } + color ic = c == c_w ? c_b : c_w; for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { if (table[x][y].c != c && is_valid(x, y, kx, ky)) { @@ -186,14 +213,13 @@ bool is_checkmate(color c) { int v_y = dy ? ((dy > 0) ? 1 : -1) : 0; for (int n = 1; n < abs(dx); n++) if (table[x + n * v_x][y + n * v_y].p == p_no) - if (in_check(!c, x + n * v_x, y + n * v_y)) - return false; - } else if (table[x][y].p == p_rook) { + if (in_check(ic, x + n * v_x, y + n * v_y)) + return r_no; } } } } - return true; + return r_win; } bool is_valid(int from_x, int from_y, int to_x, int to_y) { @@ -201,13 +227,13 @@ bool is_valid(int from_x, int from_y, int to_x, int to_y) { int dx = to_x - from_x, dy = to_y - from_y; int v_x, v_y, l; if (in_check_sim(from_x, from_y, to_x, to_y)) - return 0; + return false; switch (p.p) { case p_pawn: - // TODO: refactor, en passant if ((dx != 0 && ((dx != 1 && dx != -1) || (dy != 1 && p.c == c_w) || - (dy != -1 && p.c == c_b) || table[to_x][to_y].p == p_no)) || + (dy != -1 && p.c == c_b) || + (table[to_x][to_y].p == p_no && to_x != pawnx && to_y != pawny))) || dy < -2 || dy > 2 || (dy == 1 && p.c != c_w) || (dy == 2 && (p.c != c_w || from_y != 1 || table[from_x][from_y + 1].p != p_no)) || @@ -247,7 +273,7 @@ bool is_valid(int from_x, int from_y, int to_x, int to_y) { l = (dx * dy == 0) ? abs(dx + dy) : abs(dx); for (int n = 1; n < l; n++) if (table[from_x + n * v_x][from_y + n * v_y].p != p_no) - return 0; + return false; break; case p_king: if (in_check(p.c, to_x, to_y)) @@ -291,8 +317,30 @@ bool is_valid(int from_x, int from_y, int to_x, int to_y) { return true; } +void print_move(color c, char buf[50]) { + printf("%s", buf); + if (c == c_w) + dprintf(b_fd, buf); + else + dprintf(w_fd, buf); +} + +void print_result(color c) { + if ((result r = is_checkmate(c)) != r_no) { + if (r == r_stalemate) { + PRINT_ALL("\ndöntetlen\n"); + } else { + if (c == c_w) + PRINT_ALL("\na fekete nyert!\n"); + else + PRINT_ALL("\na fehér nyert!\n"); + break; + } + } +} + void play_game() { - color c_c = c_w; + color c_c = c_w; // current color for (;;) { print_table(); if (c_c == c_w) @@ -301,8 +349,13 @@ void play_game() { dprintf(w_fd, "fekete gondolkodik...\n"); no_print: dprintf(*c_fd, "> "); + print_result(c_c); + + // parse move char buf[50] = {0}; - read(*c_fd, buf, 20); + read(*c_fd, buf, 50); + if (buf[0] == 's') + goto skip; if (buf[0] == ':') { if (c_c == c_w) dprintf(b_fd, buf); @@ -314,13 +367,8 @@ void play_game() { int from_y = buf[1] - '1'; int to_x = buf[3] - 'a'; int to_y = buf[4] - '1'; - if (is_checkmate(c_c)) { - if (c_c == c_w) - PRINT_ALL("a fekete nyert!"); - else - PRINT_ALL("a fehér nyert!"); - break; - } + + // is legal if (!is_inside(from_x) || !is_inside(from_y) || !is_inside(to_x) || !is_inside(to_y) || table[from_x][from_y].p == p_no || table[from_x][from_y].c != c_c || @@ -329,20 +377,21 @@ void play_game() { dprintf(*c_fd, "hiba: %d %d %d %d\n", from_x, from_y, to_x, to_y); goto no_print; } else { - printf("%s", buf); - if (c_c == c_w) - dprintf(b_fd, buf); - else - dprintf(w_fd, buf); - if (table[to_x][to_y].p == p_king) { - if (c_c == c_w) - PRINT_ALL("a fehér nyert!"); - else - PRINT_ALL("a fekete nyert!"); - break; - } + print_move(c_c, buf); + + // do move table[to_x][to_y] = table[from_x][from_y]; - table[from_x][from_y] = (piece){p_no, c_w}; + table[from_x][from_y].p = p_no; + + // en passant + if (to_x == pawnx && to_y == pawny && table[to_x][to_y].p == p_pawn) + table[pawnx][to_y + (pawny - to_y)].p = p_no; + pawnx = -1, pawny = -1; + if (table[to_x][to_y].p == p_pawn && + (from_y - to_y == -2 || from_y - to_y == 2)) + pawnx = to_x, pawny = to_y + (from_y - to_y) / 2; + + // trade pawn if ((to_y == 0 || to_y == 7) && table[to_x][to_y].p == p_pawn) { char cbuf[10] = {0}; retry: @@ -373,6 +422,7 @@ void play_game() { } } } + skip: if (c_fd == &w_fd) { c_fd = &b_fd; c_c = c_b; |