summaryrefslogtreecommitdiff
path: root/minesweeper
diff options
context:
space:
mode:
authormRnea <akannemre@gmail.com>2024-12-20 01:32:56 +0300
committermRnea <akannemre@gmail.com>2024-12-20 01:32:56 +0300
commit0944b03fc0bdd86b467330ae1909ef5f32aef57c (patch)
tree3e9e2f972bb99191babd67341cf895887855d4a3 /minesweeper
parentf4012e2c8455ed3b94ef4007fac4647efe08ffb0 (diff)
added expansion, marks etc. basic functionality mostly finished.
Diffstat (limited to 'minesweeper')
-rw-r--r--minesweeper/mine.c136
1 files changed, 119 insertions, 17 deletions
diff --git a/minesweeper/mine.c b/minesweeper/mine.c
index a78659d..7ea5ec8 100644
--- a/minesweeper/mine.c
+++ b/minesweeper/mine.c
@@ -5,16 +5,18 @@
#include "../util.h"
typedef char cell;
-#define MINE 0b10000000
-#define MARKED 0b01000000
-#define EXPOSED 0b00100000
-#define NUMBERED 0b00000111
+#define MINE 0b10000000
+#define MARKED 0b01000000
+#define EXPOSED 0b00100000
+#define NUMBERED 0b00010000
+#define CELL_NUMBER 0b00000111
/*
cell is a char (8 bits)
0000 0000
- ^^^ ^^^
- ||| number of mine neigbours
+ ^^^^ ^^^
+ |||| number of mine neigbours
+ ||||> 1 if is a number
|||> 1 if exposed (revealed)
||> 1 if marked
|> 1 if mine
@@ -69,7 +71,7 @@ Minefield make_minefield(int row, int col, int mine_count){
}
}
}
- set_cell(&mf, i, j, c);
+ set_cell(&mf, i, j, c | NUMBERED);
}
}
}
@@ -89,7 +91,7 @@ char cell_char(cell c){
} else if (c & MINE) {
return '*';
} else {
- c &= NUMBERED;
+ c &= CELL_NUMBER;
return c > 0 ? c + '0' : ' ';
}
}
@@ -106,32 +108,125 @@ void print_minefield(Minefield *mf, FILE *stream) {
const int screenWidth = 800;
const int screenHeight = 450;
+float cell_size;
+bool dead;
void draw_minefield(Minefield* mf){
- float width = (float) screenWidth / mf->col;
- float height = (float) screenHeight / mf->row;
- float size = width > height ? height : width;
char str[2] = "0";
for (int i = 0; i < mf->row; i++){
for (int j = 0; j < mf->col; j++){
- int x = size * j;
- int y = size * i;
- DrawRectangleLines(x, y, size, size, BLACK);
- str[0] = cell_char(mf->cells[i * mf->col + j]);
- DrawText(str, x + size / 3, y + size / 3, 20, BLACK);
+ int x = cell_size * j;
+ int y = cell_size * i;
+ DrawRectangleLines(x, y, cell_size, cell_size, BLACK);
+ cell c = get_cell(mf, i, j);
+ if (c & EXPOSED){
+ str[0] = cell_char(c);
+ DrawText(str, x + cell_size / 3, y + cell_size / 3, 20, BLACK);
+ } else {
+ DrawRectangle(x + 2, y + 2 , cell_size - 4, cell_size - 4,
+ c & MARKED ? RED : GRAY);
+ }
}
}
}
+cell* clicked_cell(Minefield* mf, int x, int y){
+ int r = y / cell_size;
+ int c = x / cell_size;
+ if (r >= 0 && r < mf->row && c >= 0 && c < mf->col) {
+ return &mf->cells[r * mf->col + c];
+ }
+ return NULL;
+}
+
+void expose_cell(Minefield* mf, int r, int c){
+ cell* cel = &mf->cells[r * mf->col + c];
+ *cel |= EXPOSED;
+ if (*cel & NUMBERED && (*cel & CELL_NUMBER) == 0) {
+ for (int i = imax(r - 1, 0); i < imin(r + 2, mf->row); i++){
+ for (int j = imax(c - 1, 0); j < imin(c + 2, mf->col); j++){
+ cell tcell = get_cell(mf, i, j);
+ if (tcell & EXPOSED ||
+ !(tcell & NUMBERED)){
+ continue;
+ }
+ expose_cell(mf, i, j);
+ }
+ }
+ /* if (r - 1 >= 0 && !(get_cell(mf, r - 1, c) & EXPOSED)){ */
+ /* expose_cell(mf, r - 1, c); */
+ /* } */
+ /* if (c - 1 >= 0 && !(get_cell(mf, r, c - 1) & EXPOSED)){ */
+ /* expose_cell(mf, r, c - 1); */
+ /* } */
+ /* if (r + 1 < mf->row && !(get_cell(mf, r + 1, c) & EXPOSED)){ */
+ /* expose_cell(mf, r + 1, c); */
+ /* } */
+ /* if (c + 1 < mf->col && !(get_cell(mf, r, c + 1) & EXPOSED)){ */
+ /* expose_cell(mf, r, c + 1); */
+ /* } */
+ }
+}
+
+void handle_click(Minefield* mf){
+ if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)){
+ int r = GetMouseY() / cell_size;
+ int c = GetMouseX() / cell_size;
+
+ if (!(r >= 0 && r < mf->row && c >= 0 && c < mf->col)) {
+ printf("Click outside range, (%d, %d)\n", r, c);
+ return;
+ }
+ cell cell = get_cell(mf, r, c);
+
+ if (cell & MARKED){
+ return;
+ } else if (cell & MINE){
+ printf("DIED\n");
+ expose_cell(mf, r, c);
+ dead = true;
+ } else {
+ expose_cell(mf, r, c);
+ }
+ } else if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)){
+ int r = GetMouseY() / cell_size;
+ int c = GetMouseX() / cell_size;
+
+ if (!(r >= 0 && r < mf->row && c >= 0 && c < mf->col)) {
+ printf("Click outside range, (%d, %d)\n", r, c);
+ return;
+ }
+
+ mf->cells[r * mf->col + c] ^= MARKED;
+ }
+
+
+ /* putchar(cell_char(*c)); */
+ /* fflush(stdout); */
+
+}
+
int main(){
srand(time(NULL));
Minefield mf = make_minefield(10, 20, 30);
- print_minefield(&mf, stdout);
+ /* print_minefield(&mf, stdout); */
+ dead = false;
+
+ {
+ float width = (float) screenWidth / mf.col;
+ float height = (float) screenHeight / mf.row;
+ cell_size = width > height ? height : width;
+ }
InitWindow(screenWidth, screenHeight, "Minesweeper");
SetTargetFPS(60);
while(!WindowShouldClose()){
+
+ if (!dead){
+ handle_click(&mf);
+ }
+
BeginDrawing();
ClearBackground(RAYWHITE);
draw_minefield(&mf);
@@ -142,3 +237,10 @@ int main(){
return 0;
}
+
+/* if (IsKeyPressed(KEY_A)){ */
+/* for (int i = 0; i < mf.row * mf.col; i++){ */
+/* mf.cells[i] ^= EXPOSED; */
+/* } */
+/* } */
+