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