summaryrefslogtreecommitdiff
path: root/src/game_loop.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/game_loop.c
parentb74a45d66405d59ea3f2891a10ee2c62f12134d9 (diff)
Pulled lots of things out of game loop
Diffstat (limited to 'src/game_loop.c')
-rw-r--r--src/game_loop.c170
1 files changed, 14 insertions, 156 deletions
diff --git a/src/game_loop.c b/src/game_loop.c
index c11f473..bdb37f5 100644
--- a/src/game_loop.c
+++ b/src/game_loop.c
@@ -28,6 +28,7 @@
#include <string.h>
#include "othello.h"
+#include "othello_move.h"
#define STREQ(a, b) (strcmp(a, b) == 0)
@@ -35,169 +36,26 @@ static enum player_color current_player;
enum player_color get_current_player(void) { return current_player; }
-static enum player_color **board;
-
-const enum player_color **get_board(void) {
- return (const enum player_color **)board;
-}
-
struct move (*player_one_get_move)();
struct move (*player_two_get_move)();
-static enum player_color other_player(enum player_color current_player) {
- switch (current_player) {
- case WHITE:
- return BLACK;
- case BLACK:
- return WHITE;
- default:
- return EMPTY;
- }
-}
-
-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 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 void inner_main(void *closure, int argc, char **argv) {
- (void)closure;
- scm_shell(argc, argv);
-}
-
-static 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;
-}
-
-/* Returns true if the move was valid */
-static bool apply_move(enum player_color current_player, struct move move) {
-
- // Flip in up direction
- bool flipped_up = false;
- for (int i = move.row - 1;
- i > 0 && board[i][move.col] != EMPTY && !flipped_up; i--) {
- if (board[i][move.col] == current_player) {
- for (int j = move.row - 1; j > i; j--) {
- board[j][move.col] = current_player;
- }
- flipped_up = true;
- }
- }
-
- // Flip in down direction
- bool flipped_down = false;
- for (int i = move.row + 1;
- i < 8 && board[i][move.col] == EMPTY && !flipped_down; i++) {
- if (board[i][move.col] == current_player) {
- for (int j = move.row + 1; j < i; j++) {
- board[j][move.col] = current_player;
- }
- flipped_down = true;
- }
- }
-
- // Flip in left direction
- bool flipped_left = false;
- for (int i = move.col - 1;
- i > 0 && board[move.row][i] == EMPTY && !flipped_left; i--) {
- if (board[move.row][i] == current_player) {
- for (int j = move.col - 1; j > i; j--) {
- board[move.row][j] = current_player;
- }
- flipped_left = true;
- }
- }
-
- // Flip in right direction
- bool flipped_right = false;
- for (int i = move.col + 1;
- i < 8 && board[move.row][i] == EMPTY && !flipped_right; i++) {
- if (board[move.row][i] == current_player) {
- for (int j = move.col + 1; j < i; j++) {
- board[move.row][j] = current_player;
- }
- flipped_right = true;
- }
- }
-
- return flipped_up || flipped_down || flipped_left || flipped_right;
-}
-
-
enum player_color game_loop() {
- initialize_board(&board);
- using_history();
+ initialize_board();
+ using_history();
- current_player = WHITE;
+ current_player = WHITE;
+#define other_player (current_player == WHITE ? BLACK : WHITE)
- while (has_valid_moves(current_player)) {
- struct move move = prompt_get_move(current_player);
- apply_move(current_player, move);
- current_player = other_player(current_player);
- }
-
- int white_score = 0, black_score = 0;
- for (int row = 0; row < 8; row++) {
- for (int col = 0; col < 8; col++) {
- white_score += (int)(board[row][col] == WHITE);
- black_score += (int)(board[row][col] == BLACK);
+ while (has_valid_moves(current_player)) {
+ struct move move = prompt_get_move(current_player);
+ if (apply_move(current_player, move)) {
+ current_player = other_player;
+ }
}
- }
- rl_clear_history();
+#undef other_player
+
+ rl_clear_history();
- return white_score > black_score ? WHITE
- : black_score > white_score ? BLACK
- : EMPTY;
+ return get_winner();
}