diff options
Diffstat (limited to 'src/ct1986.c')
| -rw-r--r-- | src/ct1986.c | 106 |
1 files changed, 76 insertions, 30 deletions
diff --git a/src/ct1986.c b/src/ct1986.c index 0872ca7..2c2d875 100644 --- a/src/ct1986.c +++ b/src/ct1986.c @@ -21,17 +21,33 @@ #include <stdlib.h> #include <string.h> +#include <ncurses.h> + #include <tak.h> #include <negamax.h> #include <lcdlib.h> -static char *gamelog = 0; + static int human; +static char *gamelog = 0; static void +new_game(uint8_t size) { + reset_state(size); + lcd_printf_line(L_SCROLL, "New 5s game @ D%d", + negamax_search_depth); + if (gamelog) gamelog = realloc(gamelog, sizeof(char)); + else gamelog = malloc(sizeof(char)); + gamelog[0] = 0; +} + +static int 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' ? + + if (gamelog == NULL) return EXIT_FAILURE; + char prepend[8]; if (win_line) { @@ -48,8 +64,11 @@ append_to_gamelog(const char *line, const uint8_t win_line) { strlen(gamelog) + strlen(prepend) + strlen(line) + 1); - strcat(gamelog,prepend); - strcat(gamelog,line); + // TODO: trap errno + strcat(gamelog, prepend); + strcat(gamelog, line); + + return EXIT_SUCCESS; } static void @@ -94,32 +113,24 @@ handle_turn(char *line) { return EXIT_FAILURE; } -static void -new_game(uint8_t size) { - reset_state(size); - lcd_put_line(L_SCROLL, "New 5x5 game."); - if (gamelog) gamelog = realloc(gamelog, sizeof(char)); - else gamelog = malloc(sizeof(char)); - gamelog[0] = 0; -} // Set up output function for negamax -static uint8_t perc; +static uint32_t perc; inline void negamax_display_progress(const uint8_t depth, const uint32_t length) { - if (depth == 0) { - perc++; - lcd_printf_line(L_OVERWRITE, "Computing: %d%%", (perc*100)/length); + if (depth == negamax_search_depth) { + lcd_printf_line(L_OVERWRITE, "Computing: %d%%", + (++perc*100)/length); } } static int negamax_turn() { // Prepare progress bar + perc = 0; lcd_put_line(L_SCROLL, "Computing: 0%"); // Run the minimax - perc = 0; float minimax = negamax_generate(); // Failed to find a move? if (minimax < -infty) { @@ -136,7 +147,7 @@ negamax_turn() { static void do_game_log(void) { - lcd_put_line(L_SCROLL, "Not implemented."); + lcd_put_line(L_SCROLL, "TODO!"); } static int @@ -144,7 +155,7 @@ input_is_not_turn(const char *line) { switch (line[0]) { case 'l': { do_game_log(); break; } case 'n': { new_game(5); break; } - case 's': { + case 'D': { negamax_search_depth = line[1] - '0'; lcd_printf_line(L_SCROLL, "Search depth: %d", negamax_search_depth); @@ -163,6 +174,47 @@ 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"; +#define LINE_BUFF_LEN 9 +static char line[LINE_BUFF_LEN+1]; + +static int +poll_input(void) { + char c, *prompt; + int idx = 0, polling = 1; + + if (ply & 1) prompt = "Black: "; + else prompt = "White: "; + + lcd_put_line(L_SCROLL, prompt); + + line[0] = 0; + while (polling) { + lcd_printf_line(L_OVERWRITE, "%s%s", prompt, line); + c = getchar(); + switch (c) { + case 0x7F: { + if (idx>0) idx--; + line[idx] = 0; + break; + } + case 0xFF: // fall-through + case '\r': // fall-through + case '\n': { + polling = 0; + break; + } + default: { + if (idx+1<LINE_BUFF_LEN) { + line[idx] = c; + line[++idx] = 0; + } + break; + } + } + } + return idx; +} + int main(int argc, char **argv) { (void)(argc); (void)(argv); @@ -172,46 +224,40 @@ int main(int argc, char **argv) { if (lcd_begin() != EXIT_SUCCESS) return EXIT_FAILURE; + initscr(); negamax_search_depth = 3; new_game(5); negamax_init(5); - char *line = NULL; - ssize_t read; - size_t alloc_size; - human = 0; for (int playing = 1; playing;) { while (human == 0) { - if (ply & 1) lcd_put_line(L_SCROLL, "Black: "); - else lcd_put_line(L_SCROLL, "White: "); - read = getline(&line, &alloc_size, stdin); - if (read > 0) { - line[read - 1] = 0; + lcd_set_blink(); + if (poll_input() > 0) { if (input_is_not_turn(line)) { int r = handle_turn(line); if (r == EXIT_SUCCESS && won == 0xFF) { human = 1; } } - free(line); - line = NULL; } else { playing = 0; human = 1; } } + lcd_stop_blink(); if (playing) { negamax_turn(); human = 0; } } - free(line); free(gamelog); negamax_free(); lcd_end(); + endwin(); + return EXIT_SUCCESS; } |
