diff options
| -rw-r--r-- | build.c | 10 | ||||
| -rw-r--r-- | include/bitboard.h (renamed from src/bitboard.h) | 0 | ||||
| -rw-r--r-- | include/engine/moves.h (renamed from src/engine/moves.h) | 0 | ||||
| -rw-r--r-- | include/fen.h (renamed from src/fen.h) | 0 | ||||
| -rw-r--r-- | include/ints.h (renamed from src/ints.h) | 0 | ||||
| -rw-r--r-- | include/ipc.h (renamed from src/ipc.h) | 24 | ||||
| -rw-r--r-- | include/uci.h (renamed from src/uci.h) | 0 | ||||
| -rw-r--r-- | include/uci/command.h (renamed from src/uci/command.h) | 0 | ||||
| -rw-r--r-- | include/uci/response.h (renamed from src/uci/response.h) | 5 | ||||
| -rw-r--r-- | include/uci/state.h (renamed from src/uci/state.h) | 4 | ||||
| -rw-r--r-- | resources/uci/UCI-Protocol-Specification.txt (renamed from src/uci/UCI-Protocol-Specification.txt) | 0 | ||||
| -rw-r--r-- | resources/uci/draft-1.pdf (renamed from src/uci/draft-1.pdf) | bin | 593597 -> 593597 bytes | |||
| -rw-r--r-- | resources/uci/draft-2.pdf (renamed from src/uci/draft-2.pdf) | bin | 75147 -> 75147 bytes | |||
| -rw-r--r-- | resources/uci/uci_min.txt (renamed from src/uci/uci_min.txt) | 0 | ||||
| -rw-r--r-- | src/engine.c | 105 | ||||
| -rw-r--r-- | src/engine/moves.c | 4 | ||||
| -rw-r--r-- | src/engine/moves/bishop.c | 2 | ||||
| -rw-r--r-- | src/engine/moves/king.c | 2 | ||||
| -rw-r--r-- | src/engine/moves/knight.c | 2 | ||||
| -rw-r--r-- | src/engine/moves/pawn.c | 2 | ||||
| -rw-r--r-- | src/engine/moves/queen.c | 2 | ||||
| -rw-r--r-- | src/engine/moves/rook.c | 2 | ||||
| -rw-r--r-- | src/engine/moves/vec.c | 2 | ||||
| -rw-r--r-- | src/ipc.c | 18 | ||||
| -rw-r--r-- | src/log.c | 29 | ||||
| -rw-r--r-- | src/logger/logger.c | 5 | ||||
| -rw-r--r-- | src/logger/logger.h | 67 | ||||
| -rw-r--r-- | src/server.c | 190 | ||||
| -rw-r--r-- | src/server/base64.c | 34 | ||||
| -rw-r--r-- | src/server/comms.c | 68 | ||||
| -rw-r--r-- | src/server/ws_key.c | 36 | ||||
| -rw-r--r-- | src/uci.c | 8 | ||||
| -rw-r--r-- | src/uci/command.c | 2 | ||||
| -rw-r--r-- | src/uci/response.c | 79 | ||||
| -rw-r--r-- | src/uci/state.c | 8 | ||||
| -rw-r--r-- | tests/find_tests.c (renamed from generate/find_tests.c) | 4 | ||||
| -rw-r--r-- | tests/generated.c | 25 | ||||
| -rw-r--r-- | tests/main.c | 2 |
38 files changed, 253 insertions, 488 deletions
@@ -6,7 +6,11 @@ #include <time.h> #include <string.h> -#define CC "gcc"//, "-O3" +#define GLOBAL_INCLUDE "-Iinclude/" +#define ENGINE_INCLUDE "-Iinclude/engine" +#define UCI_INCLUDE "-Iinclude/uci" + +#define CC "gcc", "-fsanitize=address", "-g", GLOBAL_INCLUDE #define ENGINE_O "output/engine.o" #define UCI_O "output/uci.o" #define MAIN_O "output/main.o" @@ -109,8 +113,8 @@ int uci_mode(int run_mode) { } RUN_CMD({CC, "-c", "src/ipc.c", "-o", IPC_O, NULL}); - RUN_CMD({CC, "-c", "src/engine.c", "-o", ENGINE_O, NULL}); - RUN_CMD({CC, "-c", "src/uci.c", "-o", UCI_O, NULL}); + RUN_CMD({CC, ENGINE_INCLUDE, "-c", "src/engine.c", "-o", ENGINE_O, NULL}); + RUN_CMD({CC, UCI_INCLUDE, "-c", "src/uci.c", "-o", UCI_O, NULL}); RUN_CMD({CC, UCI_O, ENGINE_O, IPC_O, "-o", MAIN_O, NULL}); return status != 0; } diff --git a/src/bitboard.h b/include/bitboard.h index ecd8c35..ecd8c35 100644 --- a/src/bitboard.h +++ b/include/bitboard.h diff --git a/src/engine/moves.h b/include/engine/moves.h index 86c4844..86c4844 100644 --- a/src/engine/moves.h +++ b/include/engine/moves.h diff --git a/src/fen.h b/include/fen.h index d45240e..d45240e 100644 --- a/src/fen.h +++ b/include/fen.h diff --git a/src/ints.h b/include/ints.h index 4a0cfe3..4a0cfe3 100644 --- a/src/ints.h +++ b/include/ints.h diff --git a/src/ipc.h b/include/ipc.h index 35b109b..90a2bcc 100644 --- a/src/ipc.h +++ b/include/ipc.h @@ -3,8 +3,8 @@ // NOT TRUE IPC: I REALISED I AM STUPID AND COULD HAVE JUST USED THREADS -#include <stdlib.h> #include <sys/mman.h> +#include <stdlib.h> #include "fen.h" #include "uci/state.h" @@ -16,6 +16,8 @@ typedef struct { } comm_moves; struct engine_message { + int id; + int ready; int depth; @@ -27,6 +29,9 @@ struct engine_message { int hashfull; int tbhits; int time; + + int mate; + bool node_limit; comm_moves pv; struct uci_move best_move; @@ -53,4 +58,21 @@ typedef struct { comm_moves comm_moves_init(); void add_comm_move(comm_moves *moves, struct uci_move move); +struct go_args { + comm_moves searchmoves; + bool ponder; + int wtime; + int btime; + int winc; + int binc; + int movestogo; + int depth; + int nodes; + int mate; + int movetime; + bool infinite; + int perft; +}; +bool should_continue(struct engine_message *message, struct go_args* go); + #endif // IPC_H diff --git a/src/uci.h b/include/uci.h index b3ee4cc..b3ee4cc 100644 --- a/src/uci.h +++ b/include/uci.h diff --git a/src/uci/command.h b/include/uci/command.h index ba9c51d..ba9c51d 100644 --- a/src/uci/command.h +++ b/include/uci/command.h diff --git a/src/uci/response.h b/include/uci/response.h index 16652d2..320b1f0 100644 --- a/src/uci/response.h +++ b/include/uci/response.h @@ -1,3 +1,6 @@ +#ifndef RESPONSE_H +#define RESPONSE_H + #include "command.h" #include "state.h" #include "../ipc.h" @@ -17,3 +20,5 @@ void handle_active( ucicmd cmd ); void handle_halt(uci_state *state, ucicmd cmd); + +#endif // RESPONSE_H diff --git a/src/uci/state.h b/include/uci/state.h index 9c59a3a..a1df891 100644 --- a/src/uci/state.h +++ b/include/uci/state.h @@ -82,8 +82,12 @@ typedef struct { bool debug; atomic_int go; + atomic_int go_ready_receive; atomic_int quit; + atomic_int stop; + atomic_int cleanup; + void* go_args; // TODO: fix the information flow so i don't need to do this trick position_t position; struct uci_move *moves; int moves_count; diff --git a/src/uci/UCI-Protocol-Specification.txt b/resources/uci/UCI-Protocol-Specification.txt index f28b730..f28b730 100644 --- a/src/uci/UCI-Protocol-Specification.txt +++ b/resources/uci/UCI-Protocol-Specification.txt diff --git a/src/uci/draft-1.pdf b/resources/uci/draft-1.pdf Binary files differindex 9c68adb..9c68adb 100644 --- a/src/uci/draft-1.pdf +++ b/resources/uci/draft-1.pdf diff --git a/src/uci/draft-2.pdf b/resources/uci/draft-2.pdf Binary files differindex d0d4707..d0d4707 100644 --- a/src/uci/draft-2.pdf +++ b/resources/uci/draft-2.pdf diff --git a/src/uci/uci_min.txt b/resources/uci/uci_min.txt index 58a85b6..58a85b6 100644 --- a/src/uci/uci_min.txt +++ b/resources/uci/uci_min.txt diff --git a/src/engine.c b/src/engine.c index a063520..dc1f54e 100644 --- a/src/engine.c +++ b/src/engine.c @@ -2,49 +2,60 @@ #include <string.h> #include <unistd.h> #include <pthread.h> +#include "fcntl.h" #include "bitboard.h" -#include "engine/moves.h" +#include "moves.h" #include "fen.h" -#include "fcntl.h" #include "uci.h" #include "ipc.h" -// TODO: implement break conditions from the go command struct thread_args { int id; int stop; position_t position; + struct go_args *go_args; struct engine_message *message; }; + void *engine_thread(void *_args) { + printf("NIGGGGA\n"); struct thread_args *args = (struct thread_args*)_args; + args->stop = 0; - int k = 0; - while (k < 10) { - if (args->stop) continue; + int depth = 0; + while (true) { struct engine_message *message = args->message; - - k++; - message->depth = 69; + message->depth = depth++; message->multipv = args->id; message->pv = comm_moves_init(); + + // pseudo engine work + for (volatile int k = 0; k < 1000000000; k++) {} + add_comm_move(&message->pv, (struct uci_move) { 14, 24 }); - if (k == 10) { + if (args->stop || !should_continue(message, args->go_args)) { message->best_move = (struct uci_move) { 12, 24 }; message->ponder = (struct uci_move) { 42, 54 }; + message->next = NULL; + message->ready = 1; + break; } message->next = malloc(sizeof(struct engine_message*)); + message->next->ready = 0; message->ready = 1; args->message = message->next; } + + args->stop = 2; } struct threads { pthread_t *threads; struct thread_args* args; + struct go_args *go_args; engine_messages *engine_messages; size_t count; size_t capacity; @@ -53,24 +64,25 @@ struct threads { }; void increase_threads(struct threads *threads, size_t change) { + int old_capacity = threads->capacity; if (threads->count + change > threads->capacity) { - threads->capacity = threads->count + change + 16; // TODO: maybe round it to the upper power of 2 + threads->capacity = threads->count + change + 16; } threads->threads = threads->threads == NULL - ? malloc(sizeof(*threads->threads) * threads->capacity) - : realloc(threads->threads, sizeof(*threads->threads) * threads->capacity); + ? malloc(sizeof(pthread_t) * threads->capacity) + : realloc(threads->threads, sizeof(pthread_t) * threads->capacity); threads->args = threads->args == NULL - ? malloc(sizeof(*threads->args) * threads->capacity) - : realloc(threads->args, sizeof(*threads->args) * threads->capacity); + ? malloc(sizeof(struct thread_args) * threads->capacity) + : realloc(threads->args, sizeof(struct thread_args) * threads->capacity); threads->engine_messages->data = threads->engine_messages->data == NULL - ? malloc(sizeof(*threads->engine_messages->data) * threads->capacity) + ? malloc(sizeof(struct engine_message*) * threads->capacity) : realloc( - threads->engine_messages->data, - sizeof(*threads->engine_messages->data) * threads->capacity - ); + threads->engine_messages->data, + sizeof(struct engine_message*) * threads->capacity + ); for (int i = threads->count; i < threads->count + change; i++) { threads->engine_messages->data[i] = malloc(sizeof(struct engine_message)); @@ -79,6 +91,7 @@ void increase_threads(struct threads *threads, size_t change) { i, 0, threads->sharing_position, + threads->go_args, threads->engine_messages->data[i], }; pthread_create( @@ -94,7 +107,9 @@ void increase_threads(struct threads *threads, size_t change) { void decrease_threads(struct threads *threads, size_t change) { for (int i = 0; i < change; i++) { - free(threads->engine_messages->data[threads->count - i - 1]); + struct engine_message *item = threads->engine_messages->data[i]; + threads->engine_messages->data[i] = NULL; + free(item); pthread_cancel(threads->threads[threads->count - i - 1]); } threads->count -= change; @@ -102,17 +117,33 @@ void decrease_threads(struct threads *threads, size_t change) { } void set_threads(struct threads *threads, size_t new_size) { - if (new_size > threads->count) { + if (new_size >= threads->count) { increase_threads(threads, new_size - threads->count); } else { decrease_threads(threads, threads->count - new_size); } } +void send_stop_signal(struct threads *threads) { + for (int i = 0; i < threads->count; i++) { + if (threads->args[i].stop) continue; + threads->args[i].stop = 1; + } +} +bool all_stopped(struct threads *threads) { + if (threads->count == 0) return false; + for (int i = 0; i < threads->count; i++) { + if (threads->args[i].stop == 2) continue; + return false; + } + return true; +} + // TODO: someday fix that some structs have typedef, some dont int main(int argc, char** argv) { comms *comms = malloc(sizeof(*comms)); comms->engine_messages = malloc(sizeof(*comms->engine_messages)); + comms->engine_messages->data = NULL; comms->uci_state_initialized = 0; pthread_t uci_thread; @@ -123,24 +154,44 @@ int main(int argc, char** argv) { struct threads engine_threads = {0}; engine_threads.engine_messages = comms->engine_messages; - int initialized = 0; while (1) { if (atomic_load(&comms->state.quit)) break; - if (!atomic_load(&comms->state.go)) continue; - - if (initialized == 0) { + if (atomic_load(&comms->state.cleanup)) { + set_threads(&engine_threads, 0); + for (int i = 0; i < engine_threads.count; i++) { + engine_threads.args[i].stop = -1; + } + } + if (atomic_load(&comms->state.go)) { + printf("going\n"); engine_threads.sharing_position = comms->state.position; + engine_threads.go_args = (struct go_args*)comms->state.go_args; set_threads(&engine_threads, comms->state.threads); - initialized = 1; + atomic_store(&comms->state.go, 0); + atomic_store(&comms->state.go_ready_receive, 1); + } + if (atomic_load(&comms->state.stop)) { + printf("stopping\n"); + send_stop_signal(&engine_threads); + if (!all_stopped(&engine_threads)) continue; + set_threads(&engine_threads, 0); + for (int i = 0; i < engine_threads.count; i++) { + engine_threads.args[i].stop = -1; + } + atomic_store(&comms->state.stop, 0); } } + pthread_cancel(uci_thread); set_threads(&engine_threads, 0); free(engine_threads.threads); free(engine_threads.args); - free(comms->engine_messages); + for (int i = 0; i < engine_threads.count; i++) { + free(engine_threads.engine_messages->data[i]); + } free(comms->engine_messages->data); + free(comms->engine_messages); free(comms); return 0; } diff --git a/src/engine/moves.c b/src/engine/moves.c index 797e770..56bb47d 100644 --- a/src/engine/moves.c +++ b/src/engine/moves.c @@ -1,5 +1,6 @@ #include "moves.h" -#include "../bitboard.h" +#include "bitboard.h" + #include "moves/vec.c" #include "moves/king.c" #include "moves/knight.c" @@ -7,6 +8,7 @@ #include "moves/rook.c" #include "moves/bishop.c" #include "moves/queen.c" + #include <assert.h> void get_moves(moves_t* moves, position_t position) { diff --git a/src/engine/moves/bishop.c b/src/engine/moves/bishop.c index c51d405..b69be57 100644 --- a/src/engine/moves/bishop.c +++ b/src/engine/moves/bishop.c @@ -1,4 +1,4 @@ -#include "../moves.h" +#include "moves.h" void __forloop_bishop_moves_gen( moves_t* moves, diff --git a/src/engine/moves/king.c b/src/engine/moves/king.c index e954ae5..1775e7f 100644 --- a/src/engine/moves/king.c +++ b/src/engine/moves/king.c @@ -1,4 +1,4 @@ -#include "../moves.h" +#include "moves.h" #include <stdio.h> void get_king_moves(moves_t* moves, position_t position) { diff --git a/src/engine/moves/knight.c b/src/engine/moves/knight.c index 20d072f..e7615f0 100644 --- a/src/engine/moves/knight.c +++ b/src/engine/moves/knight.c @@ -1,4 +1,4 @@ -#include "../moves.h" +#include "moves.h" bitboard_t knight_moves[64] = { 132096ULL, diff --git a/src/engine/moves/pawn.c b/src/engine/moves/pawn.c index 0b8993f..d9757f4 100644 --- a/src/engine/moves/pawn.c +++ b/src/engine/moves/pawn.c @@ -1,4 +1,4 @@ -#include "../moves.h" +#include "moves.h" #define add_promote_moves(other_flags) \ add_move(moves, from, to, .flags = other_flags | MOVE_PROMOTE_Q); \ diff --git a/src/engine/moves/queen.c b/src/engine/moves/queen.c index 9e6e5c4..bdf96fc 100644 --- a/src/engine/moves/queen.c +++ b/src/engine/moves/queen.c @@ -1,4 +1,4 @@ -#include "../moves.h" +#include "moves.h" void get_queen_moves(moves_t* moves, position_t position) { assert_valid_position(position); diff --git a/src/engine/moves/rook.c b/src/engine/moves/rook.c index dfd9c32..3e0ac95 100644 --- a/src/engine/moves/rook.c +++ b/src/engine/moves/rook.c @@ -1,4 +1,4 @@ -#include "../moves.h" +#include "moves.h" void __forloop_rook_moves_gen( moves_t* moves, diff --git a/src/engine/moves/vec.c b/src/engine/moves/vec.c index 6a5f3c6..9ded70d 100644 --- a/src/engine/moves/vec.c +++ b/src/engine/moves/vec.c @@ -1,4 +1,4 @@ -#include "../moves.h" +#include "moves.h" #include <assert.h> #include <stdlib.h> @@ -22,6 +22,24 @@ void add_comm_move(comm_moves *moves, struct uci_move move) { moves->moves[moves->count++] = move; } + +bool should_continue(struct engine_message *message, struct go_args* go) { + int depth; + int nodes; + int mate; + if (go->depth && (go->depth >= message->depth)) { + return false; + } + if (go->nodes && (go->nodes >= message->nodes)) { + message->node_limit = true; + return false; + } + if (go->mate && message->mate && (go->mate <= message->mate)) { + return false; + } + return true; +} + #include "fen.c" #include "bitboard.c" diff --git a/src/log.c b/src/log.c deleted file mode 100644 index 64d738c..0000000 --- a/src/log.c +++ /dev/null @@ -1,29 +0,0 @@ -#include <stdio.h> -#include "ipc.c" -#include "unistd.h" - -int main(int argc, char** argv) { - mqd_t rx = mq_open("/logs", O_CREAT | O_RDONLY, 0666, &attr); - mqd_t _ = mq_open("/server_to_engine", O_CREAT, 0666, &attr); - _ = mq_open("/engine_to_server", O_CREAT, 0666, &attr); - - for (int i = 1; i < argc; i++) { - printf("Running: %s\n", argv[i]); - if (fork() == 0) { - char* new_argv[] = {argv[i], NULL}; - execvp(argv[i], new_argv); - } - } - - while (1) { - char* buf = read_queue(rx); - if (buf[0] == 'e') { - printf("[\x1b[31mERRO\x1b[0m] %s\n", buf + 1); - } else if (buf[0] == 'w') { - printf("[\x1b[1;33mWARN\x1b[0m] %s\n", buf + 1); - } else if (buf[0] == 'i') { - printf("[\x1b[32mINFO\x1b[0m] %s\n", buf + 1); - } - free(buf); - } -} diff --git a/src/logger/logger.c b/src/logger/logger.c deleted file mode 100644 index 9f1e612..0000000 --- a/src/logger/logger.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "logger.h" - -void send_log(mqd_t target, const char* msg, int n) { - mq_send(target, msg, n, 0); -} diff --git a/src/logger/logger.h b/src/logger/logger.h deleted file mode 100644 index abcdb6d..0000000 --- a/src/logger/logger.h +++ /dev/null @@ -1,67 +0,0 @@ -#include <stdio.h> -#include <mqueue.h> - -#ifndef LOG_LEVEL - #define LOG_LEVEL 3 -#endif - -#ifndef HAS_LOG_MODULE -#ifndef LOG_MODULE - #define HAS_LOG_MODULE 0 - #define LOG_MODULE "" -#else - #define HAS_LOG_MODULE 1 -#endif -#endif - -#if LOG_LEVEL >= 3 -#define log_infof(...) do { \ - char log_buf[1024]; \ - int n = 1; \ - log_buf[0] = 'i'; \ - if (HAS_LOG_MODULE == 1) { \ - n = snprintf(log_buf + 1, 1023, "(%s) ", LOG_MODULE); \ - } \ - snprintf(log_buf + n, 1024 - n, __VA_ARGS__); \ - send_log(logging, log_buf, 1024); \ -} while(0); -#endif // LOG_LEVEL >= 3 - -#if LOG_LEVEL >= 2 -#define log_warnf(...) do { \ - char log_buf[1024]; \ - int n = 1; \ - log_buf[0] = 'w'; \ - if (HAS_LOG_MODULE == 1) { \ - n = snprintf(log_buf + 1, 1023, "(%s) ", LOG_MODULE); \ - } \ - snprintf(log_buf + n, 1024 - n, __VA_ARGS__); \ - send_log(logging, log_buf, 1024); \ -} while(0); -#endif // LOG_LEVEL >= 2 - -#if LOG_LEVEL >= 1 -#define log_errof(...) do { \ - char log_buf[1024]; \ - int n = 1; \ - log_buf[0] = 'e'; \ - if (HAS_LOG_MODULE == 1) { \ - n = snprintf(log_buf + 1, 1023, "(%s) ", LOG_MODULE); \ - } \ - snprintf(log_buf + n, 1024 - n, __VA_ARGS__); \ - send_log(logging, log_buf, 1024); \ -} while(0); -#endif // LOG_LEVEL >= 1 - - -#ifndef log_infof -#define log_infof(...) (void)0 -#endif -#ifndef log_warnf -#define log_warnf(...) (void)0 -#endif -#ifndef log_errof -#define log_errof(...) (void)0 -#endif - -void send_log(mqd_t target, const char* msg, int n); diff --git a/src/server.c b/src/server.c deleted file mode 100644 index 7ff9c87..0000000 --- a/src/server.c +++ /dev/null @@ -1,190 +0,0 @@ -#include <errno.h> -#include <sys/socket.h> -#include <sys/wait.h> -#include <assert.h> -#include <unistd.h> - -#define LOG_MODULE "server" -#include "logger/logger.h" -#include "string.h" - -#define PORT 3456 - -#include "server/base64.c" -#include "server/ws_key.c" -#include "server/comms.c" - -mqd_t logging, tx, rx; -int handle_client(int client); - -int main(void) { - logging = mq_open("/logs", O_WRONLY); - tx = mq_open("/server_to_engine", O_WRONLY); - rx = mq_open("/engine_to_server", O_RDONLY); - - int server_fd = socket(AF_INET, SOCK_STREAM, 0); - int opt = 1; - - setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); - struct sockaddr_in addr = { - .sin_family = AF_INET, - .sin_addr.s_addr = INADDR_ANY, - .sin_port = htons(PORT) - }; - - if (bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - perror("bind"); - return 1; - } - - if (listen(server_fd, 16) < 0) { - perror("listen"); - return 1; - } - - log_infof("Listening on %d", PORT); - - // https://websocket.org/guides/websocket-protocol/ - while(1) { - int client = accept(server_fd, NULL, NULL); - - if (client < 0) continue; - char req[4096]; - - int n = recv(client, req, sizeof(req) - 1, 0); - if (n <= 0) { - log_infof("Client close"); - close(client); - continue; - } - - req[n] = 0; - - char *key = find_websocket_key(req); - - if (!key) { - close(client); - continue; - } - - char accept_key[128]; - - websocket_accept_key(key, accept_key); - char response[512]; - - snprintf( - response, - sizeof(response), - "HTTP/1.1 101 Switching Protocols\r\n" - "Upgrade: websocket\r\n" - "Connection: Upgrade\r\n" - "Sec-WebSocket-Accept: %s\r\n" - "\r\n", - accept_key - ); - - send(client, response, strlen(response), 0); - if (fork() == 0) { - log_infof("{%d} WebSocket connected", client); - while(1) { - if (handle_client(client)) continue; - else break; - } - log_infof("{%d} WebSocket disconnected", client); - close(client); - } - } -} - -int handle_client(int client) { - unsigned char hdr[2]; - int recvn; - - if ((recvn = recv(client, hdr, 2, MSG_WAITALL)) != 2) { - if (recvn == -1) { - char buf[256]; - if (strerror_r(errno, buf, sizeof(buf)) == 0) { - log_warnf("recv: %s", buf); - } - } - log_warnf("{%d} recv close %d", client, recvn); - return 0; - } - - unsigned opcode = hdr[0] & 0x0F; - unsigned len = hdr[1] & 0x7F; - log_infof( - "{%d} opcode=%u len=%u masked=%u", - client, - opcode, - hdr[1] & 0x7F, - !!(hdr[1] & 0x80) - ); - if (opcode == 0x8) { - unsigned char close_frame[2] = {0x88, 0x00}; - send(client, close_frame, 2, 0); - log_warnf("{%d} opcode 0x8 close", client); - return 0; - } - - if (opcode == 0x9) { - unsigned char pong[2] = {0x8A, 0x00}; - send(client, pong, 2, 0); - return 1; - } - - unsigned char mask[4]; - recvn = recv(client, mask, 4, MSG_WAITALL); - if (recvn == -1) { - char buf[256]; - if (strerror_r(errno, buf, sizeof(buf)) == 0) { - log_warnf("mask recv err: %s", buf); - } - } else { - char mask_hex[256] = {0}; - base64_encode(mask, 126, mask_hex); - log_infof("mask recv{%d}: %s", recvn, mask_hex); - } - - unsigned char payload[126]; - recvn = recv(client, payload, len, MSG_WAITALL); - if (recvn == -1) { - char buf[256]; - if (strerror_r(errno, buf, sizeof(buf)) == 0) { - log_warnf("payload recv err: %s", buf); - } - } else { - char payload_hex[256] = {0}; - base64_encode(payload, 126, payload_hex); - log_infof("payload recv{%d}: %s", recvn, payload_hex); - } - - for (unsigned i = 0; i < len; i++) - payload[i] ^= mask[i % 4]; - - payload[len] = 0; - char* payload_ptr = (char*)payload; - struct strs response = handle_input(logging, tx, rx, payload_ptr, len); - - unsigned char out[1024]; - out[0] = 0x81; - int shift; - for (int i = 0; i < response.count; i++) { - struct str item = response.data[i]; - assert(item.len <= 125); - - log_infof("Replying %d: %.*s", client, item.len, item.msg) - out[1] = item.len; - shift = 2; - memcpy(out + 2, item.msg, item.len); - send(client, out, item.len + 2, 0); - } - log_infof("Replying %d: END-TRANSMISSION", client) - char end_transmission[] = "END-TRANSMISSION"; - int n = strlen(end_transmission); - out[1] = n; - - memcpy(out + 2, end_transmission, n); - send(client, out, n + 2, 0); - return 1; -} diff --git a/src/server/base64.c b/src/server/base64.c deleted file mode 100644 index e3e0ef6..0000000 --- a/src/server/base64.c +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef BASE64_C -#define BASE64_C - -#include <stddef.h> - -static const char b64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; - -void base64_encode( - const unsigned char *in, - size_t len, - char *out -) { - size_t i, j = 0; - - for (i = 0; i < len; i += 3) { - unsigned v = in[i] << 16; - - if (i + 1 < len) v |= in[i + 1] << 8; - if (i + 2 < len) v |= in[i + 2]; - - out[j++] = b64[(v >> 18) & 63]; - out[j++] = b64[(v >> 12) & 63]; - - out[j++] = (i + 1 < len) ? b64[(v >> 6) & 63] : '='; - out[j++] = (i + 2 < len) ? b64[v & 63] : '='; - } - - out[j] = 0; -} - -#endif // BASE64_C diff --git a/src/server/comms.c b/src/server/comms.c deleted file mode 100644 index 67e42a2..0000000 --- a/src/server/comms.c +++ /dev/null @@ -1,68 +0,0 @@ -#include <assert.h> -#include <string.h> -#include "../ipc.c" -#include "../logger/logger.h" - -struct str { - char msg[1023]; - int len; -}; - -void set_output(struct str* output, char* msg) { - int i = 0; - while (msg[i] != 0) { - assert(i < 1023); - output->msg[i] = msg[i]; - i++; - } - output->len = i; -} - -struct strs { - struct str* data; - int capacity; - int count; -}; - -struct strs init_strs() { - return (struct strs) { - .data = malloc(sizeof(struct str) * 10), - .count = 0, - .capacity = 10, - }; -} -void add_str(struct strs* strs, char* str) { - if (strs->count + 1 > strs->capacity) { - strs->capacity += 30; - strs->data = realloc(strs->data, sizeof(struct str) * strs->capacity); - } - - struct str item; - set_output(&item, str); - - strs->data[strs->count] = item; - strs->count++; -} - -struct strs handle_input(mqd_t logging, mqd_t tx, mqd_t rx, char* payload, int len) { - log_infof("after: %d", payload[len]); - send_queue(tx, payload, len + 1); - char* buf = read_queue(rx); - - struct strs output = init_strs(); - - if (strcmp(buf, "Sending") != 0) { - return output; - } - - while (1) { - char* buf = read_queue(rx); - if (strcmp(buf, "END-TRANSMISSION") == 0) { - free(buf); - break; - } - add_str(&output, buf); - free(buf); - } - return output; -} diff --git a/src/server/ws_key.c b/src/server/ws_key.c deleted file mode 100644 index 015605e..0000000 --- a/src/server/ws_key.c +++ /dev/null @@ -1,36 +0,0 @@ -#include <openssl/sha.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <stdio.h> - -#include "./base64.c" - -static const char *GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; - -void websocket_accept_key(const char *client_key, char *output) { - char buf[256]; - snprintf(buf, sizeof(buf), "%s%s", client_key, GUID); - - unsigned char hash[SHA_DIGEST_LENGTH]; - SHA1((unsigned char *)buf, strlen(buf), hash); - base64_encode(hash, SHA_DIGEST_LENGTH, output); -} - -char *find_websocket_key(char *req) { - char *p = strstr(req, "Sec-WebSocket-Key:"); - - if (!p) return NULL; - - p += strlen("Sec-WebSocket-Key:"); - - while (*p == ' ') p++; - - static char key[128]; - int i = 0; - while (*p && *p != '\r' && *p != '\n') - key[i++] = *p++; - - key[i] = 0; - return key; -} @@ -1,14 +1,14 @@ #include <stdio.h> #include <string.h> #include <stdbool.h> -#include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <assert.h> -#include "uci/state.h" -#include "uci/command.h" -#include "uci/response.h" +#include <stdlib.h> +#include "state.h" +#include "command.h" +#include "response.h" #include "uci.h" #include "ipc.h" diff --git a/src/uci/command.c b/src/uci/command.c index d82c50c..02d6e0f 100644 --- a/src/uci/command.c +++ b/src/uci/command.c @@ -1,6 +1,6 @@ #include <assert.h> -#include <stdlib.h> #include <string.h> +#include <stdlib.h> #include "command.h" ucicmd ucicmd_init() { diff --git a/src/uci/response.c b/src/uci/response.c index 6208a54..7ebe49c 100644 --- a/src/uci/response.c +++ b/src/uci/response.c @@ -3,8 +3,9 @@ #include <stdlib.h> #include "response.h" -#include "../fen.h" -#include "../bitboard.h" +#include "ipc.h" +#include "fen.h" +#include "bitboard.h" void apply_option(uci_state *state, char *name, char *buffer) { int settings_count = sizeof(state->option_settings)/sizeof(option_setting_t); @@ -212,6 +213,48 @@ void handle_idle( } else if (strcmp(cmd.root, "isready") == 0) { current_state = STATE_SYNC; } else if (strcmp(cmd.root, "go") == 0) { + state->go_args = malloc(sizeof(struct go_args)); + struct go_args *info = state->go_args; + for (int i = 0; i < cmd.args_count; i++) { + if (strcmp(ucicmd_get_arg(cmd, i), "searchmoves") == 0) { + info->searchmoves = comm_moves_init(); + for (i++; i < cmd.args_count; i++) { + char* move_str = ucicmd_get_arg(cmd, i); + if (move_str[1] < '0' || move_str[1] > '9') break; + + add_comm_move(&info->searchmoves, (struct uci_move) { + (move_str[0] - 'a') * 8 + (move_str[1] - '1'), + (move_str[2] - 'a') * 8 + (move_str[3] - '1') + }); + } + i--; + } else if (strcmp(ucicmd_get_arg(cmd, i), "ponder") == 0) { + info->ponder = true; + } else if (strcmp(ucicmd_get_arg(cmd, i), "wtime") == 0) { + info->wtime = atoi(ucicmd_get_arg(cmd, ++i)); + } else if (strcmp(ucicmd_get_arg(cmd, i), "btime") == 0) { + info->btime = atoi(ucicmd_get_arg(cmd, ++i)); + } else if (strcmp(ucicmd_get_arg(cmd, i), "winc") == 0) { + info->winc = atoi(ucicmd_get_arg(cmd, ++i)); + } else if (strcmp(ucicmd_get_arg(cmd, i), "binc") == 0) { + info->binc = atoi(ucicmd_get_arg(cmd, ++i)); + } else if (strcmp(ucicmd_get_arg(cmd, i), "movestogo") == 0) { + info->movestogo = atoi(ucicmd_get_arg(cmd, ++i)); + } else if (strcmp(ucicmd_get_arg(cmd, i), "depth") == 0) { + info->depth = atoi(ucicmd_get_arg(cmd, ++i)); + } else if (strcmp(ucicmd_get_arg(cmd, i), "nodes") == 0) { + info->nodes = atoi(ucicmd_get_arg(cmd, ++i)); + } else if (strcmp(ucicmd_get_arg(cmd, i), "mate") == 0) { + info->mate = atoi(ucicmd_get_arg(cmd, ++i)); + } else if (strcmp(ucicmd_get_arg(cmd, i), "movetime") == 0) { + info->movetime = atoi(ucicmd_get_arg(cmd, ++i)); + } else if (strcmp(ucicmd_get_arg(cmd, i), "infinite") == 0) { + info->infinite = true; + } else if (strcmp(ucicmd_get_arg(cmd, i), "perft") == 0) { + info->perft = atoi(ucicmd_get_arg(cmd, ++i)); + } + } + atomic_store(&state->go, 1); current_state = STATE_ACTIVE; } else { @@ -247,17 +290,31 @@ void handle_active( engine_messages* engine_messages, ucicmd cmd ) { + while (atomic_load(&state->go_ready_receive) == 0); + + bool ended = false; for (int i = 0; i < engine_messages->count; i++) { struct engine_message *old = engine_messages->data[i]; + if (old == NULL) continue; if (!old->ready) continue; old->ready = 0; printf( - "info depth %d seldepth %d multipv %d score cp %d nodes %d nps %d hashfull %d tbhits %d time %d pv", + "info depth %d seldepth %d multipv %d ", old->depth, old->seldepth, - old->multipv, - old->score_cp, + old->multipv + ); + if (old->mate) { + printf("mate %d ", old->mate); + } else { + printf("score cp %d ", old->score_cp); + } + if (old->node_limit) { + printf("upperbound "); + } + printf( + "nodes %d nps %d hashfull %d tbhits %d time %d pv", old->nodes, old->nps, old->hashfull, @@ -278,6 +335,7 @@ void handle_active( printf("\n"); if (old->best_move.from != 0 && old->best_move.to != 0) { + ended = true; printf( "bestmove %c%c%c%c", (old->best_move.from / 8) + 'a', @@ -300,8 +358,13 @@ void handle_active( engine_messages->data[i] = old->next; free(old->pv.moves); free(old); + + if (ended) { + printf("ENDED\n"); + atomic_store(&state->cleanup, 1); + current_state = STATE_IDLE; + } } - // TODO: this section will call the engine to analysis if (cmd.empty) { return; } @@ -316,9 +379,9 @@ void handle_active( void handle_halt(uci_state *state, ucicmd cmd) { // TIMEOUT NOTICE: THE FOLLOWING BLOCK SHOULDN'T TAKE MORE THAN 1 SECONDS - + + atomic_store(&state->stop, 1); // --- - printf("bestmove 0000\n"); // TODO: idk get it rn current_state = STATE_IDLE; } diff --git a/src/uci/state.c b/src/uci/state.c index f64b5cf..56e0b04 100644 --- a/src/uci/state.c +++ b/src/uci/state.c @@ -9,7 +9,7 @@ option_setting_t option_setting_combo( combo_t *combo ) { option_setting_t output = {0}; - memcpy(output.option_name, option_name, 32); + strncpy(output.option_name, option_name, 32); output.type = OPTION_COMBO; output.data.combo = (option_combo_setting_t) { combinations, @@ -29,7 +29,7 @@ option_setting_t option_setting_spin( spin_t *spin ) { option_setting_t output = {0}; - memcpy(output.option_name, option_name, 32); + strncpy(output.option_name, option_name, 32); output.type = OPTION_SPIN; output.data.spin = (option_spin_setting_t) { min, max, default_value }; output.value.spin = spin; @@ -43,7 +43,7 @@ option_setting_t option_setting_check( check_t *check ) { option_setting_t output = {0}; - memcpy(output.option_name, option_name, 32); + strncpy(output.option_name, option_name, 32); output.type = OPTION_CHECK; output.data.check_default = default_value; output.value.check = check; @@ -72,7 +72,7 @@ option_setting_t option_setting_button( button_t *button ) { option_setting_t output = {0}; - memcpy(output.option_name, option_name, 32); + strncpy(output.option_name, option_name, 32); output.type = OPTION_BUTTON; output.value.button = button; *button = false; diff --git a/generate/find_tests.c b/tests/find_tests.c index 8630255..a0b9f63 100644 --- a/generate/find_tests.c +++ b/tests/find_tests.c @@ -163,7 +163,7 @@ void handle_fn(const char* input_path, int path_strip_index, FILE* file) { int main() { if (fork() == 0) { - char* args[] = {"mkdir", "-p", "generated", NULL}; + char* args[] = {"mkdir", "-p", "tests/generated", NULL}; execvp(args[0], args); } wait(NULL); @@ -174,7 +174,7 @@ int main() { handle_input("src", path_type_directory, handle_fn); - FILE* f = fopen("generated/tests.c", "w"); + FILE* f = fopen("tests/generated.c", "w"); int total_test_count = 0; for (int i = 0; i < tests.count; i++) { diff --git a/tests/generated.c b/tests/generated.c new file mode 100644 index 0000000..777f8b1 --- /dev/null +++ b/tests/generated.c @@ -0,0 +1,25 @@ +#include "../src/engine/fen.c" +#include "../src/engine/moves/king.c" +#include "../src/uci/command.c" + +int total_test_count = 7; +bool (*tests[7])(void) = { + test_fen_no_passant, + test_fen_passant, + test_starting_position, + test_white_king_corners, + test_black_king_corners, + test_ucicmd, + test_invalid_cmd_ucicmd, +}; + +int max_test_name_size = 18; +char test_names[7][100] = { + "fen_no_passant", + "fen_passant", + "starting_position", + "white_king_corners", + "black_king_corners", + "ucicmd", + "invalid_cmd_ucicmd", +}; diff --git a/tests/main.c b/tests/main.c index df802c2..191f0dd 100644 --- a/tests/main.c +++ b/tests/main.c @@ -3,7 +3,7 @@ #include <time.h> #define TEST_MOD -#include "../generated/tests.c" +#include "generated.c" double diff_time(struct timespec a, struct timespec b) { double a_time = (double)a.tv_sec + a.tv_nsec * 1e-9; |
