5 #include <gui/basics.h>
6 #include <gui/circle.h>
7 #include <drv/input/keyboard.h>
8 #include <drv/input/mouse.h>
10 #include "./minesweeper_sprites.h"
14 #define FIELD_HEIGHT 9
34 void init_array(
array* arr) {
40 arr->arr = krealloc(arr->arr, (arr->size + 1) *
sizeof(
block*));
42 arr->arr[arr->size - 1] = item;
46 return arr->arr[index];
49 void array_clear(
array* arr) {
58 to->size = from->size;
63 block field[FIELD_WIDTH * FIELD_HEIGHT] = {0};
68 void draw_sprite(
const uint32_t*
sprite,
const uint32_t sprite_size, int32_t sx, int32_t sy) {
69 for (
int x = 0; x < sprite_size; ++x) {
70 for (
int y = 0; y < sprite_size; ++y) {
71 uint32_t pix =
sprite[sprite_size * y + x];
72 if (pix >> 24 == 0)
continue;
73 set_pixel(sx + x, sy + y,
74 ((pix & 0xFF0000) >> 16) + (pix & 0x00FF00) + ((pix & 0x0000FF) << 16));
79 void init_field(int32_t sx, int32_t sy) {
80 for (
int x = 0; x < 9; ++x) {
81 for (
int y = 0; y < 9; ++y) {
82 block* b = &field[FIELD_HEIGHT * x + y];
85 b->sx = sx + x * BLOCK_SIZE + x * 2;
86 b->sy = sy + y * BLOCK_SIZE + y * 2;
94 for (
int i = 0; i < 10; ++i) {
95 int r = (uint32_t)rand() % 81;
100 for (
int i = 0; i < 81; ++i) {
101 block* b = &field[i];
106 for (
int x = -1; x < 2; ++x) {
107 for (
int y = -1; y < 2; ++y) {
110 if (xx < 0 || yy < 0 || xx >= FIELD_WIDTH ||
111 yy >= FIELD_HEIGHT || (xx == b->fx && yy == b->fy))
continue;
112 block* bb = &field[FIELD_HEIGHT * xx + yy];
113 if (bb->has_mine) ++count;
123 for (
int i = 0; i < 81; ++i) {
124 block* b = &field[i];
128 draw_filled_rectangle(b->sx, b->sy, BLOCK_SIZE, BLOCK_SIZE, 0xAAAAAA);
131 draw_sprite(flag_sprite, FLAG_FRAME_SIZE, b->sx, b->sy);
134 draw_filled_rectangle(b->sx, b->sy, BLOCK_SIZE, BLOCK_SIZE, 0x777777);
140 uint32_t* num = nums_sprites[b->count - 1];
141 draw_sprite(num, NUMS_FRAME_SIZE, b->sx, b->sy);
145 draw_sprite(mine_sprite, MINE_FRAME_SIZE, b->sx, b->sy);
152 if (getCharRaw() == 1) running = 0;
155 if (mouse_get_b1()) {
158 int32_t mx = mouse_get_x();
159 int32_t my = mouse_get_y();
161 for (
int i = 0; i < FIELD_WIDTH * FIELD_HEIGHT; ++i) {
162 block* b = &field[i];
164 if (mx >= b->sx && mx <= b->sx + BLOCK_SIZE &&
165 my >= b->sy && my <= b->sy + BLOCK_SIZE) {
166 if (!b->checked && b->closed) {
171 array_append(&arr, b);
173 array second_arr = {0};
174 init_array(&second_arr);
177 for (
size_t i = 0; i < arr.size; ++i) {
178 b = array_get(&arr, i);
180 for (
int x = -1; x < 2; ++x) {
183 if (xx < 0 || yy < 0 || xx >= FIELD_WIDTH ||
184 yy >= FIELD_HEIGHT || (xx == b->fx && yy == b->fy))
continue;
185 block* bb = &field[FIELD_HEIGHT * xx + yy];
186 if (!bb->checked && bb->closed && !bb->has_mine) {
188 if (bb->count == 0) array_append(&second_arr, bb);
192 for (
int y = -1; y < 2; ++y) {
195 if (xx < 0 || yy < 0 || xx >= FIELD_WIDTH ||
196 yy >= FIELD_HEIGHT || (xx == b->fx && yy == b->fy))
continue;
197 block* bb = &field[FIELD_HEIGHT * xx + yy];
198 if (!bb->checked && bb->closed && !bb->has_mine) {
200 if (bb->count == 0) array_append(&second_arr, bb);
205 move_array(&second_arr, &arr);
207 }
while (arr.size != 0);
210 array_clear(&second_arr);
214 if (b->has_mine) running = 0;
223 if (mouse_get_b2()) {
226 int32_t mx = mouse_get_x();
227 int32_t my = mouse_get_y();
229 for (
int i = 0; i < 81; ++i) {
230 block* b = &field[i];
231 if (mx >= b->sx && mx <= b->sx + BLOCK_SIZE &&
232 my >= b->sy && my <= b->sy + BLOCK_SIZE) {
233 b->checked = !b->checked;
244 set_cursor_enabled(
false);
245 keyboardctl(KEYBOARD_ECHO,
false);
259 draw_circle(lmx, lmy, 3, 0x000000);
261 int32_t mx = mouse_get_x();
262 int32_t my = mouse_get_y();
263 draw_circle(mx, my, 3, 0xFFFFFF);
270 if (getCharRaw() == 1)
break;
274 set_cursor_enabled(
true);
276 keyboardctl(KEYBOARD_ECHO,
true);