aboutsummaryrefslogtreecommitdiffstats
path: root/ajedrez.c
diff options
context:
space:
mode:
Diffstat (limited to 'ajedrez.c')
-rw-r--r--ajedrez.c740
1 files changed, 740 insertions, 0 deletions
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 <arpa/inet.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <time.h>
+#include <unistd.h>
+
+#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;
+}
Un proyecto texto-plano.xyz