11
11
#define TILE_WIDTH 8
12
12
#define TILE_HEIGHT 8
13
13
14
+ #define MINECOUNT 27
15
+
14
16
typedef enum {
15
17
EventTypeTick ,
16
18
EventTypeKey ,
@@ -22,7 +24,7 @@ typedef struct {
22
24
} PluginEvent ;
23
25
24
26
typedef enum {
25
- TileTypeUncleared ,
27
+ TileTypeUncleared , // this HAS to be the first element so it gets assigned 0 for easier init :)
26
28
TileTypeCleared ,
27
29
TileType0 ,
28
30
TileType1 ,
@@ -38,15 +40,16 @@ typedef enum {
38
40
} TileType ;
39
41
40
42
typedef enum {
41
- FieldMine ,
42
- FieldEmpty
43
+ FieldEmpty , // <-- same goes for this
44
+ FieldMine
43
45
} Field ;
44
46
45
47
typedef struct {
46
48
Field minefield [PLAYFIELD_WIDTH ][PLAYFIELD_HEIGHT ];
47
49
TileType playfield [PLAYFIELD_WIDTH ][PLAYFIELD_HEIGHT ];
48
50
int cursor_cell_x ;
49
51
int cursor_cell_y ;
52
+ bool game_started ;
50
53
} Minesweeper ;
51
54
52
55
static void input_callback (InputEvent * input_event , FuriMessageQueue * event_queue ) {
@@ -67,13 +70,23 @@ static void render_callback(Canvas* const canvas, void* ctx) {
67
70
if ( x == minesweeper_state -> cursor_cell_x && y == minesweeper_state -> cursor_cell_y ) {
68
71
canvas_invert_color (canvas );
69
72
}
70
- canvas_draw_xbm (
71
- canvas ,
72
- x * TILE_HEIGHT , // x
73
- 8 + (y * TILE_WIDTH ), // y
74
- TILE_WIDTH ,
75
- TILE_HEIGHT ,
76
- tile_uncleared_bits );
73
+ if (minesweeper_state -> minefield [x ][y ] == FieldMine ) {
74
+ canvas_draw_xbm (
75
+ canvas ,
76
+ x * TILE_HEIGHT , // x
77
+ 8 + (y * TILE_WIDTH ), // y
78
+ TILE_WIDTH ,
79
+ TILE_HEIGHT ,
80
+ tile_mine_bits );
81
+ } else {
82
+ canvas_draw_xbm (
83
+ canvas ,
84
+ x * TILE_HEIGHT , // x
85
+ 8 + (y * TILE_WIDTH ), // y
86
+ TILE_WIDTH ,
87
+ TILE_HEIGHT ,
88
+ tile_uncleared_bits );
89
+ }
77
90
if ( x == minesweeper_state -> cursor_cell_x && y == minesweeper_state -> cursor_cell_y ) {
78
91
canvas_invert_color (canvas );
79
92
}
@@ -82,9 +95,31 @@ static void render_callback(Canvas* const canvas, void* ctx) {
82
95
release_mutex ((ValueMutex * )ctx , minesweeper_state );
83
96
}
84
97
98
+ static void setup_playfield (Minesweeper * minesweeper_state ) {
99
+ int mines_left = MINECOUNT ;
100
+ while (mines_left > 0 ) {
101
+ int rand_x = rand () % PLAYFIELD_WIDTH ;
102
+ int rand_y = rand () % PLAYFIELD_HEIGHT ;
103
+ // make sure first guess isn't a mine
104
+ if (minesweeper_state -> minefield [rand_x ][rand_y ] == FieldEmpty &&
105
+ (minesweeper_state -> cursor_cell_x != rand_x && minesweeper_state -> cursor_cell_y != rand_y )) {
106
+ minesweeper_state -> minefield [rand_x ][rand_y ] = FieldMine ;
107
+ mines_left -- ;
108
+ }
109
+ }
110
+ }
85
111
86
112
static void minesweeper_state_init (Minesweeper * const plugin_state ) {
87
113
plugin_state -> cursor_cell_x = plugin_state -> cursor_cell_y = 0 ;
114
+ plugin_state -> game_started = false;
115
+ for (int y = 0 ; y < PLAYFIELD_HEIGHT ; y ++ ) {
116
+ for (int x = 0 ; x < PLAYFIELD_WIDTH ; x ++ ){
117
+ plugin_state -> minefield [x ][y ] = FieldEmpty ;
118
+ plugin_state -> playfield [x ][y ] = TileTypeUncleared ;
119
+ }
120
+ }
121
+ //plugin_state->minefield = {0};
122
+ //plugin_state->playfield = {0};
88
123
}
89
124
90
125
int32_t minesweeper_app (void * p ) {
@@ -147,6 +182,10 @@ int32_t minesweeper_app(void* p) {
147
182
}
148
183
break ;
149
184
case InputKeyOk :
185
+ if (!minesweeper_state -> game_started ) {
186
+ setup_playfield (minesweeper_state );
187
+ minesweeper_state -> game_started = true;
188
+ }
150
189
break ;
151
190
case InputKeyBack :
152
191
// Exit the plugin
0 commit comments