чување 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:
измењених датотека: 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);
}