From 47ee3987fd91446cb44b8d44edfb4a081c4656a5 Mon Sep 17 00:00:00 2001 From: theturtlemafia Date: Sun, 27 Jul 2025 06:40:11 -0400 Subject: [PATCH 1/3] refactor jokers to use struct and function pointer --- include/joker.h | 10 +++++++++- source/game.c | 2 +- source/joker.c | 39 +++++++++--------------------------- source/joker_effects.c | 45 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 32 deletions(-) create mode 100644 source/joker_effects.c diff --git a/include/joker.h b/include/joker.h index 017fa65..9e387a0 100644 --- a/include/joker.h +++ b/include/joker.h @@ -25,7 +25,6 @@ #define RARE_JOKER 2 #define LEGENDARY_JOKER 3 -#define MAX_JOKERS 2 // The current maximum jokers added #define MAX_JOKER_OBJECTS 32 // The maximum number of joker objects that can be created at once #define DEFAULT_JOKER_ID 0 @@ -55,6 +54,15 @@ typedef struct // These jokers are triggered after the played hand has finished bool retrigger; // Retrigger played hand (e.g. "Dusk" joker, even though on the wiki it says "On Scored" it makes more sense to have it here) } JokerEffect; +typedef JokerEffect (*JokerEffectFunc)(Joker *joker, Card *scored_card); +typedef struct { + u8 rarity; + u8 base_value; + JokerEffectFunc effect; +} JokerInfo; +extern const JokerInfo joker_registry[]; +extern const size_t joker_registry_size; + void joker_init(); Joker *joker_new(u8 id); diff --git a/source/game.c b/source/game.c index fbcf9eb..9089327 100644 --- a/source/game.c +++ b/source/game.c @@ -1825,7 +1825,7 @@ static void game_shop_create_items(JokerObject *shop_jokers[], bool first_time) joker_object_destroy(&shop_jokers[i]); // Destroy the joker object if it exists } - u8 joker_id = random() % MAX_JOKERS; + u8 joker_id = random() % joker_registry_size; shop_jokers[i] = joker_object_new(joker_new(joker_id)); shop_jokers[i]->sprite_object->x = int2fx(120 + i * 32); diff --git a/source/joker.c b/source/joker.c index bad9168..2233405 100644 --- a/source/joker.c +++ b/source/joker.c @@ -12,13 +12,6 @@ #define JOKER_SCORE_TEXT_Y 48 -const static u8 joker_data_lut[MAX_JOKERS][2] = // Rarity, Value -{ - // TODO: Change to struct - {COMMON_JOKER, 2}, // Default Joker - {COMMON_JOKER, 5}, // Greedy Joker -}; - const static u8 edition_price_lut[MAX_EDITIONS] = { 0, // BASE_EDITION @@ -45,12 +38,15 @@ void joker_init() Joker *joker_new(u8 id) { - Joker *joker = malloc(sizeof(Joker)); + if (id >= joker_registry_size) return NULL; - joker->id = id; // TODO: Make this random later + Joker *joker = malloc(sizeof(Joker)); + const JokerInfo *jinfo = &joker_registry[id]; + + joker->id = id; joker->modifier = BASE_EDITION; // TODO: Make this random later - joker->value = joker_data_lut[id][1] + edition_price_lut[joker->modifier]; // Base value + edition price - joker->rarity = joker_data_lut[id][0]; + joker->value = jinfo->base_value + edition_price_lut[joker->modifier]; // Base value + edition price + joker->rarity = jinfo->rarity; joker->processed = false; return joker; @@ -65,25 +61,8 @@ void joker_destroy(Joker **joker) JokerEffect joker_get_score_effect(Joker *joker, Card *scored_card) { - JokerEffect effect = {0}; - - switch (joker->id) - { - case DEFAULT_JOKER_ID: // Default Joker - if (scored_card != NULL) break; // Joker is independent, no effect - effect.mult = 4; - break; - case GREEDY_JOKER_ID: // Greedy Joker - if (scored_card != NULL && scored_card->suit == DIAMONDS) // If the scored card is a diamond - { - effect.mult = 3; - } - break; - default: - break; - } - - return effect; + if (joker->id >= joker_registry_size) return (JokerEffect){0}; + return joker_registry[joker->id].effect(joker, scored_card); } // JokerObject methods diff --git a/source/joker_effects.c b/source/joker_effects.c new file mode 100644 index 0000000..367c654 --- /dev/null +++ b/source/joker_effects.c @@ -0,0 +1,45 @@ +#include "joker.h" + +static JokerEffect default_joker_effect(Joker *joker, Card *scored_card) { + JokerEffect effect = {0}; + if (scored_card == NULL) effect.mult = 4; + return effect; +} + +static JokerEffect greedy_joker_effect(Joker *joker, Card *scored_card) { + JokerEffect effect = {0}; + if (scored_card != NULL && scored_card->suit == DIAMONDS) + effect.mult = 3; + return effect; +} + +static JokerEffect lusty_joker_effect(Joker *joker, Card *scored_card) { + JokerEffect effect = {0}; + if (scored_card != NULL && scored_card->suit == HEARTS) + effect.mult = 3; + return effect; +} + +static JokerEffect wrathful_joker_effect(Joker *joker, Card *scored_card) { + JokerEffect effect = {0}; + if (scored_card != NULL && scored_card->suit == SPADES) + effect.mult = 3; + return effect; +} + +static JokerEffect gluttonous_joker_effect(Joker *joker, Card *scored_card) { + JokerEffect effect = {0}; + if (scored_card != NULL && scored_card->suit == CLUBS) + effect.mult = 3; + return effect; +} + +const JokerInfo joker_registry[] = { + { COMMON_JOKER, 2, default_joker_effect }, // DEFAULT_JOKER_ID = 0 + { COMMON_JOKER, 5, greedy_joker_effect }, // GREEDY_JOKER_ID = 1 + { COMMON_JOKER, 5, lusty_joker_effect }, // etc... + { COMMON_JOKER, 5, wrathful_joker_effect }, + { COMMON_JOKER, 5, gluttonous_joker_effect }, +}; + +const size_t joker_registry_size = sizeof(joker_registry) / sizeof(joker_registry[0]); From 5c58b092d7b8cc7dc1b2790970830ea2532de5be Mon Sep 17 00:00:00 2001 From: MeirGavish Date: Sun, 27 Jul 2025 19:01:26 +0300 Subject: [PATCH 2/3] Extracted sinful jokers effects to single function sinful_joker_effect() --- source/joker_effects.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/source/joker_effects.c b/source/joker_effects.c index 367c654..08b0728 100644 --- a/source/joker_effects.c +++ b/source/joker_effects.c @@ -1,37 +1,33 @@ #include "joker.h" + static JokerEffect default_joker_effect(Joker *joker, Card *scored_card) { JokerEffect effect = {0}; if (scored_card == NULL) effect.mult = 4; return effect; } -static JokerEffect greedy_joker_effect(Joker *joker, Card *scored_card) { +static JokerEffect sinful_joker_effect(Card *scored_card, u8 sinful_suit) { JokerEffect effect = {0}; - if (scored_card != NULL && scored_card->suit == DIAMONDS) + if (scored_card != NULL && scored_card->suit == sinful_suit) effect.mult = 3; return effect; } +static JokerEffect greedy_joker_effect(Joker *joker, Card *scored_card) { + return sinful_joker_effect(scored_card, DIAMONDS); +} + static JokerEffect lusty_joker_effect(Joker *joker, Card *scored_card) { - JokerEffect effect = {0}; - if (scored_card != NULL && scored_card->suit == HEARTS) - effect.mult = 3; - return effect; + return sinful_joker_effect(scored_card, HEARTS); } static JokerEffect wrathful_joker_effect(Joker *joker, Card *scored_card) { - JokerEffect effect = {0}; - if (scored_card != NULL && scored_card->suit == SPADES) - effect.mult = 3; - return effect; + return sinful_joker_effect(scored_card, SPADES); } static JokerEffect gluttonous_joker_effect(Joker *joker, Card *scored_card) { - JokerEffect effect = {0}; - if (scored_card != NULL && scored_card->suit == CLUBS) - effect.mult = 3; - return effect; + return sinful_joker_effect(scored_card, CLUBS); } const JokerInfo joker_registry[] = { From ed1204db74f8bbef431a627294d5c0864a664253 Mon Sep 17 00:00:00 2001 From: theturtlemafia Date: Mon, 28 Jul 2025 14:24:33 -0400 Subject: [PATCH 3/3] remove usage of extern for joker_registry. Add array size macro to util.h --- include/joker.h | 4 ++-- include/util.h | 2 ++ source/game.c | 2 +- source/joker.c | 10 ++++++---- source/joker_effects.c | 14 +++++++++++++- 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/include/joker.h b/include/joker.h index 9e387a0..a735066 100644 --- a/include/joker.h +++ b/include/joker.h @@ -60,8 +60,8 @@ typedef struct { u8 base_value; JokerEffectFunc effect; } JokerInfo; -extern const JokerInfo joker_registry[]; -extern const size_t joker_registry_size; +const JokerInfo* get_joker_registry_entry(int joker_id); +size_t get_joker_registry_size(void); void joker_init(); diff --git a/include/util.h b/include/util.h index 39b872b..54edbc1 100644 --- a/include/util.h +++ b/include/util.h @@ -35,4 +35,6 @@ static inline int get_digits_even(int n) #define UNDEFINED -1 +#define NUM_ELEM_IN_ARR(arr) (sizeof(arr) / sizeof((arr)[0])) + #endif // UTIL_H \ No newline at end of file diff --git a/source/game.c b/source/game.c index 9089327..204c9c3 100644 --- a/source/game.c +++ b/source/game.c @@ -1825,7 +1825,7 @@ static void game_shop_create_items(JokerObject *shop_jokers[], bool first_time) joker_object_destroy(&shop_jokers[i]); // Destroy the joker object if it exists } - u8 joker_id = random() % joker_registry_size; + u8 joker_id = random() % get_joker_registry_size(); shop_jokers[i] = joker_object_new(joker_new(joker_id)); shop_jokers[i]->sprite_object->x = int2fx(120 + i * 32); diff --git a/source/joker.c b/source/joker.c index 2233405..233769b 100644 --- a/source/joker.c +++ b/source/joker.c @@ -38,10 +38,10 @@ void joker_init() Joker *joker_new(u8 id) { - if (id >= joker_registry_size) return NULL; + if (id >= get_joker_registry_size()) return NULL; Joker *joker = malloc(sizeof(Joker)); - const JokerInfo *jinfo = &joker_registry[id]; + const JokerInfo *jinfo = get_joker_registry_entry(id); joker->id = id; joker->modifier = BASE_EDITION; // TODO: Make this random later @@ -61,8 +61,10 @@ void joker_destroy(Joker **joker) JokerEffect joker_get_score_effect(Joker *joker, Card *scored_card) { - if (joker->id >= joker_registry_size) return (JokerEffect){0}; - return joker_registry[joker->id].effect(joker, scored_card); + const JokerInfo *jinfo = get_joker_registry_entry(joker->id); + if (!jinfo) return (JokerEffect){0}; + + return jinfo->effect(joker, scored_card); } // JokerObject methods diff --git a/source/joker_effects.c b/source/joker_effects.c index 08b0728..438af93 100644 --- a/source/joker_effects.c +++ b/source/joker_effects.c @@ -1,4 +1,5 @@ #include "joker.h" +#include "util.h" static JokerEffect default_joker_effect(Joker *joker, Card *scored_card) { @@ -38,4 +39,15 @@ const JokerInfo joker_registry[] = { { COMMON_JOKER, 5, gluttonous_joker_effect }, }; -const size_t joker_registry_size = sizeof(joker_registry) / sizeof(joker_registry[0]); +static const size_t joker_registry_size = NUM_ELEM_IN_ARR(joker_registry); + +const JokerInfo* get_joker_registry_entry(int joker_id) { + if (joker_id < 0 || (size_t)joker_id >= joker_registry_size) { + return NULL; + } + return &joker_registry[joker_id]; +} + +size_t get_joker_registry_size(void) { + return joker_registry_size; +}