aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortslil clingman <tslil@posteo.de>2021-01-31 15:33:30 -0500
committertslil <tslil@posteo.de>2026-08-28 19:37:41 +0100
commit399d90f1b94717aa0ca5abb1dc43bdb6f4160d13 (patch)
tree21c954622a23fa606dacfe85552df92f6f195903 /src
parent84ad2e3c12cb505e3c5e3dd29d05edb529b82174 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/ct1986.c106
-rw-r--r--src/ctaklm.c17
2 files changed, 87 insertions, 36 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;
}
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;