X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=dvonn-board.c;h=eeab83076294649ebe0ccdaa846ca59307eef1e0;hb=7e10cab22cd0cd20ff48bf5665f0f7536f1ad032;hp=b6b36e5eac7dfefcbf1e6cce6d53901a8fcd7ff8;hpb=74df2492e8c32df37d886dec4baf9344dc6b8cff;p=dvonn diff --git a/dvonn-board.c b/dvonn-board.c index b6b36e5..eeab830 100644 --- a/dvonn-board.c +++ b/dvonn-board.c @@ -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;