diff options
author | mRnea <akannemre@gmail.com> | 2024-12-20 01:32:56 +0300 |
---|---|---|
committer | mRnea <akannemre@gmail.com> | 2024-12-20 01:32:56 +0300 |
commit | 0944b03fc0bdd86b467330ae1909ef5f32aef57c (patch) | |
tree | 3e9e2f972bb99191babd67341cf895887855d4a3 /minesweeper | |
parent | f4012e2c8455ed3b94ef4007fac4647efe08ffb0 (diff) |
added expansion, marks etc. basic functionality mostly finished.
Diffstat (limited to 'minesweeper')
-rw-r--r-- | minesweeper/mine.c | 136 |
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; */ +/* } */ +/* } */ + |