Compare commits

..

10 Commits

Author SHA1 Message Date
_N3m0 4ed5fb7b94 readme screenshot 2024-03-25 09:44:11 +01:00
_N3m0 fbc4cdfd07 fix: record put new line in record_file 2024-03-18 16:43:10 +01:00
_N3m0 238ae68c8e update readme for config 2024-03-18 13:52:08 +01:00
_N3m0 d81864bee0 save record 2024-03-18 13:40:55 +01:00
_N3m0 19a8890509 introduce macro for file path 2024-03-18 09:21:37 +01:00
_N3m0 cf34d87fc1 timer start at first click 2024-03-18 08:32:42 +01:00
_N3m0 f6901505af save record in memory 2024-03-17 16:52:15 +01:00
_N3m0 247d252def timer logic 2024-03-15 21:34:27 +01:00
_N3m0 eacffc0c11 fix unclickable menu 2024-03-15 18:19:18 +01:00
_N3m0 b6c8f03f97 show timer 2024-03-15 13:53:08 +01:00
4 changed files with 114 additions and 39 deletions

1
.gitignore vendored
View File

@ -1,3 +1,2 @@
.wakatime-project .wakatime-project
mineur mineur
minesweeper-screenshot.png

View File

@ -1,5 +1,7 @@
# MINEUR # MINEUR
![screenshot](minesweeper-screenshot.png)
Minesweeper game. Minesweeper game.
Oh no, my os doesn't comme with minesweeper preinstalled, let's make it myself. Oh no, my os doesn't comme with minesweeper preinstalled, let's make it myself.
@ -24,7 +26,12 @@ Oh no, my os doesn't comme with minesweeper preinstalled, let's make it myself.
all of these action can be done with the menu bar all of these action can be done with the menu bar
# building # Configuration
You can change the path to the ressource directory, record file and screenshot file name
by changing the corresponding macro at the top of [main.c](main.c)
# Building
You need to install [raylib v5](https://github.com/raysan5/raylib/releases/tag/5.0), but any version should work. You need to install [raylib v5](https://github.com/raysan5/raylib/releases/tag/5.0), but any version should work.

137
main.c
View File

@ -1,11 +1,20 @@
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <time.h> #include <time.h>
#include "raylib.h" #include "raylib.h"
// don't forget the / at the end of dir
#ifdef RELEASE
#define RESSOURCES_DIR "/home/cptbb/opt/dev/built/data/mineur/"
#else
#define RESSOURCES_DIR "/home/cptbb/dev/mineur/ressources/"
#endif
#define RECORD_FILE "/home/cptbb/.local/share/mineur_record"
#define SCREEN_SHOT_NAME "minesweeper-screenshot.png"
#define ARRAT(arr, type, x, y) ((arr) + (y)*(type) + (x)) #define ARRAT(arr, type, x, y) ((arr) + (y)*(type) + (x))
#define min(a, b) ((a) < (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b))
@ -59,6 +68,10 @@ const Color text_color = BLACK;
const Color hover_color = RED; const Color hover_color = RED;
float timer = 0.0f; float timer = 0.0f;
char timer_text[10] = {0};
char timer_record[GAME_TYPE_NB][10] = {"9999", "9999", "9999"};
FILE *record_file_read;
FILE *record_file_write;
int need_to_fill = 1; int need_to_fill = 1;
#define INIT_TEXTURE(img, tex) \ #define INIT_TEXTURE(img, tex) \
@ -178,12 +191,11 @@ void fill_game(int click_x, int click_y)
int x = rand() % game_size.x; int x = rand() % game_size.x;
int y = rand() % game_size.y; int y = rand() % game_size.y;
if (click_x == x && click_y == y) if ((click_x == x && click_y == y) || game[y][x] == 'X') {
continue;
if (game[y][x] == 'X')
i--; i--;
else continue;
}
game[y][x] = 'X'; game[y][x] = 'X';
} }
@ -241,6 +253,7 @@ void reload_game(void)
need_to_fill = 1; need_to_fill = 1;
screen_resize_handle(); screen_resize_handle();
timer = 0.0f; timer = 0.0f;
memset(timer_text, 0, sizeof(timer_text));
} }
void switch_mode(GameType gt) void switch_mode(GameType gt)
@ -264,10 +277,42 @@ void switch_mode(GameType gt)
} }
} }
int nb_len(char *string)
{
int i = 0;
for (; string[i] >= 48 && string[i] <= 48+10; i++);
return i+1;
}
void load_record(void)
{
for (
int i=0;
i<GAME_TYPE_NB &&
fgets(timer_record[i], sizeof(timer_record[i]), record_file_read);
i++
);
}
void save_record(void)
{
record_file_write = fopen(RECORD_FILE, "w");
fprintf(record_file_write, "%.*s\n%.*s\n%.*s\n",
nb_len(timer_record[BEGINNER]) - 1, timer_record[BEGINNER],
nb_len(timer_record[INTERMEDIATE]) - 1, timer_record[INTERMEDIATE],
nb_len(timer_record[EXPERT]) - 1, timer_record[EXPERT]);
fclose(record_file_write);
}
int main(void) int main(void)
{ {
srand(time(NULL)); srand(time(NULL));
record_file_read = fopen(RECORD_FILE, "r");
load_record();
SetConfigFlags(FLAG_WINDOW_RESIZABLE); SetConfigFlags(FLAG_WINDOW_RESIZABLE);
#ifdef RELEASE #ifdef RELEASE
SetTraceLogLevel(LOG_ERROR); SetTraceLogLevel(LOG_ERROR);
@ -277,27 +322,27 @@ int main(void)
SetTargetFPS(60); SetTargetFPS(60);
menu = (Rectangle){0, 0, screen_width, screen_height - screen_width}; menu = (Rectangle){0, 0, screen_width, screen_height - screen_width};
tile_image_orig = LoadImage("ressources/tile.png"); tile_image_orig = LoadImage(RESSOURCES_DIR "tile.png");
tile_hover_image_orig = LoadImage("ressources/tile_hover.png"); tile_hover_image_orig = LoadImage(RESSOURCES_DIR "tile_hover.png");
mine_image_orig = LoadImage("ressources/mine.png"); mine_image_orig = LoadImage(RESSOURCES_DIR "mine.png");
mine_image_orig = LoadImage("ressources/mine.png"); mine_image_orig = LoadImage(RESSOURCES_DIR "mine.png");
t1_image_orig = LoadImage("ressources/1.png"); t1_image_orig = LoadImage(RESSOURCES_DIR "1.png");
t2_image_orig = LoadImage("ressources/2.png"); t2_image_orig = LoadImage(RESSOURCES_DIR "2.png");
t3_image_orig = LoadImage("ressources/3.png"); t3_image_orig = LoadImage(RESSOURCES_DIR "3.png");
t4_image_orig = LoadImage("ressources/4.png"); t4_image_orig = LoadImage(RESSOURCES_DIR "4.png");
t5_image_orig = LoadImage("ressources/5.png"); t5_image_orig = LoadImage(RESSOURCES_DIR "5.png");
t6_image_orig = LoadImage("ressources/6.png"); t6_image_orig = LoadImage(RESSOURCES_DIR "6.png");
t7_image_orig = LoadImage("ressources/7.png"); t7_image_orig = LoadImage(RESSOURCES_DIR "7.png");
t8_image_orig = LoadImage("ressources/8.png"); t8_image_orig = LoadImage(RESSOURCES_DIR "8.png");
camera_texture = LoadTexture("ressources/camera.png"); camera_texture = LoadTexture(RESSOURCES_DIR "camera.png");
lose_texture = LoadTexture("ressources/lose.png"); lose_texture = LoadTexture(RESSOURCES_DIR "lose.png");
win_texture = LoadTexture("ressources/win.png"); win_texture = LoadTexture(RESSOURCES_DIR "win.png");
record_texture = LoadTexture("ressources/record.png"); record_texture = LoadTexture(RESSOURCES_DIR "record.png");
playing_texture = LoadTexture("ressources/playing.png"); playing_texture = LoadTexture(RESSOURCES_DIR "playing.png");
fixed_tile_texture = LoadTexture("ressources/fixed_tile.png"); fixed_tile_texture = LoadTexture(RESSOURCES_DIR "fixed_tile.png");
double_tile_texture = LoadTexture("ressources/tile_2.png"); double_tile_texture = LoadTexture(RESSOURCES_DIR "tile_2.png");
triple_tile_texture = LoadTexture("ressources/tile_3.png"); triple_tile_texture = LoadTexture(RESSOURCES_DIR "tile_3.png");
setup_game(); setup_game();
screen_resize_handle(); screen_resize_handle();
@ -310,11 +355,17 @@ int main(void)
screen_resize_handle(); screen_resize_handle();
if (take_screenshot) { if (take_screenshot) {
TakeScreenshot("minesweeper-screenshot.png"); TakeScreenshot(SCREEN_SHOT_NAME);
take_screenshot = 0; take_screenshot = 0;
} }
if (game_state == PLAYING) {
if (need_to_fill)
timer = 0;
else
timer += GetFrameTime(); timer += GetFrameTime();
snprintf(timer_text, sizeof(timer_text), "%d", (int) timer);
}
ClearBackground((Color) { ClearBackground((Color) {
.r = 0x8E, .g = 0x8E, .b = 0x8E, .a = 255 .r = 0x8E, .g = 0x8E, .b = 0x8E, .a = 255
@ -410,11 +461,21 @@ int main(void)
timer_mid - timer_pad - double_tile_texture.width, 0, timer_mid - timer_pad - double_tile_texture.width, 0,
WHITE WHITE
); );
DrawText(
timer_text,
timer_mid - timer_pad - double_tile_texture.width + 13, 10,
35.0f, text_color
);
DrawTexture( DrawTexture(
double_tile_texture, double_tile_texture,
timer_mid + timer_pad, 0, timer_mid + timer_pad, 0,
WHITE WHITE
); );
DrawText(
timer_record[current_game_type],
timer_mid + timer_pad + 13, 10,
35.0f, text_color
);
for (int y=0; y<game_size.y; y++) { for (int y=0; y<game_size.y; y++) {
for (int x=0; x<game_size.x; x++) { for (int x=0; x<game_size.x; x++) {
@ -464,18 +525,18 @@ int main(void)
} }
} }
mouse_x = ((mouse_x - grid.x) / grid.width) * game_size.x; int mouse_map_x = ((mouse_x - grid.x) / grid.width) * game_size.x;
mouse_y = ((mouse_y - grid.y) / grid.height) * game_size.y; int mouse_map_y = ((mouse_y - grid.y) / grid.height) * game_size.y;
if (need_to_fill && mouse_pressed) { if (need_to_fill && mouse_pressed) {
fill_game(mouse_x, mouse_y); fill_game(mouse_map_x, mouse_map_y);
need_to_fill = 0; need_to_fill = 0;
} }
if (mouse_in_grid && game_state == PLAYING) { if (mouse_in_grid && game_state == PLAYING) {
discover[mouse_y][mouse_x] = 1; discover[mouse_map_y][mouse_map_x] = 1;
zero_click(mouse_x, mouse_y); zero_click(mouse_map_x, mouse_map_y);
int count_undiscovered_cell = 0; int count_undiscovered_cell = 0;
for (int x=0; x<game_size.x; x++) { for (int x=0; x<game_size.x; x++) {
@ -485,10 +546,18 @@ int main(void)
} }
} }
if (game_state != LOSE && count_undiscovered_cell <= nb_bomb) if (game_state != LOSE && count_undiscovered_cell <= nb_bomb) {
if (timer < atoi(timer_record[current_game_type])) {
game_state = RECORD;
memset(timer_record[current_game_type], 1, sizeof(timer_record[0]));
snprintf(timer_record[current_game_type], sizeof(timer_record[0]), "%d", (int) timer);
save_record();
} else {
game_state = WIN; game_state = WIN;
}
}
if (game[mouse_y][mouse_x] == 'X') { if (game[mouse_map_y][mouse_map_x] == 'X') {
memset(discover, 1, game_cap); memset(discover, 1, game_cap);
game_state = LOSE; game_state = LOSE;
} }

BIN
minesweeper-screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB