]> git.cworth.org Git - dvonn/blobdiff - dvonn-board.c
Enforce legal moves
[dvonn] / dvonn-board.c
index 4d09e13be58f0ce25f2ee048bca2ea11391ee2b5..b6b36e5eac7dfefcbf1e6cce6d53901a8fcd7ff8 100644 (file)
@@ -82,12 +82,50 @@ dvonn_board_init (dvonn_board_t *board)
     board->moves = 0;
 }
 
+dvonn_bool_t
+dvonn_board_cell_occupied (dvonn_board_t *board,
+                          int x, int y)
+{
+    if (x < 0 || x >= DVONN_BOARD_X_SIZE ||
+       y < 0 || y >= DVONN_BOARD_Y_SIZE)
+    {
+       return FALSE;
+    }
+
+    if (board->cells[x][y].type == DVONN_CELL_INVALID ||
+       board->cells[x][y].type == DVONN_CELL_EMPTY)
+    {
+       return FALSE;
+    }
+
+    return TRUE;
+}
+
+dvonn_bool_t
+dvonn_board_cell_surrounded (dvonn_board_t *board,
+                            int x, int y)
+{
+    int surround_count;
+
+    surround_count =
+       dvonn_board_cell_occupied (board, x - 1, y) +
+       dvonn_board_cell_occupied (board, x + 1, y) +
+       dvonn_board_cell_occupied (board, x, y - 1) +
+       dvonn_board_cell_occupied (board, x, y + 1) +
+       dvonn_board_cell_occupied (board, x + 1, y - 1) +
+       dvonn_board_cell_occupied (board, x - 1, y + 1);
+
+    return (surround_count == 6);
+}
+
 static dvonn_bool_t
 dvonn_board_move_legal (dvonn_board_t *board,
                        int x1, int y1,
                        int x2, int y2,
                        char **error)
 {
+    int distance;
+
     if (x1 < 0 || x1 >= DVONN_BOARD_X_SIZE ||
        y1 < 0 || y1 >= DVONN_BOARD_Y_SIZE ||
        x2 < 0 || x2 >= DVONN_BOARD_X_SIZE ||
@@ -97,22 +135,50 @@ dvonn_board_move_legal (dvonn_board_t *board,
        return FALSE;
     }
 
-    if (board->cells[x1][y1].type == DVONN_CELL_INVALID) {
+    if (board->cells[x1][y1].type == DVONN_CELL_INVALID ||
+       board->cells[x2][y2].type == DVONN_CELL_INVALID)
+    {
        *error = "Not a valid board space";
        return FALSE;
     }
 
     if (board->cells[x1][y1].type == DVONN_CELL_EMPTY) {
-       *error = "There is no piece there to move";
+       *error = "There are no pieces there to move";
+       return FALSE;
+    }
+
+    if (dvonn_board_cell_surrounded (board, x1, y1)) {
+       *error = "You cannot move a piece that is surrounded";
        return FALSE;
     }
 
     if (board->cells[x1][y1].type != board->player) {
-       *error = "You cannot move your opponent's piece";
+       *error = "You cannot move your opponent's stack";
        return FALSE;
     }
 
-    /* XXX: Need to code up DVONN-legal move calculation here. */
+    if (board->cells[x2][y2].type == DVONN_CELL_EMPTY) {
+       *error = "You cannot move to an empty space";
+       return FALSE;
+    }
+
+    /* Move must be in a straight line, which in our array is
+     * horizontal, vertical, or one of the diagonals. */
+    if (x2 == x1)
+       distance = abs (y2 - y1);
+    else if (y2 == y1)
+       distance = abs (x2 - x1);
+    else if ((x2 - x1) == - (y2 - y1))
+       distance = abs (x2 - x1);
+    else {
+       *error = "Move is not in a straight line";
+       return FALSE;
+    }
+
+    if (distance != board->cells[x1][y1].height) {
+       *error = "Move distance is not the same as stack height";
+       return FALSE;
+    }
 
     return TRUE;
 }