diff --git a/game.c b/game.c index 14f93fa..2f40e64 100644 --- a/game.c +++ b/game.c @@ -303,8 +303,18 @@ void run_frame_left_playing(Game *g) { } void run_frame_left_from_deck(Game *g) { - if (run_frame_from_deck(g, &g->left_scored)) - g->state = GAME_STATE_PLAYER_CHOOSING_FROM_HAND; + 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; + } + } +} + +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)); + g->state = GAME_STATE_INITIALIZING; } void run_frame(Game *g) { @@ -351,6 +361,9 @@ void run_frame(Game *g) { case GAME_STATE_LEFT_FROM_DECK: run_frame_left_from_deck(g); break; + case GAME_STATE_CALCULATING_SCORES: + run_frame_calculating_scores(g); + break; } } diff --git a/game.h b/game.h index 907aa70..c07b4b0 100644 --- a/game.h +++ b/game.h @@ -8,6 +8,7 @@ typedef struct Game Game; #include "card.h" #include "field_multiplier.h" #include "teyaku.h" +#include "points.h" typedef enum GameState { GAME_STATE_INITIALIZING, @@ -21,6 +22,7 @@ typedef enum GameState { GAME_STATE_RIGHT_FROM_DECK, GAME_STATE_LEFT_PLAYING, GAME_STATE_LEFT_FROM_DECK, + GAME_STATE_CALCULATING_SCORES, } GameState; struct Game { diff --git a/points.c b/points.c new file mode 100644 index 0000000..7483b04 --- /dev/null +++ b/points.c @@ -0,0 +1,23 @@ +#include "points.h" +int hand_points(Hand *hand) { + int points = 0; + for (int i = 0; i < hand->count; i++) { + Card *c = hand->cards[i]; + switch (c->type) { + case CHAFF: + points += 1; + break; + case RIBBON: + points += 5; + break; + case ANIMAL: + points += 10; + break; + case BRIGHT: + points += 20; + break; + } + } + + return points - 88; +} diff --git a/points.h b/points.h new file mode 100644 index 0000000..cd77d8e --- /dev/null +++ b/points.h @@ -0,0 +1,8 @@ +#ifndef _HF_POINTS_ +#define _HF_POINTS_ + +#include "card.h" + +int hand_points(Hand *hand); + +#endif diff --git a/special_cases.c b/special_cases.c new file mode 100644 index 0000000..6ca47e9 --- /dev/null +++ b/special_cases.c @@ -0,0 +1,48 @@ +#include "game.h" +#include "card.h" +#include "points.h" +#include "special_cases.h" + +int hand_count_chaff(Hand *hand) { + int chaff = 0; + for (int i = 0; i < hand->count; i++) { + Card *c = hand->cards[i]; + if (c->type == CHAFF || c->month == NOVEMBER) chaff++; + } + return chaff; +} + +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); + + if (player_points == 0 && + right_points == 0 && + left_points == 0) { + return (SpecialCase) { SPECIAL_CASE_ALL_EIGHTS, SPECIAL_CASE_TARGET_DEALER, 10 }; + } + + if (player_points >= 80) + return (SpecialCase) { SPECIAL_CASE_DOUBLE_EIGHTS, SPECIAL_CASE_TARGET_PLAYER, player_points - 70 }; + if (right_points >= 80) + return (SpecialCase) { SPECIAL_CASE_DOUBLE_EIGHTS, SPECIAL_CASE_TARGET_RIGHT, right_points - 70 }; + if (left_points >= 80) + + return (SpecialCase) { SPECIAL_CASE_DOUBLE_EIGHTS, SPECIAL_CASE_TARGET_LEFT, left_points - 70 }; + + 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); + 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); + if (left_chaff >= 16) + return (SpecialCase) { SPECIAL_CASE_SIXTEEN_CHAFF, SPECIAL_CASE_TARGET_LEFT, (2 * left_chaff) - 20 }; + + return (SpecialCase) { SPECIAL_CASE_NONE, SPECIAL_CASE_TARGET_NONE, 0 }; +} + diff --git a/special_cases.h b/special_cases.h new file mode 100644 index 0000000..ed89dfe --- /dev/null +++ b/special_cases.h @@ -0,0 +1,30 @@ +#ifndef _HF_SPECIAL_CASES_ +#define _HF_SPECIAL_CASES_ + +typedef struct SpecialCase SpecialCase; +typedef enum SpecialCaseType { + SPECIAL_CASE_NONE, + SPECIAL_CASE_ALL_EIGHTS, + SPECIAL_CASE_DOUBLE_EIGHTS, + SPECIAL_CASE_SIXTEEN_CHAFF, +} SpecialCaseType; + +typedef enum SpecialCaseTarget { + SPECIAL_CASE_TARGET_NONE, + SPECIAL_CASE_TARGET_DEALER, + SPECIAL_CASE_TARGET_PLAYER, + SPECIAL_CASE_TARGET_RIGHT, + SPECIAL_CASE_TARGET_LEFT, +} SpecialCaseTarget; + +#include "game.h" + +struct SpecialCase { + SpecialCaseType type; + SpecialCaseTarget target; + int score; +}; + +SpecialCase calculate_special_case(Game *g); + +#endif