From 399d90f1b94717aa0ca5abb1dc43bdb6f4160d13 Mon Sep 17 00:00:00 2001 From: tslil clingman Date: Sun, 31 Jan 2021 15:33:30 -0500 Subject: Fairly important bug fixes to lcdlib, LCD now echoes input! Input polling without line-buffering is done using ncurses, so the buildroot configuration had to change accordingly to include that library. The Makefile changed to accommodate stand-alone building of ct1986 and to include -lcurses where appropriate. There were also some typos about copying ct1986 and ctaklm to the correct directories. --- Makefile | 12 +++-- include/lcdlib.c | 44 ++++++++++++------- include/lcdlib.h | 3 ++ resources/buildroot.config | 8 ++-- src/ct1986.c | 106 ++++++++++++++++++++++++++++++++------------- src/ctaklm.c | 17 +++++--- 6 files changed, 132 insertions(+), 58 deletions(-) diff --git a/Makefile b/Makefile index a62f2f7..41dedee 100644 --- a/Makefile +++ b/Makefile @@ -34,13 +34,17 @@ native: clean ctaklm pptdb $(CROSS_CC): ./resources/do_buildroot.sh $(BUILDROOT_DIR) -ct1986: src/ct1986.o include/lcdlib.o $(OBJS) - $(CC) $(CFLAGS) src/ct1986.o $(OBJS) include/lcdlib.o -o ct1986 +ct1986: CC=$(CROSS_CC) +ct1986: STRIP=$(CROSS_STRIP) +ct1986: $(CROSS_CC) clean src/ct1986.o include/lcdlib.o $(OBJS) + $(CC) $(CFLAGS) src/ct1986.o $(OBJS) include/lcdlib.o -o ct1986 -lcurses $(STRIP) ct1986 pi: CC=$(CROSS_CC) pi: STRIP=$(CROSS_STRIP) -pi: $(CROSS_CC) clean ctaklm ct1986 - cp ct1986 ctaklm $(BUILDROOT_DIR)/board/raspberrypi0/rootfs_overlay/ +pi: $(CROSS_CC) ct1986 ctaklm + mkdir -p $(BUILDROOT_DIR)/board/raspberrypi0/rootfs_overlay/usr/bin/ + cp ct1986 ctaklm $(BUILDROOT_DIR)/board/raspberrypi0/rootfs_overlay/usr/bin/ + cp resources/ash-profile $(BUILDROOT_DIR)/board/raspberrypi0/rootfs_overlay/.profile make -C $(BUILDROOT_DIR) $(info Image ready in $(BUILDROOT_DIR)/output/images/sdcard.img) diff --git a/include/lcdlib.c b/include/lcdlib.c index c956d5c..7f10e33 100644 --- a/include/lcdlib.c +++ b/include/lcdlib.c @@ -26,8 +26,6 @@ int lcd_begin(void) { lcd = fopen("/dev/lcd", "w"); if (lcd == NULL) return EXIT_FAILURE; - fprintf(lcd, "%sB", esc); - fflush(lcd); lcd_clear(); return EXIT_SUCCESS; } @@ -37,6 +35,18 @@ lcd_end(void) { fclose(lcd); } +void +lcd_set_blink(void) { + fprintf(lcd, "%sB", esc); + fflush(lcd); +} + +void +lcd_stop_blink(void) { + fprintf(lcd, "%sb", esc); + fflush(lcd); +} + void lcd_clear(void) { line_idx = 0; @@ -49,34 +59,38 @@ lcd_clear(void) { void lcd_put_line(const enum LCD_WRITE_MODE mode, const char *line) { - if (mode == L_SCROLL && line_idx == LCD_HEIGHT) { - // If we're at the bottom, ``shift'' everything up - for (int y = 1; y < LCD_HEIGHT; y++) { - // Go to the start of row y, clear the line, and print the - // previous string there - fprintf(lcd, "%sy%dx0;%sk%s", esc, y-1, esc, previous_lines[y]); - // Overwrite the stored previous line with the next - strncpy(previous_lines[y-1], previous_lines[y], 17); + char last_line = 0; + if (line_idx == LCD_HEIGHT) { + if (mode == L_SCROLL) { + // If we're at the bottom, ``shift'' everything up + for (int y = 1; y < LCD_HEIGHT; y++) { + // Go to the start of row y, clear the line, and print the + // previous string there + fprintf(lcd, "%sy%dx0;%sk%s", esc, y-1, esc, previous_lines[y]); + // Overwrite the stored previous line with the next + strncpy(previous_lines[y-1], previous_lines[y], LCD_WIDTH+1); + } } - line_idx--; + last_line = 1; } // Go to the correct line, clear it, and write the input. fprintf(lcd, "%sy%dx0;%sk%s", esc, line_idx, esc, line); fflush(lcd); // Store this line, null-terminate! - strncpy(previous_lines[line_idx], line, 16); - previous_lines[line_idx][16] = 0; + if (last_line) line_idx--; + strncpy(previous_lines[line_idx], line, LCD_WIDTH+1); + previous_lines[line_idx][LCD_WIDTH] = 0; if (mode == L_SCROLL && line_idx < LCD_HEIGHT) line_idx++; } void lcd_printf_line(const enum LCD_WRITE_MODE mode, const char *format, ...) { - char buf[16]; + char buf[LCD_WIDTH+1]; va_list(args); va_start(args, format); - vsnprintf(buf, 16, format, args); + vsnprintf(buf, LCD_WIDTH+1, format, args); va_end(args); lcd_put_line(mode, buf); diff --git a/include/lcdlib.h b/include/lcdlib.h index 192b3a4..b1cfc87 100644 --- a/include/lcdlib.h +++ b/include/lcdlib.h @@ -37,6 +37,9 @@ int lcd_begin(void); void lcd_end(void); void lcd_clear(void); +void lcd_set_blink(void); +void lcd_stop_blink(void); + void lcd_put_line(const enum LCD_WRITE_MODE mode, const char *line); void lcd_printf_line(const enum LCD_WRITE_MODE mode, diff --git a/resources/buildroot.config b/resources/buildroot.config index 7f56444..0708ae5 100644 --- a/resources/buildroot.config +++ b/resources/buildroot.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Buildroot -gec8dfa9 Configuration +# Buildroot -gc24be1f-dirty Configuration # BR2_HAVE_DOT_CONFIG=y BR2_HOST_GCC_AT_LEAST_4_9=y @@ -8,7 +8,6 @@ BR2_HOST_GCC_AT_LEAST_5=y BR2_HOST_GCC_AT_LEAST_6=y BR2_HOST_GCC_AT_LEAST_7=y BR2_HOST_GCC_AT_LEAST_8=y -BR2_HOST_GCC_AT_LEAST_9=y # # Target options @@ -2042,7 +2041,10 @@ BR2_PACKAGE_PROTOBUF_ARCH_SUPPORTS=y # BR2_PACKAGE_LIBFRIBIDI is not set # BR2_PACKAGE_LIBUNISTRING is not set # BR2_PACKAGE_LINENOISE is not set -# BR2_PACKAGE_NCURSES is not set +BR2_PACKAGE_NCURSES=y +BR2_PACKAGE_NCURSES_WCHAR=y +# BR2_PACKAGE_NCURSES_TARGET_PROGS is not set +BR2_PACKAGE_NCURSES_ADDITIONAL_TERMINFO="" # BR2_PACKAGE_NEWT is not set # BR2_PACKAGE_ONIGURUMA is not set # BR2_PACKAGE_PCRE is not set 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 #include +#include + #include #include #include -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 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; } diff --git a/src/ctaklm.c b/src/ctaklm.c index 681f29c..4d910c4 100644 --- a/src/ctaklm.c +++ b/src/ctaklm.c @@ -171,13 +171,16 @@ print_info(void) { } static int human; -static char *gamelog = 0; +static char *gamelog = NULL; static uint8_t auto_board = 0xFF, auto_info = 0xFF; -static void +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) { @@ -194,8 +197,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 @@ -438,13 +444,12 @@ int main(int argc, char **argv) { puts(license); - negamax_search_depth = 3; + negamax_search_depth = 5; new_game(5); negamax_init(5); // Test harness if (argc > 1) { - negamax_search_depth = 5; load_ptn("data/0.ptn"); negamax_turn(); return 0; -- cgit v1.2.3