linije

Клон игре Color lines
git clone https://git.sr.ht/~strahinja/linije
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

чување 82968c79e439473a6fe7e3327063b5c854267658
родитељ c679ba92fc7c97d72fc19a5c95f6117d9bd12b72
Аутор: Страхиња Радић <sr@strahinja.org>
Датум:   Thu,  6 Aug 2026 17:30:06 +0000

Properly calculate score (off-by-one); avoid saving score multiple times; use 4 bytes for score storing

Diffstat:
Mhiscore.c | 52++++++++++++++++++++++------------------------------
Mhiscore.h | 13+++++++------
Mlinije.c | 16++++++++++++----
измењених датотека: 3, додавања: 41(+), брисања: 40(-)

diff --git a/hiscore.c b/hiscore.c @@ -16,7 +16,7 @@ int hs_add(struct HiScoreEntry** table, const char* name, const int name_len, - const unsigned int score) + const unsigned long int score) { struct HiScoreEntry* p = NULL; struct HiScoreEntry* q = NULL; @@ -45,8 +45,8 @@ hs_add(struct HiScoreEntry** table, const char* name, const int name_len, } int -hs_assign_ps(const char* name, const int name_len, const unsigned int score, - struct HiScoreEntry* dest) +hs_assign_ps(const char* name, const int name_len, + const unsigned long int score, struct HiScoreEntry* dest) { char* new_name = NULL; @@ -97,9 +97,6 @@ hs_assign_ss(const struct HiScoreEntry* source, struct HiScoreEntry* dest) } if (!memccpy(dest->name, source->name, 0, source->name_len)) dest->name[source->name_len] = 0; - /*SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, - "hs_assign_ss: dest->name = {%s} [%d]", - dest->name, dest->name_len);*/ hs_assign_ss_skip_name: dest->name_len = source->name_len; @@ -192,7 +189,7 @@ hs_get_hofdir_error: * ,-----------------------------------------------------------. * | name (HI_SCORE_NAME_MAX unsigned chars) | * |-----------------------------------------------------------| - * | score 2-byte unsigned int BE | + * | score 4-byte unsigned long int BE | * `-----------------------------------------------------------' */ int @@ -202,8 +199,8 @@ hs_load(struct HiScoreEntry** table, const char* hofdir) char* filename = NULL; char name[HI_SCORE_NAME_MAX + 1]; int filename_size = PATH_MAX + 1; - int name_len, i; - unsigned int score; + int name_len, i, ib; + unsigned long int score; uint8_t byte; if (!hofdir) @@ -240,18 +237,16 @@ hs_load(struct HiScoreEntry** table, const char* hofdir) } } name_len = strlen(name); - if (fread(&byte, 1, 1, infile) < 1) - { - fclose(infile); - goto hs_load_error; - } - score = byte << 8; - if (fread(&byte, 1, 1, infile) < 1) + score = 0; + for (ib = 0; ib < 4; ib++) { - fclose(infile); - goto hs_load_error; + if (fread(&byte, 1, 1, infile) < 1) + { + fclose(infile); + goto hs_load_error; + } + score |= SETBYTENOF4(byte, ib); } - score |= byte; hs_add(table, name, name_len, score); i++; } @@ -275,7 +270,7 @@ hs_write(struct HiScoreEntry* table, const char* hofdir) struct HiScoreEntry* p = NULL; char* filename = NULL; int filename_size = PATH_MAX + 1; - int i; + int i, ib; uint8_t byte; if (!hofdir) @@ -303,17 +298,14 @@ hs_write(struct HiScoreEntry* table, const char* hofdir) } } errno = 0; - byte = HIBYTE(p->score); - if (fwrite(&byte, 1, 1, outfile) < 1) + for (ib = 0; ib < 4; ib++) { - fclose(outfile); - goto hs_write_error; - } - byte = LOBYTE(p->score); - if (fwrite(&byte, 1, 1, outfile) < 1) - { - fclose(outfile); - goto hs_write_error; + byte = GETBYTENOF4(p->score, ib); + if (fwrite(&byte, 1, 1, outfile) < 1) + { + fclose(outfile); + goto hs_write_error; + } } } if (fclose(outfile) == EOF) diff --git a/hiscore.h b/hiscore.h @@ -10,21 +10,22 @@ #define PATH_MAX _POSIX_PATH_MAX #endif -#define HIBYTE(i) ((uint8_t)(((i) & 0xFF00) >> 8)) -#define LOBYTE(i) ((uint8_t)(((i) & 0xFF))) +#define GETBYTENOF4(x, n) \ + ((uint8_t)(((x) & (0x000000FF << (8 * (3 - (n))))) >> (8 * (3 - (n))))) +#define SETBYTENOF4(x, n) ((x) << (8 * (3 - (n)))) struct HiScoreEntry { char* name; int name_len; - unsigned int score; + unsigned long int score; }; int hs_add(struct HiScoreEntry** table, const char* name, const int name_len, - const unsigned int score); + const unsigned long int score); int hs_assign(const struct HiScoreEntry* source, struct HiScoreEntry* dest); int hs_assign_ss(const struct HiScoreEntry* source, struct HiScoreEntry* dest); -int hs_assign_ps(const char* name, const int name_len, const unsigned int score, - struct HiScoreEntry* dest); +int hs_assign_ps(const char* name, const int name_len, + const unsigned long int score, struct HiScoreEntry* dest); char* hs_get_hofdir(void); int hs_init(struct HiScoreEntry** table); int hs_load(struct HiScoreEntry** table, const char* hofdir); diff --git a/linije.c b/linije.c @@ -215,6 +215,7 @@ struct State { SDL_Texture* background; struct Cell* grid; float cell_scale_factor; + int check_score; SDL_Point dialog_dims; SDL_Point dialog_text_origin; int dialog_shown; @@ -244,7 +245,7 @@ struct State { int running; int screen_width; /* Logical */ int screen_height; - unsigned int score; + unsigned long int score; SDL_FPoint selection_start, selection_end; SDL_Texture* sprites; SDL_Texture* ter12_texture; @@ -480,7 +481,7 @@ check_five_loop: if (len > MIN_POP_LEN) { mark_five(state, &start, &end); - state->score += len * POP_STRING_CELL_VALUE; + state->score += (len - 1) * POP_STRING_CELL_VALUE; found_string = 1; } else @@ -704,8 +705,12 @@ game_over(struct State* state) { assert(state != NULL); state->mode = STATE_GAME_OVER; - if (state->score > state->hall_of_fame[HI_SCORE_MAX - 1].score) + if (state->check_score + && state->score > state->hall_of_fame[HI_SCORE_MAX - 1].score) + { + state->check_score = 0; input_name(state); + } else { SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, @@ -715,6 +720,7 @@ game_over(struct State* state) { reset(state); fill_triplet(state); + state->check_score = 1; state->input_instant_reset = 0; } else @@ -1209,6 +1215,7 @@ init_state(struct State* state) state->background = NULL; state->grid = NULL; state->cell_scale_factor = 2.0f; + state->check_score = 1; assign_point_xyII(-1, -1, &state->dialog_dims); assign_point_xyII(0, 0, &state->dialog_text_origin); state->dialog_shown = 0; @@ -1287,6 +1294,7 @@ input_name_callback(struct State* state) { reset(state); fill_triplet(state); + state->check_score = 1; state->input_instant_reset = 0; } else @@ -1510,7 +1518,7 @@ prepare_hof_dialog(struct State* state, const int show) HOF_DIALOG_MAX_LINE_LEN - 4 - e->name_len - num_size(e->score) - 1); snprintf(hof_text[HOF_SCORES_START_IDX + i], - HOF_DIALOG_MAX_LINE_LEN, "%2d. %s%s%u", i + 1, e->name, + HOF_DIALOG_MAX_LINE_LEN, "%2d. %s%s%lu", i + 1, e->name, dots, e->score); }