Refactor/hand (#490)

* move all hand funcs to their new file. now to clean up

* WIP

* Cleanup + doc hand.h

* clang format

* Refactor loose variables in hand.c into a proper Hand struct

* Fix some more issues

* Apply *some* suggestions from code review

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* remove outdated comment

* fix rebase issue

* fix rng_info missing from g_game_vars init

---------

Co-authored-by: MathisMartin31 <mathis.martin31@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Geralt
2026-05-22 17:51:39 -07:00
committed by GitHub
co-authored by Copilot Autofix powered by AI MathisMartin31
parent d7414157a5
commit 2329c4c681
9 changed files with 1235 additions and 1043 deletions
-66
View File
@@ -8,7 +8,6 @@
#include <tonc.h>
#define MAX_HAND_SIZE 16
#define MAX_DECK_SIZE 52
#define MAX_JOKERS_HELD_SIZE 5 // This doesn't account for negatives right now.
#define MAX_SHOP_JOKERS 2 // TODO: Make this dynamic and allow for other items besides jokers
@@ -54,18 +53,6 @@ enum GameState
GAME_STATE_UNDEFINED
};
enum HandState
{
HAND_DRAW,
HAND_SELECT,
// This is actually a misnomer because it's used for the deck
// but it mechanically makes sense to be a state of the hand
HAND_SHUFFLING,
HAND_DISCARD,
HAND_PLAY,
HAND_PLAYING
};
enum PlayState
{
PLAY_STARTING,
@@ -79,53 +66,6 @@ enum PlayState
PLAY_ENDED
};
// Hand types
enum HandType
{
NONE,
HIGH_CARD,
PAIR,
TWO_PAIR,
THREE_OF_A_KIND,
STRAIGHT,
FLUSH,
FULL_HOUSE,
FOUR_OF_A_KIND,
STRAIGHT_FLUSH,
ROYAL_FLUSH,
FIVE_OF_A_KIND,
FLUSH_HOUSE,
FLUSH_FIVE
};
// clang-format off
// Store all contained hands to optimize "whole hand condition" Jokers
typedef struct ContainedHandTypes
{
union
{
struct
{
u16 HIGH_CARD : 1;
u16 PAIR : 1;
u16 TWO_PAIR : 1;
u16 THREE_OF_A_KIND : 1;
u16 STRAIGHT : 1;
u16 FLUSH : 1;
u16 FULL_HOUSE : 1;
u16 FOUR_OF_A_KIND : 1;
u16 STRAIGHT_FLUSH : 1;
u16 ROYAL_FLUSH : 1;
u16 FIVE_OF_A_KIND : 1;
u16 FLUSH_HOUSE : 1;
u16 FLUSH_FIVE : 1;
u16 : 3;
};
u16 value;
};
} ContainedHandTypes;
// clang-format on
// Game functions
void game_init();
@@ -142,9 +82,6 @@ void game_reset();
void game_update();
void game_change_state(enum GameState new_game_state);
CardObject** get_hand_array(void);
int get_hand_top(void);
int hand_get_size(void);
CardObject** get_played_array(void);
int get_played_top(void);
int get_scored_card_index(void);
@@ -159,9 +96,6 @@ List* get_shop_jokers_list(void);
Bitset* get_avail_jokers_bitset(void);
void set_shop_joker_avail(int joker_id, bool avail);
ContainedHandTypes* get_contained_hands(void);
enum HandType* get_hand_type(void);
int get_deck_top(void);
int get_num_discards_remaining(void);
int get_num_hands_remaining(void);
+3
View File
@@ -27,6 +27,8 @@
#define MAX_HANDS 4
#define MAX_DISCARDS 4
#define DEFAULT_HAND_SIZE 8
/**
* @brief A central location for all game variables.
*
@@ -45,6 +47,7 @@ typedef struct
s32 round;
s32 ante;
s32 money;
s32 hand_size;
// Blind variables
+234
View File
@@ -0,0 +1,234 @@
/**
* @file hand.h
*
* @brief Functions relative to manipulating and analyzing the contents of the Hand,
* a.k.a. the Cards we hold and play.
*/
#ifndef HAND_H
#define HAND_H
#include "card.h"
#include <tonc.h>
#define MAX_HAND_SIZE 16
enum HandState
{
HAND_DRAW,
HAND_SELECT,
// This is actually a misnomer because it's used for the deck
// but it mechanically makes sense to be a state of the hand
HAND_SHUFFLING,
HAND_DISCARD,
HAND_PLAY,
HAND_PLAYING
};
enum HandType
{
NONE,
HIGH_CARD,
PAIR,
TWO_PAIR,
THREE_OF_A_KIND,
STRAIGHT,
FLUSH,
FULL_HOUSE,
FOUR_OF_A_KIND,
STRAIGHT_FLUSH,
ROYAL_FLUSH,
FIVE_OF_A_KIND,
FLUSH_HOUSE,
FLUSH_FIVE
};
// clang-format off
// Store all contained hands to optimize "whole hand condition" Jokers
typedef struct ContainedHandTypes
{
union
{
struct
{
u16 HIGH_CARD : 1;
u16 PAIR : 1;
u16 TWO_PAIR : 1;
u16 THREE_OF_A_KIND : 1;
u16 STRAIGHT : 1;
u16 FLUSH : 1;
u16 FULL_HOUSE : 1;
u16 FOUR_OF_A_KIND : 1;
u16 STRAIGHT_FLUSH : 1;
u16 ROYAL_FLUSH : 1;
u16 FIVE_OF_A_KIND : 1;
u16 FLUSH_HOUSE : 1;
u16 FLUSH_FIVE : 1;
u16 : 3;
};
u16 value;
};
} ContainedHandTypes;
// clang-format on
// Hand Structure Manipulation
/**
* @brief Set the hand state. Primarily used by the GAME_PLAYING game state.
*
* @sa HandState
*/
void set_hand_state(enum HandState);
/**
* @brief Get the hand state
*
* @return enum HandState
*
* @sa set_hand_state
*/
enum HandState get_hand_state(void);
/**
* @brief Determine the HandType and ContainedHandTypes of the currently selected Cards,
* then print the Hand's name, chips, and mult on screen.
*/
void compute_hand_value_info(void);
/**
* @brief Get the current hand type
*
* @return enum HandType
*
* @sa compute_hand_value_info
*/
enum HandType get_hand_type(void);
/**
* @brief Get the contained hands within the selected hand
*
* @return ContainedHandTypes*
*
* @sa compute_hand_value_info
*/
ContainedHandTypes* get_contained_hands(void);
/**
* @brief Get the hand array of Cards currently held in hand
*
* @return CardObject**
*/
CardObject** get_hand_array(void);
/**
* @brief Get the position in hand array of the last card obtained
*
* @return int
*
* @sa get_hand_array
*/
int get_hand_top(void);
/**
* @brief Set the position in hand array of the last card obtained
*
* @param new_hand_top
*
* @sa get_hand_top
*/
void set_hand_top(int new_hand_top);
/**
* @brief Get the current number of Cards in hand.
*
* @return `hand_top + 1`
*
* @sa get_hand_top
*/
int hand_nb_held_cards(void);
/**
* @brief Get the current number of selected Cards.
*
* @return `card_selections`
*/
int hand_get_nb_selected_cards(void);
/**
* @brief Set the current number of selected Cards.
*
* @param new_selections
*
* @sa hand_get_nb_selected_cards
*/
void hand_set_nb_selected_cards(int new_selections);
/**
* @brief Set the card at a given index in Hand as selected
*
* @param index Index of card to select in hand
*/
void hand_select_card(int index);
/**
* @brief Switch to the given sort method. Can sort playing cards in two ways: by rank and suit.
* The order of suits is as follows:
* ```
* SPADES > HEARTS > CLUBS > DIAMONDS
* ```
*
* @param to_sort_by_suit
*/
void hand_change_sort(bool to_sort_by_suit);
/**
* @brief Deselect all cards in hand.
*/
void hand_deselect_all_cards(void);
/**
* @brief Swaps the order of two cards in hand.
*
* @param idx_a index of the first card
* @param idx_b index of the second card
*/
void swap_cards_in_hand(int idx_a, int idx_b);
/**
* @brief Destroy the sprites of the Cards held in hand and recreate then in the same
* order as the Cards in the hand array. This allows Cards to render properly
* when help in hand during the round or a Tarot/Spectral booster pack.
*/
void reorder_card_sprites_layers(void);
/**
* @brief Sort the hand array according to the selected method to do that.
*
* @sa hand_change_sort
*/
void sort_cards(void);
// Hand Contents Analysis
/**
* Finds the largest flush (set of cards with the same suit) in the given array of played cards.
* Marks the cards belonging to the best flush in the out_selection array.
*
* @param played Array of pointers to CardObject representing played cards.
* @param top Index of the top of the played stack.
* @param min_len Minimum number of cards required for a flush.
* @param out_selection Output array of bools; set to true for cards in the best flush, false
* otherwise.
* @return The number of cards in the best flush found, or 0 if no flush meets min_len.
*/
int find_flush_in_played_cards(CardObject** played, int top, int min_len, bool* out_selection);
int find_straight_in_played_cards(
CardObject** played,
int top,
bool shortcut_active,
int min_len,
bool* out_selection
);
void select_paired_cards_in_hand(CardObject** played, int top, bool* selection);
#endif
-42
View File
@@ -1,42 +0,0 @@
#ifndef HAND_ANALYSIS_H
#define HAND_ANALYSIS_H
#include "card.h"
#include <tonc.h>
/**
* @brief Outputs the distribution of ranks and suits in the hand
* @param ranks_out output - updated such as ranks_out[rank] is the number of cards of rank in the
* hand. Must be of size NUM_RANKS.
* @param suits_out output - updated such as suits_out[suit] is the number of cards if suit in the
* hand Must be of size NUM_SUITS
*/
void get_hand_distribution(u8 ranks_out[NUM_RANKS], u8 suits_out[NUM_SUITS]);
/**
* @brief Outputs the distribution of ranks and suits in the played stack
* @param ranks_out output - updated such as ranks_out[rank] is the number of cards of rank in the
* played stack. Must be of size NUM_RANKS.
* @param suits_out output - updated such as suits_out[suit] is the number of cards if suit in the
* played stack. Must be of size NUM_SUITS
*/
void get_played_distribution(u8 ranks_out[NUM_RANKS], u8 suits_out[NUM_SUITS]);
u8 hand_contains_n_of_a_kind(u8* ranks);
bool hand_contains_two_pair(u8* ranks);
bool hand_contains_full_house(u8* ranks);
bool hand_contains_straight(u8* ranks);
bool hand_contains_flush(u8* suits);
int find_flush_in_played_cards(CardObject** played, int top, int min_len, bool* out_selection);
int find_straight_in_played_cards(
CardObject** played,
int top,
bool shortcut_active,
int min_len,
bool* out_selection
);
void select_paired_cards_in_hand(CardObject** played, int top, bool* selection);
#endif