A bit of dekiyaku work

This commit is contained in:
Bill Rossi 2025-02-16 20:50:13 -05:00
parent dd9c9fc2d3
commit 296fa141a3
6 changed files with 70 additions and 9 deletions

View File

@ -3,10 +3,10 @@
#include "dekiyaku.h"
void calculate_dekiyaku(const Hand h, Dekiyaku *d) {
void calculate_dekiyaku(Hand *h, Dekiyaku *d) {
int brights = 0, ribbons = 0, ribbons_except_november = 0, blue_ribbons = 0, poetry_ribbons = 0, boar = 0, deer = 0, butterflies = 0;
for (int i = 0; i < h.count; i++) {
Card *card = h.cards[i];
for (int i = 0; i < h->count; i++) {
Card *card = h->cards[i];
switch (card->type) {
case BRIGHT: brights++; break;
case RIBBON:
@ -113,3 +113,11 @@ void dekiyaku_to_string(Dekiyaku *d, char *str) {
strcat(str, meld_str);
}
}
int dekiyaku_score(Dekiyaku *d) {
int score = 0;
for (int i = 0; i < d->count; i++) {
score += d->meld[i].value;
}
return score;
}

View File

@ -3,6 +3,12 @@
#include "card.h"
typedef enum DekiyakuAction {
DEKIYAKU_ACTION_NONE,
DEKIYAKU_ACTION_SAGE,
DEKIYAKU_ACTION_SHOUBU,
} DekiyakuAction;
typedef enum DekiyakuMeldType {
NONE,
FIVE_BRIGHTS,
@ -23,8 +29,9 @@ typedef struct Dekiyaku {
int count;
} Dekiyaku;
void calculate_dekiyaku(const Hand h, Dekiyaku *d);
void calculate_dekiyaku(Hand *h, Dekiyaku *d);
char *meld_name(DekiyakuMeldType d);
void dekiyaku_to_string(Dekiyaku *d, char *str);
int dekiyaku_score(Dekiyaku *d);
#endif

40
game.c
View File

@ -22,10 +22,14 @@ void initialize_game(Game *g) {
g->player_teyaku.calculated = false;
g->left_teyaku.calculated = false;
g->right_teyaku.calculated = false;
g->player_points = 0;
g->right_points = 0;
g->left_points = 0;
g->player_points_string[0] = '\0';
g->right_points_string[0] = '\0';
g->left_points_string[0] = '\0';
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;
for (int i = 0; i < 48; i++) {
CardType t = CHAFF;
RibbonType rt = RIBBON_NONE;
@ -211,6 +215,11 @@ 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);
if (g->player_hand.count < 4) {
deal(&g->deck, &g->player_hand, 4, true);
} else if (g->left_hand.count < 4) {
@ -288,8 +297,23 @@ 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))
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;
}
}
}
void run_frame_player_has_dekiyaku(Game *g) {
if (g->player_dekiyaku_action == DEKIYAKU_ACTION_SAGE) {
g->state = GAME_STATE_RIGHT_PLAYING;
} else if (g->player_dekiyaku_action == DEKIYAKU_ACTION_SHOUBU) {
g->state = GAME_STATE_CALCULATING_DEKIYAKU_SCORE;
}
}
void run_frame_right_playing(Game *g) {
@ -298,8 +322,10 @@ void run_frame_right_playing(Game *g) {
}
void run_frame_right_from_deck(Game *g) {
if (run_frame_from_deck(g, &g->right_scored))
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) {
@ -416,6 +442,10 @@ void draw_frame(Game *g) {
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);
switch (g->state) {
case GAME_STATE_PLAYER_CHOOSING_FROM_HAND:
DrawText("Choose a card to play", 60, 485, 20, BLACK);

7
game.h
View File

@ -8,6 +8,7 @@ typedef struct Game Game;
#include "card.h"
#include "field_multiplier.h"
#include "teyaku.h"
#include "dekiyaku.h"
#include "points.h"
typedef enum GameState {
@ -18,11 +19,13 @@ typedef enum GameState {
GAME_STATE_PLAYER_CHOOSING_FROM_HAND,
GAME_STATE_PLAYER_CHOOSING_TARGET,
GAME_STATE_PLAYER_FROM_DECK,
GAME_STATE_PLAYER_HAS_DEKIYAKU,
GAME_STATE_RIGHT_PLAYING,
GAME_STATE_RIGHT_FROM_DECK,
GAME_STATE_LEFT_PLAYING,
GAME_STATE_LEFT_FROM_DECK,
GAME_STATE_CALCULATING_SCORES,
GAME_STATE_CALCULATING_DEKIYAKU_SCORE,
} GameState;
struct Game {
@ -35,8 +38,12 @@ struct Game {
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;
};

View File

@ -1,4 +1,7 @@
#include <stdio.h>
#include "points.h"
int hand_points(Hand *hand) {
int points = 0;
for (int i = 0; i < hand->count; i++) {
@ -21,3 +24,7 @@ int hand_points(Hand *hand) {
return points - 88;
}
void kan_points_string(Game *g, int points, char *string) {
sprintf(string, "%d kan %d", points / g->kan_value, points % g->kan_value);
}

View File

@ -2,7 +2,9 @@
#define _HF_POINTS_
#include "card.h"
#include "game.h"
int hand_points(Hand *hand);
void kan_points_string(Game *g, int points, char *string);
#endif