From a85cc93f674d9c6ee3d9bf4092a7a09769da683b Mon Sep 17 00:00:00 2001 From: Bill Rossi Date: Tue, 18 Feb 2025 06:26:38 -0500 Subject: [PATCH] Refactor players into their own objects --- game.c | 185 ++++++++++++++++++++++++------------------------ game.h | 11 +-- player.h | 27 +++++++ special_cases.c | 12 ++-- 4 files changed, 130 insertions(+), 105 deletions(-) create mode 100644 player.h diff --git a/game.c b/game.c index 6cceeaa..5966b34 100644 --- a/game.c +++ b/game.c @@ -19,16 +19,12 @@ void initialize_game(Game *g) { g->should_close = false; g->state = GAME_STATE_INITIALIZING; g->field_multiplier = NULL; - g->player_teyaku.calculated = false; - g->left_teyaku.calculated = false; - g->right_teyaku.calculated = false; - g->player_points_string[0] = '\0'; - g->right_points_string[0] = '\0'; - g->left_points_string[0] = '\0'; + g->player.teyaku.calculated = false; + g->left.teyaku.calculated = false; + g->right.teyaku.calculated = false; g->kan_value = 12; - g->player_points = 10 * g->kan_value; - g->right_points = 10 * g->kan_value; - g->left_points = 10 * g->kan_value; + g->current_play_from_hand = NULL; + g->current_play_target = NULL; for (int i = 0; i < 48; i++) { CardType t = CHAFF; @@ -76,27 +72,34 @@ void initialize_game(Game *g) { shuffle_hand(&g->deck); - g->player_hand.count = 0; - g->player_hand.position = (Vector2) { 300, 600 }; - g->player_hand.display_type = HAND_DISPLAY_ROW; - g->right_hand.count = 0; - g->right_hand.position = (Vector2) { 750, 125 }; - g->right_hand.display_type = HAND_DISPLAY_ROW; - g->left_hand.count = 0; - g->left_hand.position = (Vector2) { 50, 125 }; - g->left_hand.display_type = HAND_DISPLAY_ROW; + g->player.points = 10 * g->kan_value; + g->right.points = 10 * g->kan_value; + g->left.points = 10 * g->kan_value; + g->player.points_string[0] = '\0'; + g->right.points_string[0] = '\0'; + g->left.points_string[0] = '\0'; + + g->player.hand.count = 0; + g->player.hand.position = (Vector2) { 300, 600 }; + g->player.hand.display_type = HAND_DISPLAY_ROW; + g->right.hand.count = 0; + g->right.hand.position = (Vector2) { 750, 125 }; + g->right.hand.display_type = HAND_DISPLAY_ROW; + g->left.hand.count = 0; + g->left.hand.position = (Vector2) { 50, 125 }; + g->left.hand.display_type = HAND_DISPLAY_ROW; g->field.count = 0; g->field.position = (Vector2) { 400, 300 }; g->field.display_type = HAND_DISPLAY_FIELD; - g->player_scored.count = 0; - g->player_scored.position = (Vector2) { 300, 750 }; - g->player_scored.display_type = HAND_DISPLAY_SCORED; - g->right_scored.count = 0; - g->right_scored.position = (Vector2) { 750, 25 }; - g->right_scored.display_type = HAND_DISPLAY_SCORED; - g->left_scored.count = 0; - g->left_scored.position = (Vector2) { 50, 25 }; - g->left_scored.display_type = HAND_DISPLAY_SCORED; + g->player.scored.count = 0; + g->player.scored.position = (Vector2) { 300, 750 }; + g->player.scored.display_type = HAND_DISPLAY_SCORED; + g->right.scored.count = 0; + g->right.scored.position = (Vector2) { 750, 25 }; + g->right.scored.display_type = HAND_DISPLAY_SCORED; + g->left.scored.count = 0; + g->left.scored.position = (Vector2) { 50, 25 }; + g->left.scored.display_type = HAND_DISPLAY_SCORED; strcpy(teyaku_calculation, ""); @@ -112,12 +115,12 @@ void handle_input(Game *g) { case GAME_STATE_PLAYER_CHOOSING_FROM_HAND: if (IsMouseButtonPressed(0)) { mouse_pos = GetMousePosition(); - for (int i = 0; i < g->player_hand.count; i++) { - if (point_within_card(g->player_hand.cards[i], mouse_pos)) { + for (int i = 0; i < g->player.hand.count; i++) { + if (point_within_card(g->player.hand.cards[i], mouse_pos)) { for (int j = 0; j < 48; j++) { g->cards[j].selected = false; } - g->player_hand.cards[i]->selected = true; + g->player.hand.cards[i]->selected = true; break; } } @@ -126,23 +129,23 @@ void handle_input(Game *g) { case GAME_STATE_PLAYER_CHOOSING_TARGET: if (IsMouseButtonPressed(0)) { mouse_pos = GetMousePosition(); - for (int i = 0; i < g->player_hand.count; i++) { - if (point_within_card(g->player_hand.cards[i], mouse_pos)) { - if (g->player_hand.cards[i]->selected) { - g->player_hand.cards[i]->selected = false; + for (int i = 0; i < g->player.hand.count; i++) { + if (point_within_card(g->player.hand.cards[i], mouse_pos)) { + if (g->player.hand.cards[i]->selected) { + g->player.hand.cards[i]->selected = false; } else { - for (int j = 0; j < g->player_hand.count; j++) { - g->player_hand.cards[j]->selected = false; + for (int j = 0; j < g->player.hand.count; j++) { + g->player.hand.cards[j]->selected = false; } - g->player_hand.cards[i]->selected = true; + g->player.hand.cards[i]->selected = true; } } } Card *selected_card = NULL; - for (int i = 0; i < g->player_hand.count; i++) { - if (g->player_hand.cards[i]->selected) { - selected_card = g->player_hand.cards[i]; + for (int i = 0; i < g->player.hand.count; i++) { + if (g->player.hand.cards[i]->selected) { + selected_card = g->player.hand.cards[i]; break; } } @@ -216,24 +219,24 @@ void run_frame_ai_playing(Game *g, Hand *hand, Hand *scored) { void run_frame_dealing(Game *g) { // TODO maybe we only need these once per game - kan_points_string(g, g->player_points, g->player_points_string); - kan_points_string(g, g->right_points, g->right_points_string); - kan_points_string(g, g->left_points, g->left_points_string); + kan_points_string(g, g->player.points, g->player.points_string); + kan_points_string(g, g->right.points, g->right.points_string); + kan_points_string(g, g->left.points, g->left.points_string); - if (g->player_hand.count < 4) { - deal(&g->deck, &g->player_hand, 4, true); - } else if (g->left_hand.count < 4) { - deal(&g->deck, &g->left_hand, 4, false); - } else if (g->right_hand.count < 4) { - deal(&g->deck, &g->right_hand, 4, false); + if (g->player.hand.count < 4) { + deal(&g->deck, &g->player.hand, 4, true); + } else if (g->left.hand.count < 4) { + deal(&g->deck, &g->left.hand, 4, false); + } else if (g->right.hand.count < 4) { + deal(&g->deck, &g->right.hand, 4, false); } else if (g->field.count < 3) { deal(&g->deck, &g->field, 3, true); - } else if (g->player_hand.count < 7) { - deal(&g->deck, &g->player_hand, 3, true); - } else if (g->left_hand.count < 7) { - deal(&g->deck, &g->left_hand, 3, false); - } else if (g->right_hand.count < 7) { - deal(&g->deck, &g->right_hand, 3, false); + } else if (g->player.hand.count < 7) { + deal(&g->deck, &g->player.hand, 3, true); + } else if (g->left.hand.count < 7) { + deal(&g->deck, &g->left.hand, 3, false); + } else if (g->right.hand.count < 7) { + deal(&g->deck, &g->right.hand, 3, false); } else if (g->field.count < 6) { deal(&g->deck, &g->field, 3, true); } else { @@ -247,7 +250,7 @@ void run_frame_calculating_field_multiplier(Game *g) { } void run_frame_calculating_teyaku(Game *g) { - calculate_teyaku(g->player_hand, &g->player_teyaku); + calculate_teyaku(g->player.hand, &g->player.teyaku); for (int i = 0; i < 48; i++) { g->cards[i].selected = false; } @@ -255,8 +258,8 @@ void run_frame_calculating_teyaku(Game *g) { } void run_frame_player_choosing_from_hand(Game *g) { - for (int i = 0; i < g->player_hand.count; i++) { - if (g->player_hand.cards[i]->selected) { + for (int i = 0; i < g->player.hand.count; i++) { + if (g->player.hand.cards[i]->selected) { g->state = GAME_STATE_PLAYER_CHOOSING_TARGET; return; } @@ -265,8 +268,8 @@ void run_frame_player_choosing_from_hand(Game *g) { void run_frame_player_choosing_target(Game *g) { bool no_cards_selected = true; - for (int i = 0; i < g->player_hand.count; i++) { - if (g->player_hand.cards[i]->selected) { + for (int i = 0; i < g->player.hand.count; i++) { + if (g->player.hand.cards[i]->selected) { no_cards_selected = false; break; } @@ -280,15 +283,15 @@ void run_frame_player_choosing_target(Game *g) { if (g->current_play_from_hand) { if (g->current_play_target) { g->current_play_from_hand->selected = false; - remove_from_hand(&g->player_hand, g->current_play_from_hand); - add_to_hand(&g->player_scored, g->current_play_from_hand); + remove_from_hand(&g->player.hand, g->current_play_from_hand); + add_to_hand(&g->player.scored, g->current_play_from_hand); remove_from_hand(&g->field, g->current_play_target); - add_to_hand(&g->player_scored, g->current_play_target); + add_to_hand(&g->player.scored, g->current_play_target); g->current_play_from_hand = NULL; g->current_play_target = NULL; } else { g->current_play_from_hand->selected = false; - remove_from_hand(&g->player_hand, g->current_play_from_hand); + remove_from_hand(&g->player.hand, g->current_play_from_hand); add_to_hand(&g->field, g->current_play_from_hand); g->current_play_from_hand = NULL; } @@ -297,10 +300,10 @@ void run_frame_player_choosing_target(Game *g) { } void run_frame_player_from_deck(Game *g) { - if (run_frame_from_deck(g, &g->player_scored)) { - calculate_dekiyaku(&g->player_scored, &g->player_dekiyaku); - if (dekiyaku_score(&g->player_dekiyaku) != g->player_dekiyaku_score) { - g->player_dekiyaku_score = dekiyaku_score(&g->player_dekiyaku); + if (run_frame_from_deck(g, &g->player.scored)) { + calculate_dekiyaku(&g->player.scored, &g->player.dekiyaku); + if (dekiyaku_score(&g->player.dekiyaku) != g->player.dekiyaku_score) { + g->player.dekiyaku_score = dekiyaku_score(&g->player.dekiyaku); g->state = GAME_STATE_PLAYER_HAS_DEKIYAKU; } else { g->state = GAME_STATE_RIGHT_PLAYING; @@ -309,33 +312,33 @@ void run_frame_player_from_deck(Game *g) { } void run_frame_player_has_dekiyaku(Game *g) { - if (g->player_dekiyaku_action == DEKIYAKU_ACTION_SAGE) { + if (g->player.dekiyaku_action == DEKIYAKU_ACTION_SAGE) { g->state = GAME_STATE_RIGHT_PLAYING; - } else if (g->player_dekiyaku_action == DEKIYAKU_ACTION_SHOUBU) { + } else if (g->player.dekiyaku_action == DEKIYAKU_ACTION_SHOUBU) { g->state = GAME_STATE_CALCULATING_DEKIYAKU_SCORE; } } void run_frame_right_playing(Game *g) { - run_frame_ai_playing(g, &g->right_hand, &g->right_scored); + run_frame_ai_playing(g, &g->right.hand, &g->right.scored); g->state = GAME_STATE_RIGHT_FROM_DECK; } void run_frame_right_from_deck(Game *g) { - if (run_frame_from_deck(g, &g->right_scored)) { - calculate_dekiyaku(&g->right_scored, &g->right_dekiyaku); + if (run_frame_from_deck(g, &g->right.scored)) { + calculate_dekiyaku(&g->right.scored, &g->right.dekiyaku); g->state = GAME_STATE_LEFT_PLAYING; } } void run_frame_left_playing(Game *g) { - run_frame_ai_playing(g, &g->left_hand, &g->left_scored); + run_frame_ai_playing(g, &g->left.hand, &g->left.scored); g->state = GAME_STATE_LEFT_FROM_DECK; } void run_frame_left_from_deck(Game *g) { - if (run_frame_from_deck(g, &g->left_scored)) { - if (g->player_hand.count) { + if (run_frame_from_deck(g, &g->left.scored)) { + if (g->player.hand.count) { g->state = GAME_STATE_PLAYER_CHOOSING_FROM_HAND; } else { g->state = GAME_STATE_CALCULATING_SCORES; @@ -344,7 +347,7 @@ void run_frame_left_from_deck(Game *g) { } void run_frame_calculating_scores(Game *g) { - printf("Hand scores: %d %d %d\n", hand_points(&g->player_scored), hand_points(&g->right_scored), hand_points(&g->left_scored)); + printf("Hand scores: %d %d %d\n", hand_points(&g->player.scored), hand_points(&g->right.scored), hand_points(&g->left.scored)); SpecialCase special_case = calculate_special_case(g); switch(special_case.type) { @@ -356,23 +359,23 @@ void run_frame_calculating_scores(Game *g) { printf("Double eights or 16 chaff! Player %d gets %d kan\n", special_case.target, special_case.score); switch (special_case.target) { case SPECIAL_CASE_TARGET_PLAYER: - transfer_kan(g, &g->player_points, &g->right_points, special_case.score); - transfer_kan(g, &g->player_points, &g->left_points, special_case.score); + transfer_kan(g, &g->player.points, &g->right.points, special_case.score); + transfer_kan(g, &g->player.points, &g->left.points, special_case.score); break; case SPECIAL_CASE_TARGET_RIGHT: - transfer_kan(g, &g->right_points, &g->player_points, special_case.score); - transfer_kan(g, &g->right_points, &g->left_points, special_case.score); + transfer_kan(g, &g->right.points, &g->player.points, special_case.score); + transfer_kan(g, &g->right.points, &g->left.points, special_case.score); break; case SPECIAL_CASE_TARGET_LEFT: - transfer_kan(g, &g->left_points, &g->right_points, special_case.score); - transfer_kan(g, &g->left_points, &g->player_points, special_case.score); + transfer_kan(g, &g->left.points, &g->right.points, special_case.score); + transfer_kan(g, &g->left.points, &g->player.points, special_case.score); break; } break; default: - transfer_points(g, &g->player_points, &g->temp_points, hand_points(&g->player_scored)); - transfer_points(g, &g->right_points, &g->temp_points, hand_points(&g->right_scored)); - transfer_points(g, &g->left_points, &g->temp_points, hand_points(&g->left_scored)); + transfer_points(g, &g->player.points, &g->temp_points, hand_points(&g->player.scored)); + transfer_points(g, &g->right.points, &g->temp_points, hand_points(&g->right.scored)); + transfer_points(g, &g->left.points, &g->temp_points, hand_points(&g->left.scored)); break; } g->state = GAME_STATE_INITIALIZING; @@ -436,15 +439,15 @@ void draw_frame(Game *g) { } if (g->field_multiplier) DrawText(g->field_multiplier->name, 60, 385, 40, BLACK); - if (g->player_teyaku.calculated) { + if (g->player.teyaku.calculated) { char s[200]; - teyaku_to_string(&g->player_teyaku, s); + teyaku_to_string(&g->player.teyaku, s); DrawText(s, 5, 25, 30, BLACK); } - DrawText(g->player_points_string, 40, 700, 20, BLACK); - DrawText(g->right_points_string, 40, 750, 20, BLACK); - DrawText(g->left_points_string, 40, 800, 20, BLACK); + DrawText(g->player.points_string, 40, 700, 20, BLACK); + DrawText(g->right.points_string, 40, 750, 20, BLACK); + DrawText(g->left.points_string, 40, 800, 20, BLACK); switch (g->state) { case GAME_STATE_PLAYER_CHOOSING_FROM_HAND: diff --git a/game.h b/game.h index 14661f6..f3cf1f2 100644 --- a/game.h +++ b/game.h @@ -10,6 +10,7 @@ typedef struct Game Game; #include "teyaku.h" #include "dekiyaku.h" #include "points.h" +#include "player.h" typedef enum GameState { GAME_STATE_INITIALIZING, @@ -33,18 +34,12 @@ struct Game { bool should_close; Card cards[48]; Texture2D cards_texture; - Hand player_hand, left_hand, right_hand; Hand deck, field; - Hand player_scored, left_scored, right_scored; FieldMultiplier *field_multiplier; - Teyaku player_teyaku, left_teyaku, right_teyaku; - Dekiyaku player_dekiyaku, left_dekiyaku, right_dekiyaku; - DekiyakuAction player_dekiyaku_action; - int player_dekiyaku_score, left_dekiyaku_score, right_dekiyaku_score; Card *current_play_from_hand, *current_play_target; - int player_points, right_points, left_points, temp_points; - char player_points_string[20], left_points_string[20], right_points_string[20]; int kan_value; + Player player, right, left; + int temp_points; }; void initialize_game(Game *g); diff --git a/player.h b/player.h new file mode 100644 index 0000000..0d12fed --- /dev/null +++ b/player.h @@ -0,0 +1,27 @@ +#ifndef _HF_PLAYER_ +#define _HF_PLAYER_ + +typedef struct Player Player; +typedef enum PlayerSeat { + PLAYER, + RIGHT, + LEFT +} PlayerSeat; + +#include "card.h" + +struct Player { + PlayerSeat seat; + Hand hand; + Hand scored; + Teyaku teyaku; + Dekiyaku dekiyaku; + DekiyakuAction dekiyaku_action; + int dekiyaku_score; + int points; + char points_string[20]; + bool ai; + bool dealer; +}; + +#endif diff --git a/special_cases.c b/special_cases.c index 6ca47e9..819d0b2 100644 --- a/special_cases.c +++ b/special_cases.c @@ -13,9 +13,9 @@ int hand_count_chaff(Hand *hand) { } SpecialCase calculate_special_case(Game *g) { - int player_points = hand_points(&g->player_scored); - int right_points = hand_points(&g->right_scored); - int left_points = hand_points(&g->left_scored); + int player_points = hand_points(&g->player.scored); + int right_points = hand_points(&g->right.scored); + int left_points = hand_points(&g->left.scored); if (player_points == 0 && right_points == 0 && @@ -31,15 +31,15 @@ SpecialCase calculate_special_case(Game *g) { return (SpecialCase) { SPECIAL_CASE_DOUBLE_EIGHTS, SPECIAL_CASE_TARGET_LEFT, left_points - 70 }; - int player_chaff = hand_count_chaff(&g->player_scored); + int player_chaff = hand_count_chaff(&g->player.scored); if (player_chaff >= 16) return (SpecialCase) { SPECIAL_CASE_SIXTEEN_CHAFF, SPECIAL_CASE_TARGET_PLAYER, (2 * player_chaff) - 20 }; - int right_chaff = hand_count_chaff(&g->right_scored); + int right_chaff = hand_count_chaff(&g->right.scored); if (right_chaff >= 16) return (SpecialCase) { SPECIAL_CASE_SIXTEEN_CHAFF, SPECIAL_CASE_TARGET_RIGHT, (2 * right_chaff) - 20 }; - int left_chaff = hand_count_chaff(&g->left_scored); + int left_chaff = hand_count_chaff(&g->left.scored); if (left_chaff >= 16) return (SpecialCase) { SPECIAL_CASE_SIXTEEN_CHAFF, SPECIAL_CASE_TARGET_LEFT, (2 * left_chaff) - 20 };