aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile12
-rw-r--r--include/lcdlib.c44
-rw-r--r--include/lcdlib.h3
-rw-r--r--resources/buildroot.config8
-rw-r--r--src/ct1986.c106
-rw-r--r--src/ctaklm.c17
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;
}
@@ -38,6 +36,18 @@ lcd_end(void) {
}
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;
for (int y = 0; y + 1 < LCD_HEIGHT; y++) {
@@ -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 <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;
}
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;