Index

ncurses-minesweeper / 48085a2

Terminal game of Minesweeper, implemented in C with ncurses.

Latest Commit

{#}TimeHashSubjectAuthor#(+)(-)GPG?
5207 Sep 2024 07:4348085a2Fix format-security compile errorsJosh Stockin111G

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

text/plain4441 bytesdownload raw
1/* ncurses-minesweeper Copyright (c) 2021 Joshua 'joshuas3' Stockin
2 * <https://joshstock.in>
3 * <https://git.joshstock.in/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 <ncurses.h>
13
14#include "../game/game.h"
15#include "../game/reset.h"
16#include "../state.h"
17#include "../time.h"
18#include "../strings.h"
19#include "pages.h"
20#include "text.h"
21
22static int elapsed = 0;
23void render_topbar(int top, int left, int right, game_board *board) {
24 if (board->status == Waiting) {
25 elapsed = 0;
26 } else if (board->status == Playing) {
27 elapsed = 1 + (time_us() - board->time) / 1000000;
28 }
29 attron(A_BOLD);
30 if (elapsed < 999)
31 mvprintw(top, right - 4, "%03d", elapsed);
32 else
33 mvaddstr(top, right - 4, "999");
34 mvprintw(top, left, "%03d", board->mines_left);
35 attroff(A_BOLD);
36 int center = (int)(COLS / 2 - 1);
37 switch (board->status) {
38 case Waiting:
39 case Playing:
40 mvaddstr(top, center, "._.");
41 break;
42 case Done:
43 mvaddstr(top, center, "^-^");
44 break;
45 case Kaboom:
46 mvaddstr(top, center, "x_x");
47 break;
48 }
49}
50
51int draw_game(game_state *state, int ch) {
52 game_board *board = state->board;
53 int board_top = centery() - board->height/2 - 1;
54 if (board_top < 0) board_top = 0;
55 int bound_left = (int)(COLS / 2) - board->width;
56 if (bound_left < 0) bound_left = 0;
57 int bound_right = bound_left + board->width * 2;
58 render_topbar(board_top, bound_left, bound_right, board);
59
60 // handle input
61 switch (ch) {
62 case -1: {
63 return 0;
64 }
65 case KEY_RESIZE: {
66 clear();
67 break;
68 }
69 case 27: {
70 clear();
71 reset_board(state->board);
72 state->page = Title;
73 state->page_selection = 0;
74 return draw_title_screen(state, 0);
75 }
76 case '?': {
77 clear();
78 state->page = Help;
79 state->last_page = Game;
80 return draw_help_screen(state, 0);
81 }
82 }
83
84 game(state, ch); // pass input to game controller
85
86 // draw board
87 attron(A_BOLD);
88 for (int cell = 0; cell < board->width * board->height; cell++) {
89 int x = bound_left + cell % board->width * 2;
90 int y = board_top + 1 + cell / board->width;
91 if (board->current_cell == cell) attron(A_STANDOUT); // highlight selected cell
92 game_board_cell *this_cell = &board->cells[cell];
93 if (!this_cell->flagged) {
94 if (!this_cell->opened) { // unopened unflagged, grey territory
95 attroff(A_BOLD);
96 mvaddch(y, x, '~');
97 attron(A_BOLD);
98 } else { // opened but unflagged
99 if (this_cell->is_bomb) { // bomb opened
100 attron(COLOR_PAIR(5));
101 mvaddch(y, x, 'X');
102 attroff(COLOR_PAIR(5));
103 } else if (this_cell->surrounding_bomb_count) { // surrounding bomb-count label
104 int count = this_cell->surrounding_bomb_count;
105 attron(COLOR_PAIR(count));
106 mvaddch(y, x, '0' + count);
107 attroff(COLOR_PAIR(count));
108 } else { // no surrounding bombs, open area
109 mvaddch(y, x, ' ');
110 }
111 }
112 } else { // flagged cell
113 attron(A_STANDOUT);
114 if (board->status != Kaboom)
115 mvaddch(y, x, 'X');
116 else {
117 if (!board->cells[cell].is_bomb) { // highlight false positives when done
118 attron(COLOR_PAIR(5));
119 mvaddch(y, x, 'X');
120 attroff(COLOR_PAIR(5));
121 } else
122 mvaddch(y, x, 'X');
123 }
124 attroff(A_STANDOUT);
125 }
126 if (board->current_cell == cell) attroff(A_STANDOUT); // un-highlight selected cell
127 }
128 attroff(A_BOLD);
129
130 // write help note at bottom
131 mvprintw(LINES - 1, centerx(game_help_note), "%s", game_help_note);
132
133 return 0;
134}
135