aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorboa <boa@pm.me>2021-02-01 02:36:55 +0100
committerboa <boa@pm.me>2021-02-01 02:36:55 +0100
commitb690bace22189a8953825b5f121ad0d271b4de3f (patch)
tree32501f64efc6bf78d3ed6087e953ab7976bb4898
parent9654b87ee25af52ae957a339e5053dabd45e4e9f (diff)
downloadajedrez-b690bace22189a8953825b5f121ad0d271b4de3f.tar.gz
checkmate
-rwxr-xr-xchessbin26312 -> 35880 bytes
-rw-r--r--chess.c144
2 files changed, 97 insertions, 47 deletions
diff --git a/chess b/chess
index 8ba4c2c..c473760 100755
--- a/chess
+++ b/chess
Binary files differ
diff --git a/chess.c b/chess.c
index ec2dae7..2168b32 100644
--- a/chess.c
+++ b/chess.c
@@ -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;
Un proyecto texto-plano.xyz