board->phase = DVONN_PHASE_PLACEMENT;
board->player = DVONN_PLAYER_WHITE;
board->moves = 0;
+ board->score[DVONN_PLAYER_BLACK] = 0;
+ board->score[DVONN_PLAYER_WHITE] = 0;
}
dvonn_bool_t
return TRUE;
}
-static void
+static dvonn_bool_t
+dvonn_board_player_has_legal_move (dvonn_board_t *board)
+{
+ int x, y, height;
+ char *error;
+
+ for (x = 0; x < DVONN_BOARD_X_SIZE; x++) {
+ for (y = 0; y < DVONN_BOARD_X_SIZE; y++) {
+ if (! dvonn_board_cell_occupied (board, x, y))
+ continue;
+ if (! (board->cells[x][y].type == (dvonn_cell_type_t) board->player))
+ continue;
+ height = board->cells[x][y].height;
+ if (dvonn_board_move_legal (board, x, y,
+ x + height, y, &error))
+ return TRUE;
+ if (dvonn_board_move_legal (board, x, y,
+ x - height, y, &error))
+ return TRUE;
+ if (dvonn_board_move_legal (board, x, y,
+ x, y + height, &error))
+ return TRUE;
+ if (dvonn_board_move_legal (board, x, y,
+ x, y - height, &error))
+ return TRUE;
+ if (dvonn_board_move_legal (board, x, y,
+ x + height, y - height, &error))
+ return TRUE;
+ if (dvonn_board_move_legal (board, x, y,
+ x - height, y + height, &error))
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+static dvonn_phase_t
dvonn_board_next_player (dvonn_board_t *board)
{
if (board->player == DVONN_PLAYER_BLACK)
board->player = DVONN_PLAYER_WHITE;
else
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);
+ /* Only look for legal moves during the movement phase. */
+ if (board->phase != DVONN_PHASE_MOVEMENT)
+ return board->phase;
+
+ if (! dvonn_board_player_has_legal_move (board)) {
+ if (board->player == DVONN_PLAYER_BLACK)
+ board->player = DVONN_PLAYER_WHITE;
+ else
+ board->player = DVONN_PLAYER_BLACK;
+
+ if (! dvonn_board_player_has_legal_move (board))
+ {
+ int x, y;
+ dvonn_cell_t *cell;
+
+ board->phase = DVONN_PHASE_GAME_OVER;
+
+ /* Compute final score. */
+ 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))
+ {
+ cell = &board->cells[x][y];
+ if (cell->type == DVONN_CELL_RED)
+ continue;
+ board->score[cell->type] += cell->height;
+ }
+ }
+ }
+ }
+ }
- return TRUE;
+ return board->phase;
}
int
if (event->type >= GDK_2BUTTON_PRESS)
return TRUE;
- /* Right-click means pass, (yes, it would be better to add some
- * actual UI elements... */
- if (event->button == 3) {
- dvonn_board_pass (&game->board);
- return TRUE;
- }
-
x = event->x;
y = event->y;
layout_device_to_board (layout, &x, &y);
pango_font_description_set_family (game->font, DVONN_FONT);
pango_font_description_set_absolute_size (game->font, DVONN_FONT_SIZE * PANGO_SCALE);
}
- to_move = _create_layout_printf (cr, game->font,
- "%s to %s.",
- game->board.player == DVONN_PLAYER_WHITE ?
- "White" : "Black",
- game->board.phase == DVONN_PHASE_PLACEMENT ?
- "place" : "move");
+ if (game->board.phase == DVONN_PHASE_GAME_OVER) {
+ if (game->board.score[DVONN_PLAYER_WHITE] >
+ game->board.score[DVONN_PLAYER_BLACK])
+ {
+ to_move = _create_layout_printf (cr, game->font,
+ "White wins (%d to %d)\n",
+ game->board.score[DVONN_PLAYER_WHITE],
+ game->board.score[DVONN_PLAYER_BLACK]);
+ }
+ else if (game->board.score[DVONN_PLAYER_BLACK] >
+ game->board.score[DVONN_PLAYER_WHITE])
+ {
+ to_move = _create_layout_printf (cr, game->font,
+ "Black wins (%d to %d)\n",
+ game->board.score[DVONN_PLAYER_BLACK],
+ game->board.score[DVONN_PLAYER_WHITE]);
+ }
+ else
+ {
+ to_move = _create_layout_printf (cr, game->font,
+ "Tie game (%d to %d)\n",
+ game->board.score[DVONN_PLAYER_WHITE],
+ game->board.score[DVONN_PLAYER_BLACK]);
+
+ }
+ } else {
+ to_move = _create_layout_printf (cr, game->font,
+ "%s to %s.",
+ game->board.player == DVONN_PLAYER_WHITE ?
+ "White" : "Black",
+ game->board.phase == DVONN_PHASE_PLACEMENT ?
+ "place" : "move");
+ }
cairo_move_to (cr, 2, 2);
if (game->board.player == DVONN_PLAYER_WHITE)
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);