From 50ea1f574080f1d681ca7fe5dfdaba789f06a8f1 Mon Sep 17 00:00:00 2001 From: bru Date: Sun, 6 Feb 2022 17:08:16 -0300 Subject: =?UTF-8?q?Renombr=C3=A9=20sakkom*=20a=20ajedrez*?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- Makefile | 4 +- ajedrez.c | 740 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ sakkom | Bin 31552 -> 0 bytes sakkom.c | 740 ------------------------------------------------------------- 5 files changed, 743 insertions(+), 743 deletions(-) create mode 100644 ajedrez.c delete mode 100755 sakkom delete mode 100644 sakkom.c diff --git a/.gitignore b/.gitignore index bd47f90..b958eb4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -sakkom +ajedrez tags diff --git a/Makefile b/Makefile index 9cb5493..f4f982e 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ CC=cc LIBS=-lpthread all: - $(CC) -o sakkom sakkom.c $(LIBS) + $(CC) -o ajedrez ajedrez.c $(LIBS) clean: - rm sakkom + rm ajedrez diff --git a/ajedrez.c b/ajedrez.c new file mode 100644 index 0000000..3a7980c --- /dev/null +++ b/ajedrez.c @@ -0,0 +1,740 @@ +// SAKKOM: sakk a konzolban király! online multiplayer +// chess.com alternatíva, ami netcatet használ mint kliens +// +// do what you want +// boa + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PRINT_ALL(f_, ...) \ + do { \ + dprintf(w_fd, (f_), ##__VA_ARGS__); \ + dprintf(b_fd, (f_), ##__VA_ARGS__); \ + } while (0) + +typedef enum mode { mode_ascii, mode_unicode } mode; +mode modes[2]; +typedef enum color { c_w = 0, c_b = 1 } color; +typedef enum castle { castle_no, castle_long, castle_short } castle; + +int colors[] = {39, 30}; +char ascii_colors[] = {' ', '*'}; + +int abs(int a) { + if (a >= 0) + return a; + else + return -1 * a; +} + +char symbols[7][7] = {" ", "♟︎", "♜", "♞", "♝", "♛", "♚"}; +char ascii_symbols[7] = {' ', 'P', 'R', 'N', 'B', 'Q', 'K'}; + +typedef enum result { r_no, r_win, r_stalemate } result; +typedef enum piece_type { + p_no, + p_pawn, + p_rook, + p_knight, + p_bishop, + p_queen, + p_king +} piece_type; + +typedef struct pos { + int x; + int y; +} pos; + +typedef struct piece { + piece_type p; + color c; +} piece; + +typedef struct move { + pos f; // from + pos t; // to + piece p; // piece moved + piece e; // enemy taken +} move; + +typedef struct en_passant { + bool valid; + pos p; + piece *to_remove; +} en_passant; +en_passant enp; + +piece table[8][8]; +int w_fd = -1, b_fd = -1; +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 remaining_time[2] = {30 * 60, 30 * 60}; +int game_number = 1; + +void do_move(move m); +bool is_move_legal(color c, move m); +bool in_check(color c, int cx, int cy); +void print_table(); +void setup_table(); +void play_game(); + +bool is_same_pos(pos p1, pos p2) { return p1.x == p2.x && p1.y == p2.y; } + +bool is_empty(piece p) { return p.p == p_no; } +bool is_friend_of(color c, piece p) { return !is_empty(p) && p.c == c; } +bool is_enemy_of(color c, piece p) { return !is_empty(p) && p.c != c; } + +bool is_inside(int i) { return i >= 0 && i < 8; } + +bool is_move_inside(move m) { + return is_inside(m.f.x) && is_inside(m.f.y) && is_inside(m.t.x) && + is_inside(m.t.y); +} + +void print_table() { + if (modes[c_w] == mode_unicode) { + dprintf(w_fd, + "\n \e[43m\x1B[30m\033[1m BLACK \x1B[0m\n\n "); + for (int x = 0; x < 8; x++) { + dprintf(w_fd, " %c ", 'A' + x); + } + dprintf(w_fd, "\n \e[43m┏━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┓\x1B[0m\n"); + for (int y = 7; y >= 0; y--) { + if (y != 7) { + dprintf(w_fd, "\x1B[0m " + "\e[43m┣━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━┫\x1B[0m\n"); + } + dprintf(w_fd, " %d \e[43m┃", y + 1); + for (int x = 0; x < 8; x++) + dprintf(w_fd, "\e[43m\x1B[%dm \033[1m%s \x1B[0m\e[43m┃", + colors[table[x][y].c], symbols[table[x][y].p]); + dprintf(w_fd, "\x1B[0m %d\x1B[0m\n", y + 1); + } + dprintf(w_fd, " \e[43m┗━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┛\x1B[0m\n "); + for (int x = 0; x < 8; x++) { + dprintf(w_fd, " %c ", 'A' + x); + } + dprintf( + w_fd, + "\n\n \e[43m\x1B[39m\033[1m WHITE \x1B[0m\n\n\x1B[0m"); + } else { + dprintf(w_fd, "\n [ BLACK ]\n\n "); + for (int x = 0; x < 8; x++) { + dprintf(w_fd, " %c ", 'A' + x); + } + dprintf(w_fd, "\n +---+---+---+---+---+---+---+---+\n"); + for (int y = 7; y >= 0; y--) { + if (y != 7) { + dprintf(w_fd, " +---+---+---+---+---+---+---+---+\n"); + } + dprintf(w_fd, " %d |", y + 1); + for (int x = 0; x < 8; x++) + dprintf(w_fd, "%c%c |", ascii_colors[table[x][y].c], + ascii_symbols[table[x][y].p]); + dprintf(w_fd, " %d\n", y + 1); + } + dprintf(w_fd, " +---+---+---+---+---+---+---+---+\n "); + for (int x = 0; x < 8; x++) { + dprintf(w_fd, " %c ", 'A' + x); + } + dprintf(w_fd, "\n\n [ WHITE ]\n\n"); + } + + if (modes[c_b] == mode_unicode) { + dprintf(b_fd, + "\n \e[43m\x1B[39m\033[1m WHITE \x1B[0m\n\n "); + for (int x = 0; x < 8; x++) { + dprintf(b_fd, " %c ", 'A' + 7 - x); + } + dprintf(b_fd, "\n \e[43m┏━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┓\x1B[0m\n"); + for (int y = 0; y < 8; y++) { + if (y != 0) { + dprintf(b_fd, "\x1B[0m " + "\e[43m┣━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━┫\x1B[0m\n"); + } + dprintf(b_fd, " %d \e[43m┃", y + 1); + for (int x = 7; x >= 0; x--) + dprintf(b_fd, "\e[43m\x1B[%dm \033[1m%s \x1B[0m\e[43m┃", + colors[table[x][y].c], symbols[table[x][y].p]); + dprintf(b_fd, "\x1B[0m %d\n", y + 1); + } + dprintf(b_fd, " \e[43m┗━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┛\x1B[0m\n "); + for (int x = 0; x < 8; x++) { + dprintf(b_fd, " %c ", 'A' + 7 - x); + } + dprintf( + b_fd, + "\n\n \e[43m\x1B[30m\033[1m BLACK \x1B[0m\n\n\x1B[0m"); + } else { + dprintf(b_fd, "\n [ WHITE ]\n\n "); + for (int x = 0; x < 8; x++) { + dprintf(b_fd, " %c ", 'A' + 7 - x); + } + dprintf(b_fd, "\n +---+---+---+---+---+---+---+---+\n"); + for (int y = 0; y < 8; y++) { + if (y != 0) { + dprintf(b_fd, " +---+---+---+---+---+---+---+---+\n"); + } + dprintf(b_fd, " %d |", y + 1); + for (int x = 7; x >= 0; x--) + dprintf(b_fd, "%c%c |", ascii_colors[table[x][y].c], + ascii_symbols[table[x][y].p]); + dprintf(b_fd, " %d\n", y + 1); + } + dprintf(b_fd, " +---+---+---+---+---+---+---+---+\n "); + for (int x = 0; x < 8; x++) { + dprintf(b_fd, " %c ", 'A' + 7 - x); + } + dprintf(b_fd, "\n\n [ BLACK ]\n\n"); + } +} + +bool in_check(color c, int cx, int cy) { + move m; + m.t.x = cx; + m.t.y = cy; + m.e = table[cx][cy]; + for (int y = 0; y < 8; y++) { + for (int x = 0; x < 8; x++) { + if (cx == x && cy == y) + continue; + m.f.x = x; + m.f.y = y; + m.p = table[x][y]; + if (table[x][y].c != c && is_move_legal(m.p.c, m)) { + return true; + } + } + } + return false; +} + +bool in_check_sim(move m) { + do_move(m); + bool res = false; + 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 == m.p.c) { + res = in_check(m.p.c, x, y); + goto out; + } + } + } +out: + table[m.f.x][m.f.y] = m.p; + table[m.t.x][m.t.y] = m.e; + return res; +} + +void setup_table() { + table[0][0] = (piece){p_rook, c_w}; + table[1][0] = (piece){p_knight, c_w}; + table[2][0] = (piece){p_bishop, c_w}; + table[3][0] = (piece){p_king, c_w}; + table[4][0] = (piece){p_queen, c_w}; + 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}; + + 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}; +} + +pos find_king(color c) { + 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) + return (pos){x, y}; + return (pos){-1, -1}; +} + +bool is_stalemate(color c) { + pos kp = find_king(c); + if (in_check(c, kp.x, kp.y)) + return false; + + move m; + for (m.f.y = 0; m.f.y < 8; m.f.y++) { + for (m.f.x = 0; m.f.x < 8; m.f.x++) { + if (table[m.f.x][m.f.y].c == c) { + m.p = table[m.f.x][m.f.y]; + for (m.t.y = 0; m.t.y < 8; m.t.y++) { + for (m.t.x = 0; m.t.x < 8; m.t.x++) { + if (m.t.x == m.f.x && m.t.y == m.f.y) + continue; + m.e = table[m.t.x][m.t.y]; + if (is_move_legal(c, m)) { + return false; + } + } + } + } + } + } + return true; +} + +bool is_checkmate(color c) { + // probably the most simple and least efficient way to solve this problem + move m; + for (m.f.y = 0; m.f.y < 8; m.f.y++) { + for (m.f.x = 0; m.f.x < 8; m.f.x++) { + if (table[m.f.x][m.f.y].c == c) { + m.p = table[m.f.x][m.f.y]; + for (m.t.y = 0; m.t.y < 8; m.t.y++) { + for (m.t.x = 0; m.t.x < 8; m.t.x++) { + m.e = table[m.t.x][m.t.y]; + if (is_move_legal(c, m)) { + return false; + } + } + } + } + } + } + return true; +} + +int move_num = 1; +void print_move(move m) { + char buf[20]; + int n = 0; + buf[n++] = ascii_symbols[m.p.p]; + buf[n++] = m.f.x + 'a'; + buf[n++] = m.f.y + '1'; + buf[n++] = ' '; + if (m.e.p != p_no) + buf[n++] = ascii_symbols[m.p.p]; + buf[n++] = m.t.x + 'a'; + buf[n++] = m.t.y + '1'; + buf[n++] = '\n'; + buf[n++] = '\0'; + if (m.p.c == c_w) { + PRINT_ALL("%d. white: ", move_num); + } else { + PRINT_ALL("%d. black: ", move_num); + move_num++; + } + PRINT_ALL(buf); +} + +move parse_move(char buf[50]) { + move m; + + m.f.x = buf[0] - 'a'; + m.f.y = buf[1] - '1'; + m.t.x = buf[3] - 'a'; + m.t.y = buf[4] - '1'; + + m.p = table[m.f.x][m.f.y]; + m.e = table[m.t.x][m.t.y]; + + return m; +} + +castle is_castle(color c, move m) { + int dx = m.t.x - m.f.x, dy = m.t.y - m.f.y; + if (m.p.p == p_king) { + if (!moved_king[c] && dy == 0) { + if (!moved_rook_l[c] && dx == -2 && table[m.f.x - 1][m.f.y].p == p_no && + table[m.f.x - 3][m.f.y].p == p_rook && + table[m.f.x - 3][m.f.y].c == c && !in_check(c, m.f.x - 1, m.f.y) && + !in_check(c, m.f.x, m.f.y)) { + return castle_short; + } else if (!moved_rook_r[c] && dx == 3 && + table[m.f.x + 1][m.f.y].p == p_no && + table[m.f.x + 2][m.f.y].p == p_no && + table[m.f.x + 4][m.f.y].p == p_rook && + table[m.f.x + 4][m.f.y].c == c && + !in_check(c, m.f.x + 1, m.f.y) && + !in_check(c, m.f.x + 2, m.f.y) && !in_check(c, m.f.x, m.f.y)) { + return castle_long; + } + } + } + return castle_no; +} + +bool is_move_legal(color c, move m) { + if (!is_move_inside(m) || is_empty(m.p) || is_enemy_of(c, m.p) || + is_friend_of(c, m.e)) + return false; + + int dx = m.t.x - m.f.x, dy = m.t.y - m.f.y; + int v_x, v_y, l; + switch (m.p.p) { + case p_pawn: + if ((dx != 0 && ((dx != 1 && dx != -1) || (dy != 1 && c == c_w) || + (dy != -1 && c == c_b) || + (is_empty(m.e) && is_same_pos(m.t, enp.p)))) || + dy < -2 || dy > 2 || (dy == 1 && c != c_w) || + (dy == 2 && + (c != c_w || m.f.y != 1 || table[m.f.x][m.f.y + 1].p != p_no)) || + (dy == -1 && c != c_b) || + (dy == -2 && + (c != c_b || m.f.y != 6 || table[m.f.x][m.f.y - 1].p != p_no)) || + (dx == 0 && !is_empty(m.e))) + return false; + break; + case p_rook: + if (dx * dy != 0) + return false; + v_x = (dx != 0) ? ((dx > 0) ? 1 : -1) : 0; + v_y = (dy != 0) ? ((dy > 0) ? 1 : -1) : 0; + for (int n = 1; n < abs(dx + dy); n++) + if (!is_empty(table[m.f.x + n * v_x][m.f.y + n * v_y])) + return false; + break; + case p_bishop: + if (abs(dx) != abs(dy)) + return false; + v_x = dx ? ((dx > 0) ? 1 : -1) : 0; + v_y = dy ? ((dy > 0) ? 1 : -1) : 0; + for (int n = 1; n < abs(dx); n++) + if (!is_empty(table[m.f.x + n * v_x][m.f.y + n * v_y])) + return false; + break; + case p_queen: + if (dx * dy != 0 && abs(dx) != abs(dy)) + return false; + v_x = dx ? ((dx > 0) ? 1 : -1) : 0; + v_y = dy ? ((dy > 0) ? 1 : -1) : 0; + l = (dx * dy == 0) ? abs(dx + dy) : abs(dx); + for (int n = 1; n < l; n++) + if (!is_empty(table[m.f.x + n * v_x][m.f.y + n * v_y])) + return false; + break; + case p_king: + if (abs(dx) > 3 || abs(dy) > 1) + return false; + if (in_check(c, m.t.x, m.t.y)) + return false; + if (abs(dx) > 1) { + if (!moved_king[c] && dy == 0) { + if (!moved_rook_l[c] && dx == -2 && table[m.f.x - 1][m.f.y].p == p_no && + table[m.f.x - 3][m.f.y].p == p_rook && + table[m.f.x - 3][m.f.y].c == c && !in_check(c, m.f.x - 1, m.f.y) && + !in_check(c, m.f.x, m.f.y)) { + return true; + } else if (!moved_rook_r[c] && dx == 3 && + table[m.f.x + 1][m.f.y].p == p_no && + table[m.f.x + 2][m.f.y].p == p_no && + table[m.f.x + 4][m.f.y].p == p_rook && + table[m.f.x + 4][m.f.y].c == c && + !in_check(c, m.f.x + 1, m.f.y) && + !in_check(c, m.f.x + 2, m.f.y) && + !in_check(c, m.f.x, m.f.y)) { + return true; + } + } + return false; + } + break; + case p_knight: + if (!((abs(dx) == 2 && abs(dy) == 1) || (abs(dx) == 1 && abs(dy) == 2))) + return false; + break; + case p_no: + return false; + break; + } + if (in_check_sim(m)) + return false; + return true; +} + +void do_move(move m) { + table[m.t.x][m.t.y] = table[m.f.x][m.f.y]; + table[m.f.x][m.f.y].p = p_no; +} + +piece_type choose_type(int fd) { + char cbuf[10] = {0}; + while (true) { + dprintf(fd, "mit kérsz?\n"); + dprintf(fd, "> "); + read(fd, cbuf, 10); + switch (cbuf[0]) { + case 'P': + return p_pawn; + case 'R': + return p_rook; + case 'N': + return p_knight; + case 'B': + return p_bishop; + case 'Q': + return p_queen; + case 'K': + return p_king; + } + } +} + +color c_c; +bool is_printing = false; +void *run_timer(void *vargp) { + while (true) { + if (!is_printing) { + dprintf(*c_fd, "\0337\r%02d:%02d > \0338", remaining_time[c_c] / 60, + remaining_time[c_c] % 60); + remaining_time[c_c]--; + if (remaining_time[c_c] <= 0) { + if (c_c == c_w) + PRINT_ALL("fehérnek lejárt az ideje, fekete nyert!\n"); + else + PRINT_ALL("feketének lejárt az ideje, fehér nyert!\n"); + raise(SIGTERM); + } + } + sleep(1); + } + return NULL; +} + +void play_game() { + PRINT_ALL("(a)scii vagy (u)nicode? [u] "); + char input_str[50]; + read(w_fd, input_str, 50); + if (input_str[0] == 'a') + modes[c_w] = mode_ascii; + else + modes[c_w] = mode_unicode; + + read(b_fd, input_str, 50); + if (input_str[0] == 'a') + modes[c_b] = mode_ascii; + else + modes[c_b] = mode_unicode; + + c_c = c_w; // current color + is_printing = true; + pthread_t thread_id; + pthread_create(&thread_id, NULL, run_timer, NULL); + + print_table(); + for (;;) { + is_printing = true; + if (c_c == c_w) + dprintf(b_fd, "fehér gondolkodik...\n"); + else + dprintf(w_fd, "fekete gondolkodik...\n"); + no_print: + if (is_checkmate(c_c)) { + if (c_c == c_w) + PRINT_ALL("\na fekete nyert!\n"); + else + PRINT_ALL("\na fehér nyert!\n"); + break; + } else if (is_stalemate(c_c)) { + PRINT_ALL("\ndöntetlen\n"); + break; + } + dprintf(*c_fd, "\n%02d:%02d > ", remaining_time[c_c] / 60, + remaining_time[c_c] % 60); + is_printing = false; + char buf[50] = {0}; + read(*c_fd, buf, 50); + is_printing = true; + if (buf[0] == 's') + goto skip; + if (buf[0] == ':') { + if (c_c == c_w) + dprintf(b_fd, buf); + else + dprintf(w_fd, buf); + goto no_print; + } + + move m = parse_move(buf); + + if (is_move_legal(c_c, m)) { + do_move(m); + + castle ct = is_castle(c_c, m); + if (ct == castle_short) { + table[m.f.x - 1][m.f.y] = table[m.f.x - 3][m.f.y]; + table[m.f.x - 3][m.f.y].p = p_no; + } else if (ct == castle_long) { + table[m.f.x + 2][m.f.y] = table[m.f.x + 4][m.f.y]; + table[m.f.x + 4][m.f.y].p = p_no; + } + + if (m.p.p == p_rook && + ((m.f.x == 7 && m.f.y == 0) || (m.f.x == 7 && m.f.y == 7))) + moved_rook_r[c_c] = true; + else if (m.p.p == p_rook && + ((m.f.x == 0 && m.f.y == 0) || (m.f.x == 0 && m.f.y == 7))) + moved_rook_l[c_c] = true; + else if (m.p.p == p_king) + moved_king[c_c] = true; + + // en passant + if (enp.valid && is_same_pos(enp.p, m.t) && m.p.p == p_pawn) + enp.to_remove->p = p_no; + enp.valid = false; + if (m.p.p == p_pawn && abs(m.f.y - m.t.y) == 2) { + enp.valid = true; + enp.to_remove = &table[m.t.x][m.t.y]; + enp.p.x = m.t.x; + enp.p.y = m.t.y + (c_c == c_w ? -1 : 1); + } + + // trade pawn + if ((m.t.y == 0 || m.t.y == 7) && m.p.p == p_pawn) + table[m.t.x][m.t.y].p = choose_type(*c_fd); + + print_table(); + print_move(m); + } else { + dprintf(*c_fd, "hiba\n"); + goto no_print; + } + + skip: + if (c_fd == &w_fd) { + c_fd = &b_fd; + c_c = c_b; + } else { + c_fd = &w_fd; + c_c = c_w; + } + } +} + +int main() { + setup_table(); + // stolen from: https://git.sr.ht/~martijnbraam/among-sus + fd_set rfds, afds; + uint16_t port = 1234; + int listen_fd, listen6_fd, new_fd, i; + socklen_t client_size; + struct sockaddr_in listen_addr = {0}, client_addr = {0}; + struct sockaddr_in6 listen6_addr = {0}; + + if ((listen_fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { + perror("IPv4 socket"); + exit(EXIT_FAILURE); + } + if ((listen6_fd = socket(PF_INET6, SOCK_STREAM, 0)) == -1) { + perror("IPv6 socket"); + exit(EXIT_FAILURE); + } + + i = 1; + if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i))) { + perror("IPv4 setsockopt"); + exit(EXIT_FAILURE); + } + + if (setsockopt(listen6_fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i))) { + perror("IPv6 setsockopt"); + exit(EXIT_FAILURE); + } + + listen_addr.sin_family = AF_INET; + listen_addr.sin_addr.s_addr = htonl(INADDR_ANY); + listen_addr.sin_port = htons(port); + + listen6_addr.sin6_family = AF_INET6; + listen6_addr.sin6_addr = in6addr_any; + listen6_addr.sin6_port = htons(port); + if (setsockopt(listen6_fd, IPPROTO_IPV6, IPV6_V6ONLY, &i, sizeof(i))) { + perror("setsockopt"); + exit(EXIT_FAILURE); + } + if (setsockopt(listen6_fd, IPPROTO_IPV6, IPV6_V6ONLY, &i, sizeof(i))) { + perror("setsockopt"); + exit(EXIT_FAILURE); + } + + if (bind(listen_fd, (struct sockaddr *)&listen_addr, sizeof(listen_addr)) < + 0) { + perror("ipv4 bind"); + return -1; + } + if (bind(listen6_fd, (struct sockaddr *)&listen6_addr, sizeof(listen6_addr)) < + 0) { + perror("ipv6 bind"); + return -1; + } + + listen(listen_fd, 5); + listen(listen6_fd, 5); + printf("Listening on :%d\n", port); + + FD_ZERO(&afds); + FD_SET(listen_fd, &afds); + FD_SET(listen6_fd, &afds); + + while (1) { + rfds = afds; + if (select(FD_SETSIZE, &rfds, NULL, NULL, NULL) < 0) { + perror("select"); + exit(EXIT_FAILURE); + } + + for (i = 0; i < FD_SETSIZE; ++i) { + if (FD_ISSET(i, &rfds)) { + if (i == listen_fd || i == listen6_fd) { + client_size = sizeof(client_addr); + new_fd = accept(i, (struct sockaddr *)&client_addr, &client_size); + if (new_fd < 0) { + perror("accept"); + exit(EXIT_FAILURE); + } + + printf("New connection from %s:%d\n", inet_ntoa(client_addr.sin_addr), + ntohs(client_addr.sin_port)); + FD_SET(new_fd, &afds); + if (w_fd == -1) { + dprintf(new_fd, "te vagy az fehérrel\n"); + w_fd = new_fd; + } else if (b_fd == -1) { + dprintf(new_fd, "te vagy a feketével\n"); + dprintf(w_fd, "belépett a fekete is, kezdhetjük!\n"); + b_fd = new_fd; + if (fork() == 0) { + play_game(); + return 0; + } else { + w_fd = -1; + b_fd = -1; + game_number++; + } + } else { + // write(new_fd, "nincs hely!\n", strlen("nincs hely!\n")); + } + } else { + close(i); + FD_CLR(i, &afds); + } + } + } + } + return 0; +} diff --git a/sakkom b/sakkom deleted file mode 100755 index 4bdd60c..0000000 Binary files a/sakkom and /dev/null differ diff --git a/sakkom.c b/sakkom.c deleted file mode 100644 index 3a7980c..0000000 --- a/sakkom.c +++ /dev/null @@ -1,740 +0,0 @@ -// SAKKOM: sakk a konzolban király! online multiplayer -// chess.com alternatíva, ami netcatet használ mint kliens -// -// do what you want -// boa - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PRINT_ALL(f_, ...) \ - do { \ - dprintf(w_fd, (f_), ##__VA_ARGS__); \ - dprintf(b_fd, (f_), ##__VA_ARGS__); \ - } while (0) - -typedef enum mode { mode_ascii, mode_unicode } mode; -mode modes[2]; -typedef enum color { c_w = 0, c_b = 1 } color; -typedef enum castle { castle_no, castle_long, castle_short } castle; - -int colors[] = {39, 30}; -char ascii_colors[] = {' ', '*'}; - -int abs(int a) { - if (a >= 0) - return a; - else - return -1 * a; -} - -char symbols[7][7] = {" ", "♟︎", "♜", "♞", "♝", "♛", "♚"}; -char ascii_symbols[7] = {' ', 'P', 'R', 'N', 'B', 'Q', 'K'}; - -typedef enum result { r_no, r_win, r_stalemate } result; -typedef enum piece_type { - p_no, - p_pawn, - p_rook, - p_knight, - p_bishop, - p_queen, - p_king -} piece_type; - -typedef struct pos { - int x; - int y; -} pos; - -typedef struct piece { - piece_type p; - color c; -} piece; - -typedef struct move { - pos f; // from - pos t; // to - piece p; // piece moved - piece e; // enemy taken -} move; - -typedef struct en_passant { - bool valid; - pos p; - piece *to_remove; -} en_passant; -en_passant enp; - -piece table[8][8]; -int w_fd = -1, b_fd = -1; -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 remaining_time[2] = {30 * 60, 30 * 60}; -int game_number = 1; - -void do_move(move m); -bool is_move_legal(color c, move m); -bool in_check(color c, int cx, int cy); -void print_table(); -void setup_table(); -void play_game(); - -bool is_same_pos(pos p1, pos p2) { return p1.x == p2.x && p1.y == p2.y; } - -bool is_empty(piece p) { return p.p == p_no; } -bool is_friend_of(color c, piece p) { return !is_empty(p) && p.c == c; } -bool is_enemy_of(color c, piece p) { return !is_empty(p) && p.c != c; } - -bool is_inside(int i) { return i >= 0 && i < 8; } - -bool is_move_inside(move m) { - return is_inside(m.f.x) && is_inside(m.f.y) && is_inside(m.t.x) && - is_inside(m.t.y); -} - -void print_table() { - if (modes[c_w] == mode_unicode) { - dprintf(w_fd, - "\n \e[43m\x1B[30m\033[1m BLACK \x1B[0m\n\n "); - for (int x = 0; x < 8; x++) { - dprintf(w_fd, " %c ", 'A' + x); - } - dprintf(w_fd, "\n \e[43m┏━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┓\x1B[0m\n"); - for (int y = 7; y >= 0; y--) { - if (y != 7) { - dprintf(w_fd, "\x1B[0m " - "\e[43m┣━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━┫\x1B[0m\n"); - } - dprintf(w_fd, " %d \e[43m┃", y + 1); - for (int x = 0; x < 8; x++) - dprintf(w_fd, "\e[43m\x1B[%dm \033[1m%s \x1B[0m\e[43m┃", - colors[table[x][y].c], symbols[table[x][y].p]); - dprintf(w_fd, "\x1B[0m %d\x1B[0m\n", y + 1); - } - dprintf(w_fd, " \e[43m┗━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┛\x1B[0m\n "); - for (int x = 0; x < 8; x++) { - dprintf(w_fd, " %c ", 'A' + x); - } - dprintf( - w_fd, - "\n\n \e[43m\x1B[39m\033[1m WHITE \x1B[0m\n\n\x1B[0m"); - } else { - dprintf(w_fd, "\n [ BLACK ]\n\n "); - for (int x = 0; x < 8; x++) { - dprintf(w_fd, " %c ", 'A' + x); - } - dprintf(w_fd, "\n +---+---+---+---+---+---+---+---+\n"); - for (int y = 7; y >= 0; y--) { - if (y != 7) { - dprintf(w_fd, " +---+---+---+---+---+---+---+---+\n"); - } - dprintf(w_fd, " %d |", y + 1); - for (int x = 0; x < 8; x++) - dprintf(w_fd, "%c%c |", ascii_colors[table[x][y].c], - ascii_symbols[table[x][y].p]); - dprintf(w_fd, " %d\n", y + 1); - } - dprintf(w_fd, " +---+---+---+---+---+---+---+---+\n "); - for (int x = 0; x < 8; x++) { - dprintf(w_fd, " %c ", 'A' + x); - } - dprintf(w_fd, "\n\n [ WHITE ]\n\n"); - } - - if (modes[c_b] == mode_unicode) { - dprintf(b_fd, - "\n \e[43m\x1B[39m\033[1m WHITE \x1B[0m\n\n "); - for (int x = 0; x < 8; x++) { - dprintf(b_fd, " %c ", 'A' + 7 - x); - } - dprintf(b_fd, "\n \e[43m┏━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┓\x1B[0m\n"); - for (int y = 0; y < 8; y++) { - if (y != 0) { - dprintf(b_fd, "\x1B[0m " - "\e[43m┣━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━┫\x1B[0m\n"); - } - dprintf(b_fd, " %d \e[43m┃", y + 1); - for (int x = 7; x >= 0; x--) - dprintf(b_fd, "\e[43m\x1B[%dm \033[1m%s \x1B[0m\e[43m┃", - colors[table[x][y].c], symbols[table[x][y].p]); - dprintf(b_fd, "\x1B[0m %d\n", y + 1); - } - dprintf(b_fd, " \e[43m┗━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┛\x1B[0m\n "); - for (int x = 0; x < 8; x++) { - dprintf(b_fd, " %c ", 'A' + 7 - x); - } - dprintf( - b_fd, - "\n\n \e[43m\x1B[30m\033[1m BLACK \x1B[0m\n\n\x1B[0m"); - } else { - dprintf(b_fd, "\n [ WHITE ]\n\n "); - for (int x = 0; x < 8; x++) { - dprintf(b_fd, " %c ", 'A' + 7 - x); - } - dprintf(b_fd, "\n +---+---+---+---+---+---+---+---+\n"); - for (int y = 0; y < 8; y++) { - if (y != 0) { - dprintf(b_fd, " +---+---+---+---+---+---+---+---+\n"); - } - dprintf(b_fd, " %d |", y + 1); - for (int x = 7; x >= 0; x--) - dprintf(b_fd, "%c%c |", ascii_colors[table[x][y].c], - ascii_symbols[table[x][y].p]); - dprintf(b_fd, " %d\n", y + 1); - } - dprintf(b_fd, " +---+---+---+---+---+---+---+---+\n "); - for (int x = 0; x < 8; x++) { - dprintf(b_fd, " %c ", 'A' + 7 - x); - } - dprintf(b_fd, "\n\n [ BLACK ]\n\n"); - } -} - -bool in_check(color c, int cx, int cy) { - move m; - m.t.x = cx; - m.t.y = cy; - m.e = table[cx][cy]; - for (int y = 0; y < 8; y++) { - for (int x = 0; x < 8; x++) { - if (cx == x && cy == y) - continue; - m.f.x = x; - m.f.y = y; - m.p = table[x][y]; - if (table[x][y].c != c && is_move_legal(m.p.c, m)) { - return true; - } - } - } - return false; -} - -bool in_check_sim(move m) { - do_move(m); - bool res = false; - 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 == m.p.c) { - res = in_check(m.p.c, x, y); - goto out; - } - } - } -out: - table[m.f.x][m.f.y] = m.p; - table[m.t.x][m.t.y] = m.e; - return res; -} - -void setup_table() { - table[0][0] = (piece){p_rook, c_w}; - table[1][0] = (piece){p_knight, c_w}; - table[2][0] = (piece){p_bishop, c_w}; - table[3][0] = (piece){p_king, c_w}; - table[4][0] = (piece){p_queen, c_w}; - 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}; - - 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}; -} - -pos find_king(color c) { - 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) - return (pos){x, y}; - return (pos){-1, -1}; -} - -bool is_stalemate(color c) { - pos kp = find_king(c); - if (in_check(c, kp.x, kp.y)) - return false; - - move m; - for (m.f.y = 0; m.f.y < 8; m.f.y++) { - for (m.f.x = 0; m.f.x < 8; m.f.x++) { - if (table[m.f.x][m.f.y].c == c) { - m.p = table[m.f.x][m.f.y]; - for (m.t.y = 0; m.t.y < 8; m.t.y++) { - for (m.t.x = 0; m.t.x < 8; m.t.x++) { - if (m.t.x == m.f.x && m.t.y == m.f.y) - continue; - m.e = table[m.t.x][m.t.y]; - if (is_move_legal(c, m)) { - return false; - } - } - } - } - } - } - return true; -} - -bool is_checkmate(color c) { - // probably the most simple and least efficient way to solve this problem - move m; - for (m.f.y = 0; m.f.y < 8; m.f.y++) { - for (m.f.x = 0; m.f.x < 8; m.f.x++) { - if (table[m.f.x][m.f.y].c == c) { - m.p = table[m.f.x][m.f.y]; - for (m.t.y = 0; m.t.y < 8; m.t.y++) { - for (m.t.x = 0; m.t.x < 8; m.t.x++) { - m.e = table[m.t.x][m.t.y]; - if (is_move_legal(c, m)) { - return false; - } - } - } - } - } - } - return true; -} - -int move_num = 1; -void print_move(move m) { - char buf[20]; - int n = 0; - buf[n++] = ascii_symbols[m.p.p]; - buf[n++] = m.f.x + 'a'; - buf[n++] = m.f.y + '1'; - buf[n++] = ' '; - if (m.e.p != p_no) - buf[n++] = ascii_symbols[m.p.p]; - buf[n++] = m.t.x + 'a'; - buf[n++] = m.t.y + '1'; - buf[n++] = '\n'; - buf[n++] = '\0'; - if (m.p.c == c_w) { - PRINT_ALL("%d. white: ", move_num); - } else { - PRINT_ALL("%d. black: ", move_num); - move_num++; - } - PRINT_ALL(buf); -} - -move parse_move(char buf[50]) { - move m; - - m.f.x = buf[0] - 'a'; - m.f.y = buf[1] - '1'; - m.t.x = buf[3] - 'a'; - m.t.y = buf[4] - '1'; - - m.p = table[m.f.x][m.f.y]; - m.e = table[m.t.x][m.t.y]; - - return m; -} - -castle is_castle(color c, move m) { - int dx = m.t.x - m.f.x, dy = m.t.y - m.f.y; - if (m.p.p == p_king) { - if (!moved_king[c] && dy == 0) { - if (!moved_rook_l[c] && dx == -2 && table[m.f.x - 1][m.f.y].p == p_no && - table[m.f.x - 3][m.f.y].p == p_rook && - table[m.f.x - 3][m.f.y].c == c && !in_check(c, m.f.x - 1, m.f.y) && - !in_check(c, m.f.x, m.f.y)) { - return castle_short; - } else if (!moved_rook_r[c] && dx == 3 && - table[m.f.x + 1][m.f.y].p == p_no && - table[m.f.x + 2][m.f.y].p == p_no && - table[m.f.x + 4][m.f.y].p == p_rook && - table[m.f.x + 4][m.f.y].c == c && - !in_check(c, m.f.x + 1, m.f.y) && - !in_check(c, m.f.x + 2, m.f.y) && !in_check(c, m.f.x, m.f.y)) { - return castle_long; - } - } - } - return castle_no; -} - -bool is_move_legal(color c, move m) { - if (!is_move_inside(m) || is_empty(m.p) || is_enemy_of(c, m.p) || - is_friend_of(c, m.e)) - return false; - - int dx = m.t.x - m.f.x, dy = m.t.y - m.f.y; - int v_x, v_y, l; - switch (m.p.p) { - case p_pawn: - if ((dx != 0 && ((dx != 1 && dx != -1) || (dy != 1 && c == c_w) || - (dy != -1 && c == c_b) || - (is_empty(m.e) && is_same_pos(m.t, enp.p)))) || - dy < -2 || dy > 2 || (dy == 1 && c != c_w) || - (dy == 2 && - (c != c_w || m.f.y != 1 || table[m.f.x][m.f.y + 1].p != p_no)) || - (dy == -1 && c != c_b) || - (dy == -2 && - (c != c_b || m.f.y != 6 || table[m.f.x][m.f.y - 1].p != p_no)) || - (dx == 0 && !is_empty(m.e))) - return false; - break; - case p_rook: - if (dx * dy != 0) - return false; - v_x = (dx != 0) ? ((dx > 0) ? 1 : -1) : 0; - v_y = (dy != 0) ? ((dy > 0) ? 1 : -1) : 0; - for (int n = 1; n < abs(dx + dy); n++) - if (!is_empty(table[m.f.x + n * v_x][m.f.y + n * v_y])) - return false; - break; - case p_bishop: - if (abs(dx) != abs(dy)) - return false; - v_x = dx ? ((dx > 0) ? 1 : -1) : 0; - v_y = dy ? ((dy > 0) ? 1 : -1) : 0; - for (int n = 1; n < abs(dx); n++) - if (!is_empty(table[m.f.x + n * v_x][m.f.y + n * v_y])) - return false; - break; - case p_queen: - if (dx * dy != 0 && abs(dx) != abs(dy)) - return false; - v_x = dx ? ((dx > 0) ? 1 : -1) : 0; - v_y = dy ? ((dy > 0) ? 1 : -1) : 0; - l = (dx * dy == 0) ? abs(dx + dy) : abs(dx); - for (int n = 1; n < l; n++) - if (!is_empty(table[m.f.x + n * v_x][m.f.y + n * v_y])) - return false; - break; - case p_king: - if (abs(dx) > 3 || abs(dy) > 1) - return false; - if (in_check(c, m.t.x, m.t.y)) - return false; - if (abs(dx) > 1) { - if (!moved_king[c] && dy == 0) { - if (!moved_rook_l[c] && dx == -2 && table[m.f.x - 1][m.f.y].p == p_no && - table[m.f.x - 3][m.f.y].p == p_rook && - table[m.f.x - 3][m.f.y].c == c && !in_check(c, m.f.x - 1, m.f.y) && - !in_check(c, m.f.x, m.f.y)) { - return true; - } else if (!moved_rook_r[c] && dx == 3 && - table[m.f.x + 1][m.f.y].p == p_no && - table[m.f.x + 2][m.f.y].p == p_no && - table[m.f.x + 4][m.f.y].p == p_rook && - table[m.f.x + 4][m.f.y].c == c && - !in_check(c, m.f.x + 1, m.f.y) && - !in_check(c, m.f.x + 2, m.f.y) && - !in_check(c, m.f.x, m.f.y)) { - return true; - } - } - return false; - } - break; - case p_knight: - if (!((abs(dx) == 2 && abs(dy) == 1) || (abs(dx) == 1 && abs(dy) == 2))) - return false; - break; - case p_no: - return false; - break; - } - if (in_check_sim(m)) - return false; - return true; -} - -void do_move(move m) { - table[m.t.x][m.t.y] = table[m.f.x][m.f.y]; - table[m.f.x][m.f.y].p = p_no; -} - -piece_type choose_type(int fd) { - char cbuf[10] = {0}; - while (true) { - dprintf(fd, "mit kérsz?\n"); - dprintf(fd, "> "); - read(fd, cbuf, 10); - switch (cbuf[0]) { - case 'P': - return p_pawn; - case 'R': - return p_rook; - case 'N': - return p_knight; - case 'B': - return p_bishop; - case 'Q': - return p_queen; - case 'K': - return p_king; - } - } -} - -color c_c; -bool is_printing = false; -void *run_timer(void *vargp) { - while (true) { - if (!is_printing) { - dprintf(*c_fd, "\0337\r%02d:%02d > \0338", remaining_time[c_c] / 60, - remaining_time[c_c] % 60); - remaining_time[c_c]--; - if (remaining_time[c_c] <= 0) { - if (c_c == c_w) - PRINT_ALL("fehérnek lejárt az ideje, fekete nyert!\n"); - else - PRINT_ALL("feketének lejárt az ideje, fehér nyert!\n"); - raise(SIGTERM); - } - } - sleep(1); - } - return NULL; -} - -void play_game() { - PRINT_ALL("(a)scii vagy (u)nicode? [u] "); - char input_str[50]; - read(w_fd, input_str, 50); - if (input_str[0] == 'a') - modes[c_w] = mode_ascii; - else - modes[c_w] = mode_unicode; - - read(b_fd, input_str, 50); - if (input_str[0] == 'a') - modes[c_b] = mode_ascii; - else - modes[c_b] = mode_unicode; - - c_c = c_w; // current color - is_printing = true; - pthread_t thread_id; - pthread_create(&thread_id, NULL, run_timer, NULL); - - print_table(); - for (;;) { - is_printing = true; - if (c_c == c_w) - dprintf(b_fd, "fehér gondolkodik...\n"); - else - dprintf(w_fd, "fekete gondolkodik...\n"); - no_print: - if (is_checkmate(c_c)) { - if (c_c == c_w) - PRINT_ALL("\na fekete nyert!\n"); - else - PRINT_ALL("\na fehér nyert!\n"); - break; - } else if (is_stalemate(c_c)) { - PRINT_ALL("\ndöntetlen\n"); - break; - } - dprintf(*c_fd, "\n%02d:%02d > ", remaining_time[c_c] / 60, - remaining_time[c_c] % 60); - is_printing = false; - char buf[50] = {0}; - read(*c_fd, buf, 50); - is_printing = true; - if (buf[0] == 's') - goto skip; - if (buf[0] == ':') { - if (c_c == c_w) - dprintf(b_fd, buf); - else - dprintf(w_fd, buf); - goto no_print; - } - - move m = parse_move(buf); - - if (is_move_legal(c_c, m)) { - do_move(m); - - castle ct = is_castle(c_c, m); - if (ct == castle_short) { - table[m.f.x - 1][m.f.y] = table[m.f.x - 3][m.f.y]; - table[m.f.x - 3][m.f.y].p = p_no; - } else if (ct == castle_long) { - table[m.f.x + 2][m.f.y] = table[m.f.x + 4][m.f.y]; - table[m.f.x + 4][m.f.y].p = p_no; - } - - if (m.p.p == p_rook && - ((m.f.x == 7 && m.f.y == 0) || (m.f.x == 7 && m.f.y == 7))) - moved_rook_r[c_c] = true; - else if (m.p.p == p_rook && - ((m.f.x == 0 && m.f.y == 0) || (m.f.x == 0 && m.f.y == 7))) - moved_rook_l[c_c] = true; - else if (m.p.p == p_king) - moved_king[c_c] = true; - - // en passant - if (enp.valid && is_same_pos(enp.p, m.t) && m.p.p == p_pawn) - enp.to_remove->p = p_no; - enp.valid = false; - if (m.p.p == p_pawn && abs(m.f.y - m.t.y) == 2) { - enp.valid = true; - enp.to_remove = &table[m.t.x][m.t.y]; - enp.p.x = m.t.x; - enp.p.y = m.t.y + (c_c == c_w ? -1 : 1); - } - - // trade pawn - if ((m.t.y == 0 || m.t.y == 7) && m.p.p == p_pawn) - table[m.t.x][m.t.y].p = choose_type(*c_fd); - - print_table(); - print_move(m); - } else { - dprintf(*c_fd, "hiba\n"); - goto no_print; - } - - skip: - if (c_fd == &w_fd) { - c_fd = &b_fd; - c_c = c_b; - } else { - c_fd = &w_fd; - c_c = c_w; - } - } -} - -int main() { - setup_table(); - // stolen from: https://git.sr.ht/~martijnbraam/among-sus - fd_set rfds, afds; - uint16_t port = 1234; - int listen_fd, listen6_fd, new_fd, i; - socklen_t client_size; - struct sockaddr_in listen_addr = {0}, client_addr = {0}; - struct sockaddr_in6 listen6_addr = {0}; - - if ((listen_fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { - perror("IPv4 socket"); - exit(EXIT_FAILURE); - } - if ((listen6_fd = socket(PF_INET6, SOCK_STREAM, 0)) == -1) { - perror("IPv6 socket"); - exit(EXIT_FAILURE); - } - - i = 1; - if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i))) { - perror("IPv4 setsockopt"); - exit(EXIT_FAILURE); - } - - if (setsockopt(listen6_fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i))) { - perror("IPv6 setsockopt"); - exit(EXIT_FAILURE); - } - - listen_addr.sin_family = AF_INET; - listen_addr.sin_addr.s_addr = htonl(INADDR_ANY); - listen_addr.sin_port = htons(port); - - listen6_addr.sin6_family = AF_INET6; - listen6_addr.sin6_addr = in6addr_any; - listen6_addr.sin6_port = htons(port); - if (setsockopt(listen6_fd, IPPROTO_IPV6, IPV6_V6ONLY, &i, sizeof(i))) { - perror("setsockopt"); - exit(EXIT_FAILURE); - } - if (setsockopt(listen6_fd, IPPROTO_IPV6, IPV6_V6ONLY, &i, sizeof(i))) { - perror("setsockopt"); - exit(EXIT_FAILURE); - } - - if (bind(listen_fd, (struct sockaddr *)&listen_addr, sizeof(listen_addr)) < - 0) { - perror("ipv4 bind"); - return -1; - } - if (bind(listen6_fd, (struct sockaddr *)&listen6_addr, sizeof(listen6_addr)) < - 0) { - perror("ipv6 bind"); - return -1; - } - - listen(listen_fd, 5); - listen(listen6_fd, 5); - printf("Listening on :%d\n", port); - - FD_ZERO(&afds); - FD_SET(listen_fd, &afds); - FD_SET(listen6_fd, &afds); - - while (1) { - rfds = afds; - if (select(FD_SETSIZE, &rfds, NULL, NULL, NULL) < 0) { - perror("select"); - exit(EXIT_FAILURE); - } - - for (i = 0; i < FD_SETSIZE; ++i) { - if (FD_ISSET(i, &rfds)) { - if (i == listen_fd || i == listen6_fd) { - client_size = sizeof(client_addr); - new_fd = accept(i, (struct sockaddr *)&client_addr, &client_size); - if (new_fd < 0) { - perror("accept"); - exit(EXIT_FAILURE); - } - - printf("New connection from %s:%d\n", inet_ntoa(client_addr.sin_addr), - ntohs(client_addr.sin_port)); - FD_SET(new_fd, &afds); - if (w_fd == -1) { - dprintf(new_fd, "te vagy az fehérrel\n"); - w_fd = new_fd; - } else if (b_fd == -1) { - dprintf(new_fd, "te vagy a feketével\n"); - dprintf(w_fd, "belépett a fekete is, kezdhetjük!\n"); - b_fd = new_fd; - if (fork() == 0) { - play_game(); - return 0; - } else { - w_fd = -1; - b_fd = -1; - game_number++; - } - } else { - // write(new_fd, "nincs hely!\n", strlen("nincs hely!\n")); - } - } else { - close(i); - FD_CLR(i, &afds); - } - } - } - } - return 0; -} -- cgit v1.2.3