]> git.cworth.org Git - dvonn/blobdiff - dvonn-board.c
Add a new dvonn_board_cell_owned_by function
[dvonn] / dvonn-board.c
index b6b36e5eac7dfefcbf1e6cce6d53901a8fcd7ff8..eeab83076294649ebe0ccdaa846ca59307eef1e0 100644 (file)
@@ -101,6 +101,19 @@ dvonn_board_cell_occupied (dvonn_board_t *board,
     return TRUE;
 }
 
+dvonn_bool_t
+dvonn_board_cell_owned_by (dvonn_board_t *board,
+                          int x, int y,
+                          dvonn_player_t player)
+{
+    if (! dvonn_board_cell_occupied (board, x, y))
+       return FALSE;
+
+    /* Cast here to avoid compiler warning about mixing enum types in
+     * a comparison. */
+    return board->cells[x][y].type == (dvonn_cell_type_t) player;
+}
+
 dvonn_bool_t
 dvonn_board_cell_surrounded (dvonn_board_t *board,
                             int x, int y)
@@ -152,7 +165,7 @@ dvonn_board_move_legal (dvonn_board_t *board,
        return FALSE;
     }
 
-    if (board->cells[x1][y1].type != board->player) {
+    if (! dvonn_board_cell_owned_by (board, x1, y1, board->player)) {
        *error = "You cannot move your opponent's stack";
        return FALSE;
     }
@@ -192,6 +205,17 @@ dvonn_board_next_player (dvonn_board_t *board)
        board->player = DVONN_PLAYER_BLACK;
 }
 
+int
+dvonn_board_pass (dvonn_board_t *board)
+{
+    /* XXX: Should check here and only allow a pass if there are
+     * no legal moves. */
+
+    dvonn_board_next_player (board);
+
+    return TRUE;
+}
+
 int
 dvonn_board_place (dvonn_board_t *board,
                   int x, int y,
@@ -220,14 +244,60 @@ dvonn_board_place (dvonn_board_t *board,
 
     board->moves++;
 
+    dvonn_board_next_player (board);
+
     if (board->moves == 49) {
        board->phase = DVONN_PHASE_MOVEMENT;
        board->moves = 0;
+       board->player = DVONN_PLAYER_WHITE;
     }
 
     return TRUE;
 }
 
+static void
+fill_living(dvonn_board_t *board,
+           int living[DVONN_BOARD_X_SIZE][DVONN_BOARD_Y_SIZE],
+           int x, int y)
+{
+    if (dvonn_board_cell_occupied (board, x, y) && ! living[x][y])
+    {
+       living[x][y] = 1;
+
+       fill_living (board, living, x - 1, y);
+       fill_living (board, living, x + 1, y);
+       fill_living (board, living, x, y - 1);
+       fill_living (board, living, x, y + 1);
+       fill_living (board, living, x + 1, y - 1);
+       fill_living (board, living, x - 1, y + 1);
+    }
+}
+
+static void
+eliminate_disconnected_stacks (dvonn_board_t *board)
+{
+    int x, y;
+    int living[DVONN_BOARD_X_SIZE][DVONN_BOARD_Y_SIZE];
+
+    for (x = 0; x < DVONN_BOARD_X_SIZE; x++)
+       for (y = 0; y < DVONN_BOARD_Y_SIZE; y++)
+           living[x][y] = 0;
+
+    for (x = 0; x < DVONN_BOARD_X_SIZE; x++)
+       for (y = 0; y < DVONN_BOARD_Y_SIZE; y++)
+           if (board->cells[x][y].contains_red)
+               fill_living (board, living, x, y);
+
+    for (x = 0; x < DVONN_BOARD_X_SIZE; x++)
+       for (y = 0; y < DVONN_BOARD_Y_SIZE; y++)
+           if (dvonn_board_cell_occupied (board, x, y) &&
+               ! living[x][y])
+           {
+               board->cells[x][y].type = DVONN_CELL_EMPTY;
+               board->cells[x][y].height = 0;
+           }
+}
+
 int
 dvonn_board_move (dvonn_board_t *board,
                  int x1, int y1,
@@ -250,6 +320,8 @@ dvonn_board_move (dvonn_board_t *board,
     board->cells[x1][y1].height = 0;
     board->cells[x1][y1].contains_red = FALSE;
 
+    eliminate_disconnected_stacks (board);
+
     dvonn_board_next_player (board);
 
     return TRUE;