#include #include #include #include #include #include #include "uci/internals/command.h" #include "uci/internals/response.h" #include "uci/state.h" #include "ipc/state.h" #include "ipc/uci.h" void load_from_message(uci_cmd_t* cmd, const char* message) { char token[MAX_TOKEN_SIZE]; int i = 0, k = 0; while (message[i] != 0 && message[i] != '\n' && message[i] != '\r') { if (message[i] != ' ') { token[k++] = message[i++]; continue; } if (k == 0) { i++; continue; } i++; token[k] = 0; uci_cmd_add(cmd, token); k = 0; } token[k] = 0; uci_cmd_add(cmd, token); } void *uci(ipc_state_t *ipc_state) { // https://stackoverflow.com/a/41559081 fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK); uci_cmd_t cmd = uci_cmd_init(); size_t n; char buf[1024]; while (true) { cmd.empty = true; cmd.args_count = 0; ssize_t n = read(STDIN_FILENO, buf, sizeof(buf)); if (n > 0) { load_from_message(&cmd, buf); } handle_uci(&ipc_state->uci_state, cmd); handle_ipc(ipc_state); } } int k =0; void handle_ipc(ipc_state_t *state) { int signal = state->uci_state.signal; assert(signal < UCI_SIGNAL_COUNT); if (signal == UCI_SIGNAL_NONE) return; if (signal == UCI_SIGNAL_QUIT) { return; } if (signal == UCI_SIGNAL_GO) { // some init stuff ipc_state_set_event(state, EVENT_ENGINE_GO); state->uci_state.signal = UCI_SIGNAL_GO_LOOP; } if ( signal == UCI_SIGNAL_GO_LOOP && ipc_state_is_event(state, EVENT_UCI_RUNNING) ) { bool ended = false; engine_messages_t engine_messages = state->engine_messages; int engine_messages_count = engine_messages.count; for (int i = 0; i < engine_messages_count; i++) { engine_message_handler_t *handler = engine_messages.data[i]; if (!engine_message_handler_can_pop(handler)) continue; engine_message_t *message = engine_message_handler_pop(handler); printf( "info depth %d seldepth %d multipv %d ", message->depth, message->seldepth, message->multipv ); if (message->mate) { printf("mate %d ", message->mate); } else { printf("score cp %d ", message->score_cp); } if (message->node_limit) { printf("upperbound "); } printf( "nodes %d nps %d hashfull %d tbhits %d time %d pv", message->nodes, message->nps, message->hashfull, message->tbhits, message->time ); for (int j = 0; j < message->pv.count; j++) { ipc_move_t move = message->pv.data[i]; printf( " %c%c%c%c", (move.from / 8) + 'a', (move.from % 8) + '1', (move.to / 8) + 'a', (move.to % 8) + '1' ); } printf("\n"); if (message->best_move.from != 0 && message->best_move.to != 0) { ended = true; printf( "bestmove %c%c%c%c", (message->best_move.from / 8) + 'a', (message->best_move.from % 8) + '1', (message->best_move.to / 8) + 'a', (message->best_move.to % 8) + '1' ); if (message->ponder.from != 0 && message->ponder.to != 0) { printf( " ponder %c%c%c%c", (message->ponder.from / 8) + 'a', (message->ponder.from % 8) + '1', (message->ponder.to / 8) + 'a', (message->ponder.to % 8) + '1' ); } printf("\n"); } engine_message_deinit(message); if (ended) { state->uci_state.signal = UCI_SIGNAL_NONE; state->uci_state.current_state = UCI_STATE_IDLE; break; } } if (ended) { ipc_state_set_event(state, EVENT_ENGINE_STOP); } else { ipc_state_set_event(state, EVENT_ENGINE_RUNNING); } return; } if (signal == UCI_SIGNAL_STOP) { printf("uci stopping\n"); return; } } #include "uci/command.c" #include "uci/response.c" #include "uci/state.c"