added game over screen
This commit is contained in:
@@ -42,9 +42,10 @@ void free_minefield(Minefield* mf);
|
||||
char cell_char(cell c);
|
||||
void print_minefield(Minefield *mf, FILE *stream);
|
||||
void draw_minefield(Minefield* mf);
|
||||
void draw_time(Minefield* mf, float time);
|
||||
cell* clicked_cell(Minefield* mf, int x, int y);
|
||||
void expose_cell(Minefield* mf, int r, int c);
|
||||
void handle_click(Minefield* mf);
|
||||
bool handle_click(Minefield* mf);
|
||||
|
||||
typedef enum screens {
|
||||
DEFAULT_SCREEN,
|
||||
@@ -54,7 +55,7 @@ typedef enum screens {
|
||||
} Screen;
|
||||
|
||||
Screen game_loop(Minefield* mf);
|
||||
/* Screen game_over(Minefield* mf); */
|
||||
Screen game_over_loop(Minefield* mf);
|
||||
Screen help_loop(Minefield *mf);
|
||||
|
||||
Screen (*screen_fn(Screen scr))(Minefield *);
|
||||
@@ -65,14 +66,14 @@ const int screenHeight = 450;
|
||||
float cell_size;
|
||||
int mark_count;
|
||||
bool dead;
|
||||
bool quit;
|
||||
float end_time;
|
||||
Screen (*loop)(Minefield*);
|
||||
|
||||
int main(){
|
||||
srand(time(NULL));
|
||||
Minefield mf = make_minefield(10, 20, 30);
|
||||
/* print_minefield(&mf, stdout); */
|
||||
dead = false;
|
||||
quit = false;
|
||||
mark_count = 0;
|
||||
{
|
||||
float width = (float) screenWidth / mf.col;
|
||||
@@ -85,8 +86,7 @@ int main(){
|
||||
|
||||
Screen screen = GAME_LOOP;
|
||||
Screen temp_screen;
|
||||
Screen (*loop)(Minefield*);
|
||||
while(!WindowShouldClose() && !quit){
|
||||
while(!WindowShouldClose()){
|
||||
loop = screen_fn(screen);
|
||||
temp_screen = (*loop)(&mf);
|
||||
last_screen = screen;
|
||||
@@ -99,19 +99,20 @@ int main(){
|
||||
}
|
||||
|
||||
Screen game_loop(Minefield* mf){
|
||||
while(!WindowShouldClose() && !quit){
|
||||
while(!WindowShouldClose()){
|
||||
|
||||
if (IsKeyPressed(KEY_H)){
|
||||
return HELP;
|
||||
}
|
||||
|
||||
if (!dead){
|
||||
handle_click(mf);
|
||||
if (handle_click(mf)){
|
||||
return GAME_OVER;
|
||||
}
|
||||
|
||||
BeginDrawing();
|
||||
ClearBackground(RAYWHITE);
|
||||
draw_minefield(mf);
|
||||
draw_time(mf, GetTime());
|
||||
EndDrawing();
|
||||
}
|
||||
return DEFAULT_SCREEN;
|
||||
@@ -129,14 +130,31 @@ Screen help_loop(Minefield *mf) {
|
||||
return last_screen;
|
||||
}
|
||||
|
||||
Screen game_over_loop(Minefield* mf){
|
||||
char* end_text = dead ? "You Died!" : "You Win!";
|
||||
while(!WindowShouldClose()){
|
||||
|
||||
if (IsKeyPressed(KEY_H)){
|
||||
return HELP;
|
||||
}
|
||||
|
||||
BeginDrawing();
|
||||
ClearBackground(RAYWHITE);
|
||||
draw_minefield(mf);
|
||||
draw_time(mf, end_time);
|
||||
DrawText(end_text, screenWidth / 2, screenHeight / 2, 30, BLACK);
|
||||
EndDrawing();
|
||||
}
|
||||
return DEFAULT_SCREEN;
|
||||
}
|
||||
|
||||
Screen (*screen_fn(Screen scr))(Minefield *) {
|
||||
switch (scr) {
|
||||
case GAME_LOOP:
|
||||
return game_loop;
|
||||
/* case GAME_OVER: */
|
||||
/* return game_loop; */
|
||||
case GAME_OVER:
|
||||
return game_over_loop;
|
||||
case HELP:
|
||||
return help_loop;
|
||||
case GAME_LOOP:
|
||||
default:
|
||||
return game_loop;
|
||||
}
|
||||
@@ -229,10 +247,13 @@ void draw_minefield(Minefield* mf){
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw_time(Minefield* mf, float time){
|
||||
char time_str[20];
|
||||
float time = GetTime();
|
||||
float t = time;
|
||||
snprintf(time_str, 20, "%02d.%02d - %d/%d",
|
||||
(int) time / 60, (int) time % 60,
|
||||
(int) t / 60, (int) t % 60,
|
||||
mark_count, mf->mine_count);
|
||||
DrawText(time_str, screenWidth / 2 - 20, screenHeight - 30, 20, BLACK);
|
||||
}
|
||||
@@ -263,23 +284,24 @@ void expose_cell(Minefield* mf, int r, int c){
|
||||
}
|
||||
}
|
||||
|
||||
void handle_click(Minefield* mf){
|
||||
bool 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;
|
||||
return false;
|
||||
}
|
||||
cell cell = get_cell(mf, r, c);
|
||||
|
||||
if (cell & MARKED){
|
||||
return;
|
||||
return false;
|
||||
} else if (cell & MINE){
|
||||
printf("DIED\n");
|
||||
expose_cell(mf, r, c);
|
||||
dead = true;
|
||||
end_time = GetTime();
|
||||
return dead = true;
|
||||
} else {
|
||||
expose_cell(mf, r, c);
|
||||
}
|
||||
@@ -289,25 +311,22 @@ void handle_click(Minefield* mf){
|
||||
|
||||
if (!(r >= 0 && r < mf->row && c >= 0 && c < mf->col)) {
|
||||
printf("Click outside range, (%d, %d)\n", r, c);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
mark_count += mf->cells[r * mf->col + c] & MARKED ? -1 : 1;
|
||||
mf->cells[r * mf->col + c] ^= MARKED;
|
||||
|
||||
bool sol = true;
|
||||
if (mark_count == mf->mine_count){
|
||||
for (int i = 0; i < mf->row * mf->col; i++){
|
||||
cell cel = mf->cells[i] & (MARKED | MINE);
|
||||
if (cel & MARKED && !(cel & MINE)){
|
||||
sol = false;
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (sol){
|
||||
printf("Solved\n");
|
||||
quit = true;
|
||||
}
|
||||
end_time = GetTime();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user