/*
cttei, a TEI interface to the ct library & its computer opponent
Copyright (C) 2021, tslil clingman
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include
#include
#include
#include
#include
#include
// Set up output function for negamax
inline void negamax_display_progress(const uint8_t cur_depth,
const uint8_t init_depth,
const uint32_t length) {
(void)(cur_depth);
(void)(init_depth);
(void)(length);
}
enum TEI_RETURN { TEI_QUIT, TEI_OK, TEI_FAILURE };
// expects ``(startpos|tps ) moves ''
static enum TEI_RETURN parse_position_string(tak_state_p state, char *line) {
// Find the word ``moves''
char *beg = strstr(line, "moves");
if (!strncasecmp(line, "tps", 3)) {
// Split the string on the space before moves
if (beg)
*(beg - 1) = 0;
// so that we can load it as a TPS description
load_tps(state, line + 4);
} else if (!strncasecmp(line, "startpos", 8)) {
reset_state(state, 5);
} else {
return TEI_FAILURE;
}
if (beg == NULL)
return TEI_OK;
// parse the PTN sequence
strtok(beg, " ");
char *ptn = strtok(NULL, " ");
while (ptn != NULL) {
if (do_ptn(state, ptn) != ACT_OK)
return TEI_FAILURE;
ptn = strtok(NULL, " ");
}
return TEI_OK;
}
static enum TEI_RETURN handle_tei(tak_state_p state, char *line) {
if (!strcmp(line, "quit")) {
return TEI_QUIT;
}
if (!strcmp(line, "isready")) {
puts("readyok");
} else if (!strncmp(line, "setoption Depth value ", 22)) {
negamax_search_depth = atoi(line + 23);
} else if (!strncmp(line, "go", 2)) {
// TODO: for now we ignore all of the parameters
float minimax = negamax_generate(state);
enum ACT_RESULT r = do_ptn(state, negamax_ptn);
if (r != ACT_OK && r != GAME_END)
return TEI_FAILURE;
printf("info score cp %f pv %s\nbestmove %s\n", minimax, negamax_ptn,
negamax_ptn);
} else if (!strncmp(line, "position", 8)) {
return parse_position_string(state, line + 9);
} else if (!strncmp(line, "teinewgame", 10)) {
if (line[11] != '5')
return TEI_FAILURE;
const uint8_t size = atoi(line + 11);
if (size != 5) {
return TEI_FAILURE;
} else {
reset_state(state, 5);
}
}
fflush(stdout);
return TEI_OK;
}
const char *license =
"cttei, a TEI interface to the ct library & its computer opponent\n\
\n\
Copyright (C) 2021, tslil clingman\n\
\n\
This program comes with ABSOLUTELY NO WARRANTY; and is made available under the terms of the GNU GPL v3 license. This is free software, and you are welcome to redistribute it under certain conditions; see COPYING for details.\n";
int main(int argc, char **argv) {
(void)(argc);
(void)(argv);
puts(license);
char *line = NULL;
ssize_t read = -1;
size_t alloc_size;
// Wait for tei
while ((read = getline(&line, &alloc_size, stdin))) {
if (read > 0 && !strncmp("tei", line, 3)) {
break;
} else
return EXIT_FAILURE;
}
if (line)
free(line);
line = NULL;
// Identify ourselves, and send the options
puts("id name cttei");
puts("id author tslil clingman");
puts("option name Depth type spin default 4 min 2 max 6");
puts("teiok");
fflush(stdout);
// Set default option
struct tak_state_s state_s;
tak_state_p state = &state_s;
negamax_search_depth = 4;
negamax_init(5);
reset_state(state, 5);
for (int playing = 1; playing;) {
if ((read = getline(&line, &alloc_size, stdin)) > 0) {
line[read - 1] = 0;
switch (handle_tei(state, line)) {
case TEI_FAILURE:
return EXIT_FAILURE;
case TEI_QUIT:
playing = 0; // fall-through
case TEI_OK: {
if (line) {
free(line);
line = NULL;
}
break;
}
}
} else {
break;
}
}
if (line)
free(line);
negamax_free();
return EXIT_SUCCESS;
}