diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ct1986.c | 115 |
1 files changed, 57 insertions, 58 deletions
diff --git a/src/ct1986.c b/src/ct1986.c index cb232fc..4cbe2a7 100644 --- a/src/ct1986.c +++ b/src/ct1986.c @@ -5,12 +5,19 @@ #include <tak.h> #include <minimax_cnn1986.h> -FILE *lcd = NULL; +const char* esc = "[L"; +FILE *lcd = NULL; static char *gamelog = 0; static int human, search_depth; static void +write_line(const char *line) { + fputs(line, lcd); + fflush(lcd); +} + +static void append_to_gamelog(const char *line, const uint8_t win_line) { // I _could_ dynamically compute the size but ... don't let // `perfect' be the enemy of `good' ? @@ -38,8 +45,7 @@ static void end_game(char *line, char *win) { append_to_gamelog(line, 0); append_to_gamelog(win, 1); - fputs("Game over: ",lcd); - fputs(win, lcd); + fprintf(lcd, "Game over: %s\n", win); fflush(lcd); } @@ -49,13 +55,9 @@ handle_turn(char *line) { uint8_t new_win = (won == 0xFF); switch (do_ptn(line)) { // Errors - case PTN_INVALID: { fputs("Invalid PTN.", lcd); return -1; break; } - case ACT_ILLEGAL: { fputs("Illegal action.", lcd); return -1; break; } - case ACT_OVERFLOW: { - fputs("Move would cause internal overflow, select another.", lcd); - return EXIT_FAILURE; - break; - } + case PTN_INVALID: { write_line("Invalid PTN."); break; } + case ACT_ILLEGAL: { write_line("Illegal ply."); break; } + case ACT_OVERFLOW: { write_line("Overflow."); break; } // Game has ended case GAME_END: { // Did it end this turn? @@ -67,92 +69,90 @@ handle_turn(char *line) { case WIN_ROAD_BLACK: { end_game(line,"0-R"); break; } case WIN_ROAD_WHITE: { end_game(line,"R-0"); break; } } + return EXIT_SUCCESS; + } else { + write_line("Game over."); + break; } - fputs("Game over, enter `new' to play again.", lcd); - if (! new_win) return EXIT_FAILURE; - break; } // Valid, append to game log - case PTN_VALID: - case ACT_OK: { + default: { append_to_gamelog(line, 0); - break; + return EXIT_SUCCESS; } } - - return EXIT_SUCCESS; + return EXIT_FAILURE; } static void new_game(uint8_t size) { reset_state(size); - fputs("New 5x5 game! ct1986 at search depth ", lcd); - fputc(search_depth + '0', lcd); - fputc('.', lcd); - fflush(lcd); + write_line("New 5x5 game."); if (gamelog) gamelog = realloc(gamelog, sizeof(char)); else gamelog = malloc(sizeof(char)); gamelog[0] = 0; } // Set up output function for ct1986 + +static uint8_t perc; inline void ct1986_display_progress(const uint8_t depth) { if (depth == 0) { - fputc('#', lcd); + perc++; + // back four spaces + for (int k=0;k<4;k++) { + fprintf(lcd, "%sl", esc); + fflush(lcd); + } + // clear line + fprintf(lcd, "%sk", esc); + fflush(lcd); + // write percentage + fprintf(lcd, "%3d%%", perc*4); } } static int ct1986_turn(const uint8_t search_depth) { // Prepare progress bar - fputs("Computing ", lcd); + fputs("Computing.. ", lcd); fflush(lcd); // Run the minimax + perc = 0; float minimax = ct1986_generate(search_depth); + fputc('\n', lcd); // Failed to find a move? if (minimax <= -infty) { - fputs("Opponent concedes!", lcd); + fprintf(lcd, "%s concedes!\n", (ply & 1) ? "Black" : "White"); return EXIT_FAILURE; } else { - fputs("Result: ", lcd); - fputs(ct1986_ptn, lcd); + fprintf(lcd, "%s: %s\n", + (ply & 1) ? "Black" : "White", + ct1986_ptn); handle_turn(ct1986_ptn); return EXIT_SUCCESS; } } +static void +do_game_log(void) { + fputs(gamelog, lcd); +} + static int input_is_not_turn(const char *line) { - if (!strcmp(line,"help")) { - fputs("Valid commands: depth [0-9], help, new, \ -play (b|w), self-play, <PTN>.", lcd); - } else if (!strcmp(line,"log")) { - fputs(gamelog, lcd); - } else if (!strcmp(line,"new")) { - new_game(5); - } else if (!strcmp(line,"self-play")) { - while (ct1986_turn(search_depth) == 0); - } else if (!strncmp(line,"depth",5)) { - if (strnlen(line,7) == 7 && line[6] >= '0' && line[6] <= '9') { - search_depth = line[6] - '0'; - fputs("New search depth: ", lcd); - fputc(line[6], lcd); + switch (line[0]) { + case 'l': { do_game_log(); break; } + case 'n': { new_game(5); break; } + case 'd': { + search_depth = line[1] - '0'; + fprintf(lcd, "Search depth: %d\n", search_depth); fflush(lcd); - } else { - fputs("Usage: depth [0-9].", lcd); - } - } else if (!strncmp(line,"play",4)) { - if (strnlen(line,7) == 6 - && ((line[5] == 'b' || line[5] == 'B') - || (line[5] == 'w' || line[5] == 'W'))) { - // 'b' is even :) - human = 1 - (line[5] & 1); - new_game(5); - } else { - fputs("Usage: play (b|w).\n", lcd); + break; } - } else { - return EXIT_FAILURE; + case 'b': { human = 1; new_game(5); break; } + case 'w': { human = 0; new_game(5); break; } + default: return EXIT_FAILURE; } return EXIT_SUCCESS; } @@ -162,7 +162,7 @@ main(int argc, char **argv) { (void)(argc); (void)(argv); - lcd = fopen("/dev/lcd","w"); + lcd = fopen("/dev/lcd", "w"); if (lcd == NULL) return EXIT_FAILURE; human = 0; @@ -174,8 +174,7 @@ main(int argc, char **argv) { size_t alloc_size; for (int playing = 1; playing;) { - fputs("Welcome to ct1986!\n", lcd); fflush(lcd); - fflush(stdout); + write_line("Loaded ct1986!\n"); while ((human == 0) && (read = getline(&line, &alloc_size, stdin)) != -1) { if (read) { line[read - 1] = 0; |
