From c8e55ed6e9146e8fd22cfc4efef36c7424e150eb Mon Sep 17 00:00:00 2001 From: Tiehuis Date: Sun, 22 Feb 2015 11:29:15 +1300 Subject: [PATCH] Added highscore functionality --- README.md | 2 +- src/engine.c | 4 +++ src/highscore.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++ src/highscore.h | 8 ++++++ src/options.c | 2 ++ 5 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 src/highscore.c create mode 100644 src/highscore.h diff --git a/README.md b/README.md index a30244c..c04b6e3 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ create a .c file which implements all the functions in gfx.h and add a Makefile -c Enables color support (ncurses version only) -C Disables color support (ncurses version only) -Fonts used in SDL version can be found [here](openfontlibrary.org). +Fonts used in SDL version can be found [here](www.openfontlibrary.org). ## License This code is licensed under the [MIT License](https://github.com/Tiehuis/2048-cli/blob/master/LICENSE). diff --git a/src/engine.c b/src/engine.c index ae2192d..cb10a00 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1,6 +1,7 @@ #include #include #include "engine.h" +#include "highscore.h" /* Utilize block counter to improve some of the functions so they can run * quicker */ @@ -249,6 +250,8 @@ struct gamestate* gamestate_init(struct gameoptions *opt) g->blocks_in_play = 0; g->opts = opt; + highscore_load(g); + /* Initial 3 random blocks */ gamestate_new_block(g); gamestate_new_block(g); @@ -279,6 +282,7 @@ int gamestate_tick(struct gfx_state *s, struct gamestate *g, int d, void (*callb /* Free all data associated with the gamestate */ void gamestate_clear(struct gamestate *g) { + highscore_save(g); gameoptions_destroy(g->opts); free(g->grid_data_ptr); /* Free grid data */ free(g->grid); /* Free pointers to data slots */ diff --git a/src/highscore.c b/src/highscore.c new file mode 100644 index 0000000..3ac9350 --- /dev/null +++ b/src/highscore.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include "engine.h" + +const char *hs_dir_name = "2048"; +const char *hs_file_name = "highscore"; + +static const char* highscore_retrieve_file(void) +{ + static char buffer[4096]; + + if (getenv("XDG_DATA_HOME") != NULL) { + snprintf(buffer, sizeof(buffer), "%s/%s/%s", + getenv("XDG_DATA_HOME"), hs_dir_name, hs_file_name); + } + else if (getenv("HOME")) { + snprintf(buffer, sizeof(buffer), "%s/.local/share/%s/%s", + getenv("HOME"), hs_dir_name, hs_file_name); + } + else { + return hs_file_name; + } + + /* Create file only if it doesn't exist */ + if (access(buffer, F_OK) != -1) + return buffer; + + char *sep = strrchr(buffer, '/'); + while (sep != NULL) { + *sep = '\0'; + if (strlen(buffer) != 0) + mkdir(buffer, 0777); + char *tmpsep = sep; + sep = strrchr(buffer, '/'); + *tmpsep = '/'; + } + + return buffer; +} + +void highscore_reset(void) +{ + const char *hsfile = highscore_retrieve_file(); + + FILE *fd = fopen(hsfile, "w+"); + fprintf(fd, "%d", 0); + fclose(fd); +} + +void highscore_load(struct gamestate *g) +{ + const char *hsfile = highscore_retrieve_file(); + + FILE *fd = fopen(hsfile, "r"); + if (fd == NULL) + fd = fopen(hsfile, "w+"); + + fscanf(fd, "%ld", &g->score_high); + fclose(fd); +} + +void highscore_save(struct gamestate *g) +{ + if (g->score < g->score_high || g->opts->grid_width != 4 || g->opts->grid_height != 4) + return; + + const char *hsfile = highscore_retrieve_file(); + + FILE *fd = fopen(hsfile, "w"); + fprintf(fd, "%ld", g->score); + fclose(fd); +} diff --git a/src/highscore.h b/src/highscore.h new file mode 100644 index 0000000..fe2c542 --- /dev/null +++ b/src/highscore.h @@ -0,0 +1,8 @@ +#ifndef HIGHSCORE_H +#define HIGHSCORE_H + +void highscore_reset(void); +void highscore_load(struct gamestate *g); +void highscore_save(struct gamestate *g); + +#endif diff --git a/src/options.c b/src/options.c index a734e01..2fa45a6 100644 --- a/src/options.c +++ b/src/options.c @@ -1,5 +1,6 @@ #include #include +#include "highscore.h" #include "options.h" void print_usage(void) @@ -77,6 +78,7 @@ struct gameoptions* parse_options(struct gameoptions *opt, int argc, char **argv opt->spawn_rate = strtol(optarg, NULL, 10); break; case 'r': + highscore_reset(); exit(0); case 'h': print_usage();