summaryrefslogtreecommitdiff
path: root/src/move.c
diff options
context:
space:
mode:
authorRobby Zambito <contact@robbyzambito.me>2022-01-21 18:26:46 -0500
committerRobby Zambito <contact@robbyzambito.me>2022-01-21 18:26:46 -0500
commit0026e5937a3f91a1551dee15bc7482ffee1735d6 (patch)
tree22d328c06829f131d33af02ed47027357646820b /src/move.c
parent0846d554b20df412aa16c7e250c400daee82dd59 (diff)
Made apply_move return the number of flipped spaces.
This will return zero for invalid moves, and non-zero for valid moves. This means we can continue to use the result of this as a boolean. Also created a new Scheme primitive which returns the number of tiles flipped by a given move. Created two strategies. One which picks the move that flips the most tiles in the current turn, and one which flips the least.
Diffstat (limited to 'src/move.c')
-rw-r--r--src/move.c74
1 files changed, 43 insertions, 31 deletions
diff --git a/src/move.c b/src/move.c
index 58e9911..b09c4b0 100644
--- a/src/move.c
+++ b/src/move.c
@@ -92,35 +92,36 @@ struct move prompt_get_move(enum player_color current_player) {
return move;
}
-/* Returns true if the move was valid */
-bool apply_move(enum player_color **board, enum player_color current_player,
- struct move move) {
+// Returns non-zero number if the move was valid.
+// Returns the number of flipped tiles.
+int apply_move(enum player_color **board, enum player_color current_player,
+ struct move move) {
// The move must be a positive position.
if (move.row < 0 || move.col < 0) {
- return false;
+ return 0;
}
// The move must be below the upper bounds of teh board.
if (move.row > 8 || move.col > 8) {
- return false;
+ return 0;
}
// The move must be an empty spot.
if (board[move.row][move.col] != EMPTY) {
- return false;
+ return 0;
}
// Flip in up direction
- bool flipped_up = false;
+ int num_flipped_up = 0;
for (int i = move.row - 1;
- i >= 0 && board[i][move.col] != EMPTY && !flipped_up; i--) {
+ i >= 0 && board[i][move.col] != EMPTY && num_flipped_up == 0; i--) {
if (board[i][move.col] == current_player) {
if (i < move.row - 1) {
for (int j = move.row; j > i; j--) {
board[j][move.col] = current_player;
+ num_flipped_up++;
}
- flipped_up = true;
} else {
break;
}
@@ -128,15 +129,15 @@ bool apply_move(enum player_color **board, enum player_color current_player,
}
// Flip in down direction
- bool flipped_down = false;
+ int num_flipped_down = 0;
for (int i = move.row + 1;
- i < 8 && board[i][move.col] != EMPTY && !flipped_down; i++) {
+ i < 8 && board[i][move.col] != EMPTY && num_flipped_down == 0; i++) {
if (board[i][move.col] == current_player) {
if (i > move.row + 1) {
for (int j = move.row; j < i; j++) {
board[j][move.col] = current_player;
+ num_flipped_down++;
}
- flipped_down = true;
} else {
break;
}
@@ -144,15 +145,15 @@ bool apply_move(enum player_color **board, enum player_color current_player,
}
// Flip in left direction
- bool flipped_left = false;
+ int num_flipped_left = 0;
for (int i = move.col - 1;
- i >= 0 && board[move.row][i] != EMPTY && !flipped_left; i--) {
+ i >= 0 && board[move.row][i] != EMPTY && num_flipped_left == 0; i--) {
if (board[move.row][i] == current_player) {
if (i < move.col - 1) {
for (int j = move.col; j > i; j--) {
board[move.row][j] = current_player;
+ num_flipped_left++;
}
- flipped_left = true;
} else {
break;
}
@@ -160,40 +161,34 @@ bool apply_move(enum player_color **board, enum player_color current_player,
}
// Flip in right direction
- bool flipped_right = false;
+ int num_flipped_right = 0;
for (int i = move.col + 1;
- i < 8 && board[move.row][i] != EMPTY && !flipped_right; i++) {
+ i < 8 && board[move.row][i] != EMPTY && num_flipped_right == 0; i++) {
if (board[move.row][i] == current_player) {
if (i > move.col + 1) {
for (int j = move.col; j < i; j++) {
board[move.row][j] = current_player;
+ num_flipped_right++;
}
- flipped_right = true;
} else {
break;
}
}
}
- return flipped_up || flipped_down || flipped_left || flipped_right;
+ return num_flipped_up + num_flipped_down + num_flipped_left +
+ num_flipped_right;
}
SCM scm_apply_move(SCM scm_move, SCM scm_board, SCM scm_player) {
struct move move = scm_move_to_c_move(scm_move);
- enum player_color **board;
- if (scm_is_null(scm_board)) {
- board = copy_board(get_board());
- } else {
- board = scm_board_to_c_board(scm_board);
- }
+ enum player_color **board =
+ SCM_UNBNDP(scm_board) ? get_board() : scm_board_to_c_board(scm_board);
- enum player_color player;
- if (scm_is_null(scm_player)) {
- player = get_current_player();
- } else {
- player = scm_player_to_c_player(scm_player);
- }
+ enum player_color player = SCM_UNBNDP(scm_player)
+ ? get_current_player()
+ : scm_player_to_c_player(scm_player);
SCM res_board;
@@ -207,6 +202,22 @@ SCM scm_apply_move(SCM scm_move, SCM scm_board, SCM scm_player) {
return res_board;
}
+SCM scm_get_num_flipped_by_move(SCM scm_move, SCM scm_board, SCM scm_player) {
+ struct move move = scm_move_to_c_move(scm_move);
+
+ enum player_color **board = SCM_UNBNDP(scm_board)
+ ? copy_board(get_board())
+ : scm_board_to_c_board(scm_board);
+
+ enum player_color player = SCM_UNBNDP(scm_player)
+ ? get_current_player()
+ : scm_player_to_c_player(scm_player);
+ SCM res_num = scm_from_int(apply_move(board, player, move));
+ free_board(board);
+
+ return res_num;
+}
+
struct move scm_move_to_c_move(SCM scm_move) {
struct move move = {-1, -1};
move.row = scm_to_int(scm_car(scm_move));
@@ -274,6 +285,7 @@ struct move get_scm_move(char *strategy_path) {
scm_c_define_gsubr("valid-moves", 0, 2, 0, scm_valid_moves);
scm_c_define_gsubr("apply-move", 1, 2, 0, scm_apply_move);
scm_c_define_gsubr("get-winner", 2, 0, 0, scm_get_winner);
+ scm_c_define_gsubr("flipped-by-move", 1, 2, 0, scm_get_num_flipped_by_move);
// Read the move from scheme
SCM scm_move = scm_c_primitive_load(strategy_path);