the game lol
|
@ -0,0 +1,36 @@
|
|||
# A simple Makefile for compiling small SDL projects
|
||||
|
||||
# set the compiler
|
||||
CC := gcc
|
||||
|
||||
# set the compiler flags
|
||||
CFLAGS := `sdl2-config --libs --cflags` -ggdb3 -O2 --std=c99 -Wall -lSDL2_image -lSDL2_mixer -lm
|
||||
|
||||
# add header files here
|
||||
HDRS := *.h
|
||||
|
||||
# add source files here
|
||||
SRCS := *.c
|
||||
|
||||
# generate names of object files
|
||||
OBJS := $(SRCS:.c=.o)
|
||||
|
||||
# name of executable
|
||||
EXEC := minesweeper
|
||||
|
||||
# default recipe
|
||||
all: $(EXEC)
|
||||
|
||||
# recipe for building the final executable
|
||||
$(EXEC): $(OBJS) $(HDRS) Makefile
|
||||
$(CC) -o $@ $(OBJS) $(CFLAGS)
|
||||
|
||||
# recipe for building object files
|
||||
#$(OBJS): $(@:.o=.c) $(HDRS) Makefile
|
||||
# $(CC) -o $@ $(@:.o=.c) -c $(CFLAGS)
|
||||
|
||||
# recipe to clean the workspace
|
||||
clean:
|
||||
rm -f $(EXEC) $(OBJS)
|
||||
|
||||
.PHONY: all clean
|
|
@ -0,0 +1,62 @@
|
|||
#include "audio.h"
|
||||
|
||||
Mix_Chunk * sfx_click = NULL;
|
||||
Mix_Chunk * sfx_click2 = NULL;
|
||||
Mix_Chunk * sfx_explosion = NULL;
|
||||
Mix_Chunk * sfx_win = NULL;
|
||||
Mix_Chunk * sfx_lose = NULL;
|
||||
|
||||
void init_audio()
|
||||
{
|
||||
const char* driver_name = SDL_GetCurrentAudioDriver();
|
||||
|
||||
if (driver_name) {
|
||||
printf("Audio subsystem initialized: driver = %s.\n", driver_name);
|
||||
} else {
|
||||
printf("Audio subsystem not initialized.\n");
|
||||
}
|
||||
|
||||
if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0) {
|
||||
fprintf(stderr, "SDL_mixer could not initialize! SDL_mixer Error: %s\n", Mix_GetError());
|
||||
}
|
||||
|
||||
sfx_click = Mix_LoadWAV("resources/click.wav");
|
||||
sfx_click2 = Mix_LoadWAV("resources/click2.wav");
|
||||
sfx_explosion = Mix_LoadWAV("resources/explosion.wav");
|
||||
sfx_win = Mix_LoadWAV("resources/win.wav");
|
||||
sfx_lose = Mix_LoadWAV("resources/lose.wav");
|
||||
}
|
||||
|
||||
void play_audio(int sfx_index)
|
||||
{
|
||||
switch (sfx_index) {
|
||||
/* Since I stopped including the files with the macros I'll just indicate what it was with a comment */
|
||||
/* case UNCLICKED:*/
|
||||
case 0:
|
||||
Mix_PlayChannel(-1, sfx_click, 0);
|
||||
break;
|
||||
/* case SHOW_FLAG: */
|
||||
case 2:
|
||||
Mix_PlayChannel(-1, sfx_click2, 0);
|
||||
break;
|
||||
/* case EXPLOSION: */
|
||||
case 5:
|
||||
Mix_PlayChannel(-1, sfx_explosion, 0);
|
||||
break;
|
||||
/* case WON: */
|
||||
case 1:
|
||||
Mix_PlayChannel(-1, sfx_win, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void audio_destroy()
|
||||
{
|
||||
Mix_FreeChunk(sfx_click);
|
||||
Mix_FreeChunk(sfx_click2);
|
||||
Mix_FreeChunk(sfx_explosion);
|
||||
Mix_FreeChunk(sfx_win);
|
||||
Mix_FreeChunk(sfx_lose);
|
||||
Mix_Quit();
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
#include "defs.h"
|
||||
|
||||
void init_audio();
|
||||
void play_audio(int);
|
||||
void audio_destroy();
|
|
@ -0,0 +1,13 @@
|
|||
#include <stdio.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_timer.h>
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include <SDL2/SDL_mixer.h>
|
||||
|
||||
#ifndef _GLOBAL_CONSTANTS
|
||||
#define _GLOBAL_CONSTANTS
|
||||
|
||||
#define WINDOW_WIDTH 600
|
||||
#define WINDOW_HEIGHT 600
|
||||
|
||||
#endif
|
|
@ -0,0 +1,268 @@
|
|||
#include "main.h"
|
||||
#include "graphics.h"
|
||||
|
||||
SDL_Window * window = NULL;
|
||||
SDL_Renderer * rend = NULL;
|
||||
|
||||
/* lol */
|
||||
SDL_Texture * block_tex = NULL;
|
||||
SDL_Texture * flag_tex = NULL;
|
||||
SDL_Texture * explode_tex = NULL;
|
||||
SDL_Texture * click_tex = NULL;
|
||||
SDL_Texture * num1_tex = NULL;
|
||||
SDL_Texture * num2_tex = NULL;
|
||||
SDL_Texture * num3_tex = NULL;
|
||||
SDL_Texture * num4_tex = NULL;
|
||||
SDL_Texture * num5_tex = NULL;
|
||||
SDL_Texture * num6_tex = NULL;
|
||||
SDL_Texture * num7_tex = NULL;
|
||||
SDL_Texture * num8_tex = NULL;
|
||||
SDL_Texture * smiley_idle_tex = NULL;
|
||||
SDL_Texture * smiley_sweat_tex = NULL;
|
||||
SDL_Texture * smiley_anger_tex = NULL;
|
||||
SDL_Texture * smiley_happy_tex = NULL;
|
||||
|
||||
smile joe;
|
||||
blks grid;
|
||||
|
||||
SDL_Texture * create_tex(SDL_Window * window, SDL_Renderer * rend, const char * file)
|
||||
{
|
||||
/* Load image in memory */
|
||||
SDL_Surface * surface = IMG_Load(file);
|
||||
|
||||
if (!surface)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Couldn't create surface: %s\n", SDL_GetError());
|
||||
SDL_DestroyRenderer(rend);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Load image data in vram */
|
||||
SDL_Texture * tex = SDL_CreateTextureFromSurface(rend, surface);
|
||||
SDL_FreeSurface(surface);
|
||||
|
||||
if (!tex)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Couldn't create texture: %s\n", SDL_GetError());
|
||||
SDL_DestroyRenderer(rend);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
exit(1);
|
||||
|
||||
}
|
||||
return tex;
|
||||
}
|
||||
|
||||
|
||||
void init_video()
|
||||
{
|
||||
window = SDL_CreateWindow(
|
||||
"test",
|
||||
SDL_WINDOWPOS_CENTERED,
|
||||
SDL_WINDOWPOS_CENTERED,
|
||||
WINDOW_WIDTH,
|
||||
WINDOW_HEIGHT,
|
||||
SDL_WINDOW_MAXIMIZED
|
||||
);
|
||||
|
||||
if (!window)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Couldn't create window: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Uint32 render_flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC;
|
||||
|
||||
rend = SDL_CreateRenderer(window, -1, render_flags);
|
||||
|
||||
/* * *
|
||||
VERSION THAT ACCOUNTS FOR GAPS, IT DOES NOT WORK PROPERLY AT AROUND 16x16 AND UP
|
||||
* * *
|
||||
for (int i = 0; i < GRID_Y; i++) {
|
||||
for (int j = 0; j < GRID_X; j++) {
|
||||
grid[i][j].w = (WINDOW_WIDTH * 0.9) / (GRID_X + 1);
|
||||
grid[i][j].h = (WINDOW_HEIGHT * 0.9) / (GRID_Y + 1);
|
||||
grid[i][j].x = ((WINDOW_WIDTH - (WINDOW_WIDTH * 0.9)) / 2) + (j * (grid[i][j].w + (((WINDOW_WIDTH * 0.9) / (GRID_X + 1)) / (GRID_X - 1))));
|
||||
grid[i][j].y = ((WINDOW_HEIGHT - (WINDOW_HEIGHT * 0.9)) / 2) + (i * (grid[i][j].h + (((WINDOW_HEIGHT * 0.9) / (GRID_Y + 1)) / (GRID_Y - 1))));
|
||||
// drinking game: count the parentheses
|
||||
}
|
||||
}
|
||||
* * */
|
||||
|
||||
for (int i = 0; i < GRID_Y; i++) {
|
||||
for (int j = 0; j < GRID_X; j++) {
|
||||
grid.block[i][j].w = (WINDOW_WIDTH * 0.75) / GRID_Y;
|
||||
grid.block[i][j].h = (WINDOW_HEIGHT * 0.75) / GRID_Y;
|
||||
grid.block[i][j].x = ((WINDOW_WIDTH - (WINDOW_WIDTH * 0.75)) / 2) + (j * (grid.block[i][j].w));
|
||||
grid.block[i][j].y = ((((WINDOW_HEIGHT + (WINDOW_HEIGHT * 0.3)) - (WINDOW_HEIGHT * 0.9)) / 2) + (i * (grid.block[i][j].h)));
|
||||
}
|
||||
}
|
||||
|
||||
joe.rect.w = (WINDOW_HEIGHT * 0.2);
|
||||
joe.rect.h = (WINDOW_HEIGHT * 0.2);
|
||||
joe.rect.x = (WINDOW_WIDTH - joe.rect.w) / 2;
|
||||
joe.rect.y = 0;
|
||||
|
||||
joe.state = IDLE;
|
||||
|
||||
block_tex = create_tex(window, rend, "resources/ground.png");
|
||||
flag_tex = create_tex(window, rend, "resources/flag.png");
|
||||
explode_tex = create_tex(window, rend, "resources/bomb.png");
|
||||
click_tex = create_tex(window, rend, "resources/click.png");
|
||||
num1_tex = create_tex(window, rend, "resources/num1.png");
|
||||
num2_tex = create_tex(window, rend, "resources/num2.png");
|
||||
num3_tex = create_tex(window, rend, "resources/num3.png");
|
||||
num4_tex = create_tex(window, rend, "resources/num4.png");
|
||||
num5_tex = create_tex(window, rend, "resources/num5.png");
|
||||
num6_tex = create_tex(window, rend, "resources/num6.png");
|
||||
num7_tex = create_tex(window, rend, "resources/num7.png");
|
||||
num8_tex = create_tex(window, rend, "resources/num8.png");
|
||||
smiley_idle_tex = create_tex(window, rend, "resources/smiley_idle.png");
|
||||
smiley_sweat_tex = create_tex(window, rend, "resources/smiley_sweat.png");
|
||||
smiley_anger_tex = create_tex(window, rend, "resources/smiley_anger.png");
|
||||
smiley_happy_tex = create_tex(window, rend, "resources/smiley_happy.png");
|
||||
|
||||
}
|
||||
|
||||
void video_loop()
|
||||
{
|
||||
/* Clear the window */
|
||||
SDL_SetRenderDrawColor(rend, 211, 211, 211, 255);
|
||||
//SDL_SetRenderDrawColor(rend, 255, 255, 255, 255);
|
||||
SDL_RenderClear(rend);
|
||||
|
||||
//SDL_SetRenderDrawColor(rend, 100, 100, 100, 255);
|
||||
//SDL_RenderFillRects(rend, grid, GRID_X * GRID_Y);
|
||||
|
||||
/* Draw image */
|
||||
for (int i = 0; i < GRID_Y; i++) for (int j = 0; j < GRID_X; j++)
|
||||
{
|
||||
switch (grid.state[i][j]) {
|
||||
|
||||
case EXPLOSION:
|
||||
if (grid.show[i][j] == SHOW_TRUE)
|
||||
{
|
||||
SDL_RenderCopy(rend, explode_tex, NULL, &grid.block[i][j]);
|
||||
break;
|
||||
}
|
||||
|
||||
case NUM1:
|
||||
if (grid.show[i][j] == SHOW_TRUE)
|
||||
{
|
||||
SDL_RenderCopy(rend, num1_tex, NULL, &grid.block[i][j]);
|
||||
break;
|
||||
}
|
||||
|
||||
case NUM2:
|
||||
if (grid.show[i][j] == SHOW_TRUE)
|
||||
{
|
||||
SDL_RenderCopy(rend, num2_tex, NULL, &grid.block[i][j]);
|
||||
break;
|
||||
}
|
||||
|
||||
case NUM3:
|
||||
if (grid.show[i][j] == SHOW_TRUE)
|
||||
{
|
||||
SDL_RenderCopy(rend, num3_tex, NULL, &grid.block[i][j]);
|
||||
break;
|
||||
}
|
||||
|
||||
case NUM4:
|
||||
if (grid.show[i][j] == SHOW_TRUE)
|
||||
{
|
||||
SDL_RenderCopy(rend, num4_tex, NULL, &grid.block[i][j]);
|
||||
break;
|
||||
}
|
||||
|
||||
case NUM5:
|
||||
if (grid.show[i][j] == SHOW_TRUE)
|
||||
{
|
||||
SDL_RenderCopy(rend, num5_tex, NULL, &grid.block[i][j]);
|
||||
break;
|
||||
}
|
||||
|
||||
case NUM6:
|
||||
if (grid.show[i][j] == SHOW_TRUE)
|
||||
{
|
||||
SDL_RenderCopy(rend, num6_tex, NULL, &grid.block[i][j]);
|
||||
break;
|
||||
}
|
||||
|
||||
case NUM7:
|
||||
if (grid.show[i][j] == SHOW_TRUE)
|
||||
{
|
||||
SDL_RenderCopy(rend, num7_tex, NULL, &grid.block[i][j]);
|
||||
break;
|
||||
}
|
||||
|
||||
case NUM8:
|
||||
if (grid.show[i][j] == SHOW_TRUE)
|
||||
{
|
||||
SDL_RenderCopy(rend, num8_tex, NULL, &grid.block[i][j]);
|
||||
break;
|
||||
}
|
||||
|
||||
case EMPTY:
|
||||
if (grid.show[i][j] == SHOW_TRUE)
|
||||
{
|
||||
SDL_RenderCopy(rend, click_tex, NULL, &grid.block[i][j]);
|
||||
break;
|
||||
}
|
||||
|
||||
case UNCLICKED:
|
||||
if (grid.show[i][j] == SHOW_FLAG) {
|
||||
SDL_RenderCopy(rend, flag_tex, NULL, &grid.block[i][j]);
|
||||
break;
|
||||
}
|
||||
SDL_RenderCopy(rend, block_tex, NULL, &grid.block[i][j]);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
switch (joe.state) {
|
||||
case HAPPY:
|
||||
SDL_RenderCopy(rend, smiley_happy_tex, NULL, &joe.rect);
|
||||
break;
|
||||
case ANGER:
|
||||
SDL_RenderCopy(rend, smiley_anger_tex, NULL, &joe.rect);
|
||||
break;
|
||||
case SWEAT:
|
||||
SDL_RenderCopy(rend, smiley_sweat_tex, NULL, &joe.rect);
|
||||
break;
|
||||
case IDLE:
|
||||
SDL_RenderCopy(rend, smiley_idle_tex, NULL, &joe.rect);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_RenderPresent(rend);
|
||||
|
||||
}
|
||||
|
||||
void video_destroy()
|
||||
{
|
||||
SDL_DestroyTexture(block_tex);
|
||||
SDL_DestroyTexture(explode_tex);
|
||||
SDL_DestroyTexture(flag_tex);
|
||||
SDL_DestroyTexture(click_tex);
|
||||
SDL_DestroyTexture(num1_tex);
|
||||
SDL_DestroyTexture(num2_tex);
|
||||
SDL_DestroyTexture(num3_tex);
|
||||
SDL_DestroyTexture(num4_tex);
|
||||
SDL_DestroyTexture(num5_tex);
|
||||
SDL_DestroyTexture(num6_tex);
|
||||
SDL_DestroyTexture(num7_tex);
|
||||
SDL_DestroyTexture(num8_tex);
|
||||
SDL_DestroyTexture(smiley_idle_tex);
|
||||
SDL_DestroyTexture(smiley_sweat_tex);
|
||||
SDL_DestroyTexture(smiley_anger_tex);
|
||||
SDL_DestroyTexture(smiley_happy_tex);
|
||||
SDL_DestroyRenderer(rend);
|
||||
SDL_DestroyWindow(window);
|
||||
IMG_Quit();
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
#include "defs.h"
|
||||
|
||||
#define UNCLICKED 0
|
||||
#define EMPTY 1
|
||||
//#define UNUSED 2
|
||||
//#define UNUSED 3
|
||||
//#define UNUSED 4
|
||||
#define EXPLOSION 5
|
||||
#define NUM1 6
|
||||
#define NUM2 7
|
||||
#define NUM3 8
|
||||
#define NUM4 9
|
||||
#define NUM5 10
|
||||
#define NUM6 11
|
||||
#define NUM7 12
|
||||
#define NUM8 13
|
||||
|
||||
#define DONT_SHOW 0
|
||||
#define SHOW_TRUE 1
|
||||
#define SHOW_FLAG 2
|
||||
|
||||
#define HAPPY 1
|
||||
#define ANGER 2
|
||||
#define SWEAT 3
|
||||
#define IDLE 4
|
||||
|
||||
typedef struct blocks {
|
||||
SDL_Rect block[GRID_Y][GRID_X];
|
||||
int state[GRID_Y][GRID_X];
|
||||
int show[GRID_Y][GRID_X];
|
||||
int bomb[GRID_Y][GRID_X];
|
||||
} blks;
|
||||
|
||||
typedef struct smiley {
|
||||
SDL_Rect rect;
|
||||
int state;
|
||||
} smile;
|
||||
|
||||
extern SDL_Window * window;
|
||||
extern SDL_Renderer * rend;
|
||||
|
||||
extern blks grid;
|
||||
extern smile joe;
|
||||
|
||||
SDL_Texture * create_tex(SDL_Window *, SDL_Renderer *, const char *);
|
||||
void init_video();
|
||||
void video_loop();
|
||||
void video_destroy();
|
|
@ -0,0 +1,316 @@
|
|||
#include "main.h"
|
||||
#include "graphics.h"
|
||||
#include "audio.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
SDL_Rect player;
|
||||
int pause = 0;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
srand(time(NULL));
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO) < 0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Couldn't initialize SDL: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
init_video();
|
||||
init_audio();
|
||||
|
||||
player.w = 1;
|
||||
player.h = 1;
|
||||
|
||||
tick();
|
||||
|
||||
video_destroy();
|
||||
audio_destroy();
|
||||
|
||||
SDL_Quit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tick()
|
||||
{
|
||||
int close_requested = 0;
|
||||
|
||||
SDL_Event event;
|
||||
|
||||
int r_mouse = 0;
|
||||
int l_mouse = 0;
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
int player_bombs = NUM_OF_BOMBS;
|
||||
int player_unclicked = GRID_X * GRID_Y;
|
||||
|
||||
populate();
|
||||
|
||||
/* Check the board and give all blocks their proper values */
|
||||
for (int i = 0; i < GRID_Y; i++) for (int j = 0; j < GRID_X; j++)
|
||||
{
|
||||
int bombs_block = check_adjacent(i, j); /* Store value to not check twice */
|
||||
if (bombs_block > 0 && bombs_block < 9) {
|
||||
grid.state[i][j] = bombs_block + 5; /* In the DEFINE macros the numerical blocks start at 6 */
|
||||
} else if (bombs_block == 9) {
|
||||
grid.state[i][j] = EXPLOSION;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
while(!close_requested)
|
||||
{
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
{
|
||||
close_requested = 1;
|
||||
break;
|
||||
}
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
if (event.button.button == SDL_BUTTON_RIGHT) r_mouse = 1;
|
||||
if (event.button.button == SDL_BUTTON_LEFT) l_mouse = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pause)
|
||||
{
|
||||
if (player_bombs == 0) {
|
||||
for (int i = 0; i < GRID_Y; i++) for (int j = 0; j < GRID_X; j++)
|
||||
if (grid.show[i][j] == SHOW_FLAG && grid.state[i][j] == EXPLOSION) player_bombs++;
|
||||
if (player_bombs == NUM_OF_BOMBS)
|
||||
game_over(WON);
|
||||
}
|
||||
|
||||
/* This is probably inneficient, a last minute add because I forgot this is also a win condition of minesweeper */
|
||||
player_unclicked = GRID_X * GRID_Y;
|
||||
for (int i = 0; i < GRID_Y; i++) for (int j = 0; j < GRID_X; j++)
|
||||
{
|
||||
if (grid.show[i][j] == SHOW_TRUE) player_unclicked--;
|
||||
}
|
||||
|
||||
if (player_unclicked == NUM_OF_BOMBS) game_over(WON);
|
||||
|
||||
if (player_bombs == 1) {
|
||||
joe.state = SWEAT;
|
||||
}
|
||||
else if (joe.state == SWEAT) {
|
||||
joe.state = IDLE;
|
||||
}
|
||||
|
||||
int mouse_x, mouse_y;
|
||||
SDL_GetMouseState(&mouse_x, &mouse_y);
|
||||
|
||||
/* Update position */
|
||||
player.x = mouse_x;
|
||||
player.y = mouse_y;
|
||||
|
||||
for (int i = 0; i < GRID_Y; i++) for (int j = 0; j < GRID_X; j++)
|
||||
{
|
||||
if (check_collision(&player, &grid.block[i][j])) {
|
||||
if (r_mouse == 1) {
|
||||
r_mouse = 0; /* Reset the mouse the moment a single collision happened to ensure only a single block is clicked */
|
||||
if (!grid.show[i][j] && player_bombs != 0) {
|
||||
play_audio(SHOW_FLAG);
|
||||
grid.show[i][j] = SHOW_FLAG;
|
||||
player_bombs--;
|
||||
break;
|
||||
}
|
||||
if (grid.show[i][j] == SHOW_FLAG) {
|
||||
play_audio(SHOW_FLAG);
|
||||
grid.show[i][j] = DONT_SHOW;
|
||||
player_bombs++;
|
||||
break;
|
||||
}
|
||||
break; /* No need to keep checking since the mouse is reset */
|
||||
}
|
||||
if (l_mouse == 1) {
|
||||
l_mouse = 0;
|
||||
reveal(i, j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
video_loop();
|
||||
SDL_Delay(1000/60);
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void game_over(int winstate)
|
||||
{
|
||||
for (int i = 0; i < GRID_Y; i++) for (int j = 0; j < GRID_X; j++) {
|
||||
grid.show[i][j] = SHOW_TRUE;
|
||||
if (grid.state[i][j] == UNCLICKED) grid.state[i][j] = EMPTY;
|
||||
|
||||
}
|
||||
|
||||
if (winstate == LOST) {
|
||||
joe.state = ANGER;
|
||||
/* play_audio(LOST); the explosion sound is enough and avoids conflict with explosion sound */
|
||||
}
|
||||
if (winstate == WON) {
|
||||
joe.state = HAPPY;
|
||||
play_audio(WON);
|
||||
}
|
||||
|
||||
pause = 1;
|
||||
}
|
||||
|
||||
int check_adjacent(int i, int j) /* Got too used to dealing with i and j with the for loops I guess */
|
||||
{
|
||||
int bombs = 0; /* This value stores the amount of bombs around a block not the amount of bombs on the whole grid */
|
||||
|
||||
/* check middle */
|
||||
if (grid.bomb[i][j]) return 9; /* Since there can never be more than 8 bombs, this is a safe value to use */
|
||||
|
||||
/* check upper left */
|
||||
if (i - 1 >= 0 && j - 1 >= 0) {
|
||||
if (grid.bomb[i - 1][j - 1]) bombs++;
|
||||
}
|
||||
|
||||
/* check upper middle */
|
||||
if (i - 1 >= 0) {
|
||||
if (grid.bomb[i - 1][j]) bombs++;
|
||||
}
|
||||
|
||||
/* check upper right */
|
||||
if (i - 1 >= 0 && j + 1 < GRID_X ) {
|
||||
if (grid.bomb[i - 1][j + 1]) bombs++;
|
||||
}
|
||||
|
||||
/* check middle left */
|
||||
if (j - 1 >= 0) {
|
||||
if (grid.bomb[i][j - 1]) bombs++;
|
||||
}
|
||||
|
||||
/* check middle right */
|
||||
if (j + 1 < GRID_X ) {
|
||||
if (grid.bomb[i][j + 1]) bombs++;
|
||||
}
|
||||
|
||||
/* check lower left */
|
||||
if (i + 1 < GRID_Y && j - 1 >= 0) {
|
||||
if (grid.bomb[i + 1][j - 1]) bombs++;
|
||||
}
|
||||
|
||||
/* check lower middle */
|
||||
if (i + 1 < GRID_Y) {
|
||||
if (grid.bomb[i + 1][j]) bombs++;
|
||||
}
|
||||
|
||||
/* check lower right */
|
||||
if (i + 1 < GRID_Y && j + 1 < GRID_X) {
|
||||
if (grid.bomb[i + 1][j + 1]) bombs++;
|
||||
}
|
||||
|
||||
return bombs;
|
||||
}
|
||||
|
||||
void reveal(int i, int j)
|
||||
{
|
||||
if (!grid.show[i][j]) {
|
||||
grid.show[i][j] = SHOW_TRUE;
|
||||
if (grid.state[i][j] == EXPLOSION) {
|
||||
play_audio(EXPLOSION);
|
||||
game_over(LOST);
|
||||
} else {
|
||||
play_audio(UNCLICKED);
|
||||
}
|
||||
if (grid.state[i][j] == UNCLICKED) {
|
||||
grid.state[i][j] = EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
if (grid.state[i][j] == EMPTY) {
|
||||
/* check upper middle */
|
||||
if (i - 1 >= 0) {
|
||||
if (grid.state[i - 1][j] == UNCLICKED)
|
||||
{
|
||||
grid.state[i - 1][j] = EMPTY;
|
||||
grid.show[i - 1][j] = SHOW_TRUE;
|
||||
reveal(i - 1, j);
|
||||
} else {
|
||||
grid.show[i - 1][j] = SHOW_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* check middle left */
|
||||
if (j - 1 >= 0) {
|
||||
if (grid.state[i][j - 1] == UNCLICKED)
|
||||
{
|
||||
grid.state[i][j - 1] = EMPTY;
|
||||
grid.show[i][j - 1] = SHOW_TRUE;
|
||||
reveal(i, j - 1);
|
||||
} else {
|
||||
grid.show[i][j - 1] = SHOW_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* check middle right */
|
||||
if (j + 1 < GRID_X ) {
|
||||
if (grid.state[i][j + 1] == UNCLICKED)
|
||||
{
|
||||
grid.state[i][j + 1] = EMPTY;
|
||||
grid.show[i][j + 1] = SHOW_TRUE;
|
||||
reveal(i, j + 1);
|
||||
} else {
|
||||
grid.show[i][j + 1] = SHOW_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* check lower middle */
|
||||
if (i + 1 < GRID_Y) {
|
||||
if (grid.state[i + 1][j] == UNCLICKED)
|
||||
{
|
||||
grid.state[i + 1][j] = EMPTY;
|
||||
grid.show[i + 1][j] = SHOW_TRUE;
|
||||
reveal(i + 1, j);
|
||||
} else {
|
||||
grid.show[i + 1][j] = SHOW_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* Populate grid with bombs */
|
||||
void populate()
|
||||
{
|
||||
for (int i = 0; i < NUM_OF_BOMBS; i++) {
|
||||
int rand_x = rand() % GRID_X;
|
||||
int rand_y = rand() % GRID_Y;
|
||||
|
||||
if (!grid.bomb[rand_y][rand_x]) {
|
||||
grid.bomb[rand_y][rand_x] = 1;
|
||||
} else {
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int check_collision(SDL_Rect * obj1, SDL_Rect * obj2)
|
||||
{
|
||||
if (obj1->x < obj2->x + obj2->w && obj1->x + obj1->w > obj2->x) {
|
||||
if ( obj1->y < obj2->y + obj2->h && obj1->y + obj1->h > obj2->y) {
|
||||
/* collision happened */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#include "defs.h"
|
||||
|
||||
#define LOST 0
|
||||
#define WON 1
|
||||
|
||||
#define GRID_X 8
|
||||
#define GRID_Y 8
|
||||
|
||||
#define NUM_OF_BOMBS 5
|
||||
|
||||
int check_collision(SDL_Rect *, SDL_Rect *);
|
||||
void tick();
|
||||
void game_over(int);
|
||||
void populate();
|
||||
int check_adjacent(int, int);
|
||||
void reveal(int, int);
|
After Width: | Height: | Size: 191 B |
After Width: | Height: | Size: 98 B |
After Width: | Height: | Size: 133 B |
After Width: | Height: | Size: 117 B |
After Width: | Height: | Size: 122 B |
After Width: | Height: | Size: 146 B |
After Width: | Height: | Size: 143 B |
After Width: | Height: | Size: 135 B |
After Width: | Height: | Size: 134 B |
After Width: | Height: | Size: 142 B |
After Width: | Height: | Size: 137 B |
After Width: | Height: | Size: 136 B |
After Width: | Height: | Size: 269 B |
After Width: | Height: | Size: 241 B |
After Width: | Height: | Size: 212 B |
After Width: | Height: | Size: 223 B |