summaryrefslogtreecommitdiff
path: root/src/move.c
diff options
context:
space:
mode:
authorRobby Zambito <contact@robbyzambito.me>2021-12-30 00:02:22 -0500
committerRobby Zambito <contact@robbyzambito.me>2021-12-30 00:02:22 -0500
commit6a35a3cffd976f6fa9d96759e2f2bb0f784b92ac (patch)
tree8c1f87ff19ab3cdb35a3450942846e1b1c736aa6 /src/move.c
parentb74a45d66405d59ea3f2891a10ee2c62f12134d9 (diff)
Pulled lots of things out of game loop
Diffstat (limited to 'src/move.c')
-rw-r--r--src/move.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/move.c b/src/move.c
new file mode 100644
index 0000000..a22cb59
--- /dev/null
+++ b/src/move.c
@@ -0,0 +1,95 @@
+/* This file is a part of othello-ai-guile-c
+ *
+ * Copyright (C) 2021 Robby Zambito
+ *
+ * othello-ai-guile-c is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * othello-ai-guile-c is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+
+#include <libguile.h>
+#include <readline/history.h>
+#include <readline/readline.h>
+
+#include "othello.h"
+#include "othello_move.h"
+
+#define STREQ(a, b) (strcmp(a, b) == 0)
+
+static void print_help() {
+ puts("To enter a move, enter the two row and column seperated by spaces.\n"
+ "For example `0 0` will select the top left corner.\n\n"
+ "p - Print the board again\n"
+ "g - Drop into a guile repl\n"
+ "\n"
+ "In the guile repl you can define an AI to use for the current"
+ "player.\n"
+ "After you define an AI for that player, it will be used for the rest "
+ "of the game instead of prompting for input for that user.\n");
+}
+
+static char *prompt_player(enum player_color current_player) {
+ switch (current_player) {
+ case WHITE:
+ return "Player 1 [h for help] > ";
+ case BLACK:
+ return "Player 2 [h for help] > ";
+ default:
+ perror("There is no current player");
+ exit(EXIT_FAILURE);
+ }
+}
+
+static void inner_main(void *closure, int argc, char **argv) {
+ (void)closure;
+ scm_shell(argc, argv);
+}
+
+struct move prompt_get_move(enum player_color current_player) {
+ // Initialize move to an invalid move.
+ struct move move = {-1, -1};
+
+ char *prompt = prompt_player(current_player);
+ do {
+ char *input = readline(prompt);
+
+ if (input != NULL) {
+ add_history(input);
+ if (STREQ(input, "h")) {
+ print_help();
+ } else if (STREQ(input, "p")) {
+ print_board();
+ } else if (STREQ(input, "g")) {
+ int argc = 1;
+ char **argv = calloc(1, sizeof(char *));
+ argv[0] = "othello";
+ /*scm_with_guile(void *(*func)(void *), void *data)*/
+ scm_boot_guile(argc, argv, inner_main, NULL);
+ free(argv);
+ } else {
+ sscanf(input, "%d %d", &move.row, &move.col);
+ }
+ } else {
+ // If input was NULL, we have reached an EOF and would like to exit.
+ free(input);
+ exit(0);
+ }
+
+ free(input);
+ } while (!is_valid_move(current_player, move));
+
+ return move;
+}