Index

ncurses-minesweeper / 82ddf89

Terminal game of Minesweeper, implemented in C with ncurses.

Latest Commit

{#}TimeHashSubjectAuthor#(+)(-)GPG?
1812 Sep 2020 23:2382ddf89Colors; base game state and game renderingJosh Stockin1870G

Blob @ ncurses-minesweeper / src / game / game.c

text/plain2264 bytesdownload raw
1#include <stdlib.h>
2#include <time.h>
3
4#include "../state.h"
5
6int16_t *nearby_cells(uint16_t s, uint8_t w, uint8_t h) {
7 int16_t *cells = malloc(sizeof(int16_t) * 9);
8 cells[0] = s - w - 1;
9 cells[1] = s - w;
10 cells[2] = s - w + 1;
11 cells[3] = s - 1;
12 cells[4] = s;
13 cells[5] = s + 1;
14 cells[6] = s + w - 1;
15 cells[7] = s + w;
16 cells[8] = s + w + 1;
17 if (s % w == 0) { // left edge
18 cells[0] = s;
19 cells[3] = s;
20 cells[6] = s;
21 }
22 if ((s + 1) % w == 0) { // right edge
23 cells[2] = s;
24 cells[5] = s;
25 cells[8] = s;
26 }
27 if (s < w) { // top edge
28 cells[0] = s;
29 cells[1] = s;
30 cells[2] = s;
31 }
32 if (s > w * (h - 1)) { // bottom edge
33 cells[6] = s;
34 cells[7] = s;
35 cells[8] = s;
36 }
37 return cells;
38}
39
40void new_game(game_board *board) {
41 // generate board
42 board->mines_left = board->mine_count;
43 board->cells = calloc(board->width * board->height, sizeof(game_board_cell));
44
45 // open start
46 uint16_t s = board->current_cell;
47
48 int16_t *open_start_cells = nearby_cells(s, board->width, board->height);
49
50 for (int cell = 0; cell < 9; cell++) {
51 board->cells[open_start_cells[cell]].is_bomb = 0;
52 board->cells[open_start_cells[cell]].opened = 1;
53 }
54
55 free(open_start_cells);
56
57 // generate mines
58 int mines_generated = 0;
59 uint16_t end = board->width * board->height;
60
61 srand(time(0));
62
63 while (mines_generated < board->mine_count) {
64 int n = rand() % end;
65 if (!board->cells[n].is_bomb && !board->cells[n].opened) {
66 board->cells[n].is_bomb = 1;
67 mines_generated++;
68 }
69 }
70
71 // get surrounding mine counts
72 for (int i = 0; i < end; i++) {
73 if (board->cells[i].is_bomb) continue;
74 int16_t *close_cells = nearby_cells(i, board->width, board->height);
75 for (int j = 0; j < 9; j++) {
76 int16_t close_cell = close_cells[j];
77 if (close_cell != i && board->cells[close_cell].is_bomb) board->cells[i].surrounding_bomb_count++;
78 }
79 free(close_cells);
80 }
81}
82
83void game(game_state *state, int ch) {
84 if (ch == 0) { // create new game
85 new_game(state->board);
86 }
87}
88