#ifndef __UCI_H_INC #define __UCI_H_INC #define PS2(s) ([]{ static const char c[] PROGMEM = (s); return &c[0]; }()) typedef void uci_return; typedef uci_return (*uci_handler)(); struct uci_cmd { const char* command; uci_handler handler; }; uci_return uci_hello() { Serial.println(F("id name ArduChess\nid author Quinten Kock\nuciok")); } uci_return uci_unimpl() { Serial.println(F("Function not implemented yet")); } uci_return uci_unknown() { Serial.println(F("Not an UCI command")); } const uci_cmd UCI_COMMANDS[] = { {PS2("uci"), &uci_hello}, {PS2("debug"), &uci_unimpl}, {PS2("isready"), &uci_unimpl}, {PS2("setoption"), &uci_unimpl}, {PS2("ucinewgame"), &uci_unimpl}, {PS2("position"), &uci_unimpl}, {PS2("go"), &uci_unimpl}, {PS2("stop"), &uci_unimpl}, {PS2("ponderhit"), &uci_unimpl}, {PS2("quit"), &uci_unimpl}, }; const uci_cmd UCI_INVALID = {PS2(""), &uci_unknown}; uci_cmd get_uci_command(const char* command) { size_t command_num = sizeof(UCI_COMMANDS) / sizeof(uci_cmd); for(size_t i = 0; i < command_num; i++) { size_t ci = 0; uci_cmd to_try = UCI_COMMANDS[i]; while(true) { char reference = pgm_read_byte_near(to_try.command + ci); if(reference != command[ci]) { break; } if(command[ci] == '\0') { return to_try; } ci++; } } return UCI_INVALID; } String read_word() { int incoming = Serial.read(); String str = String(); do { if(incoming != -1) { str += (char)incoming; } incoming = Serial.read(); } while(incoming != '\n' && incoming != ' '); return str; } uci_return handle_uci() { if(Serial.available()) { // There is input available; so likely a command String command = read_word(); uci_cmd handler = get_uci_command(command.c_str()); handler.handler(); } } #endif