1 | /* ncurses-minesweeper Copyright (c) 2020 Joshua 'joshuas3' Stockin |
2 | * <https://joshstock.in> |
3 | * <https://github.com/JoshuaS3/ncurses-minesweeper> |
4 | * |
5 | * This software is licensed and distributed under the terms of the MIT License. |
6 | * See the MIT License in the LICENSE file of this project's root folder. |
7 | * |
8 | * This comment block and its contents, including this disclaimer, MUST be |
9 | * preserved in all copies or distributions of this software's source. |
10 | */ |
11 |
|
12 | #include <stdlib.h> |
13 |
|
14 | #include "../state.h" |
15 | #include "kaboom.h" |
16 |
|
17 | int16_t *list_nearby_cells(game_board *board, uint16_t cell) { |
18 | int16_t *cells = (int16_t *)calloc(9, sizeof(int16_t)); |
19 | if (cells == NULL) abort(); |
20 | uint8_t board_width = board->width; |
21 | uint8_t board_height = board->height; |
22 | cells[0] = cell - board_width - 1; |
23 | cells[1] = cell - board_width; |
24 | cells[2] = cell - board_width + 1; |
25 | cells[3] = cell - 1; |
26 | cells[4] = cell; |
27 | cells[5] = cell + 1; |
28 | cells[6] = cell + board_width - 1; |
29 | cells[7] = cell + board_width; |
30 | cells[8] = cell + board_width + 1; |
31 | if (cell % board_width == 0) { // left edge |
32 | cells[0] = cell; |
33 | cells[3] = cell; |
34 | cells[6] = cell; |
35 | } |
36 | if ((cell + 1) % board_width == 0) { // right edge |
37 | cells[2] = cell; |
38 | cells[5] = cell; |
39 | cells[8] = cell; |
40 | } |
41 | if (cell < board_width) { // top edge |
42 | cells[0] = cell; |
43 | cells[1] = cell; |
44 | cells[2] = cell; |
45 | } |
46 | if (cell >= board_width * (board_height - 1)) { // bottom edge |
47 | cells[6] = cell; |
48 | cells[7] = cell; |
49 | cells[8] = cell; |
50 | } |
51 | return cells; |
52 | } |
53 |
|
54 | void recursively_open_nearby_cells(game_board *board, uint16_t cell) { |
55 | int16_t *nearby = list_nearby_cells(board, cell); |
56 | for (int i = 0; i < 9; i++) { |
57 | uint16_t c = nearby[i]; |
58 | game_board_cell *x = &board->cells[c]; |
59 | if (c != cell && !x->opened && !x->flagged) { |
60 | // open unopened cell |
61 | x->opened = 1; |
62 | if (!x->is_bomb && x->surrounding_bomb_count == 0) |
63 | // recursive open if not bomb, 0 surrounding bombs, AND not flagged |
64 | recursively_open_nearby_cells(board, c); |
65 | else if (x->is_bomb) { |
66 | kaboom(board); |
67 | return; |
68 | } |
69 | } |
70 | } |
71 | free(nearby); |
72 | } |
73 |
|