added expansion, marks etc. basic functionality mostly finished.
This commit is contained in:
@@ -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; */
|
||||
/* } */
|
||||
/* } */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user