Compare commits

...

4 Commits

Author SHA1 Message Date
37bb1b47d0 More idiomatic calculation 2025-02-02 05:04:19 -05:00
5e0109a9b6 Address warnings 2025-02-02 05:04:19 -05:00
4dd45c42e8 Dekiyaku 2025-02-02 05:04:19 -05:00
3c4f882d18 Don't calculate every single frame 2025-02-02 05:04:19 -05:00
8 changed files with 203 additions and 30 deletions

3
card.c
View File

@ -1,5 +1,8 @@
#include "card.h"
static Vector2 card_size = (Vector2) { CARD_WIDTH, CARD_HEIGHT };
static char *month_english_abbr[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
void draw_card(Card *c) {
DrawRectangleV(c->position, card_size, c->selected ? RED : BLACK);
DrawRectangle(c->position.x + CARD_BORDER, c->position.y + CARD_BORDER, card_size.x - (CARD_BORDER * 2), card_size.y - (CARD_BORDER * 2) , WHITE);

6
card.h
View File

@ -9,7 +9,6 @@ typedef struct Hand Hand;
#define CARD_WIDTH 63
#define CARD_HEIGHT 105
#define CARD_BORDER 5
static Vector2 card_size = (Vector2) { CARD_WIDTH, CARD_HEIGHT };
typedef enum CardType {
CHAFF,
@ -40,8 +39,6 @@ typedef enum Month {
DECEMBER
} Month;
static char *month_english_abbr[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
struct Card {
int index;
CardType type;
@ -52,10 +49,11 @@ struct Card {
};
struct Hand {
Card cards[7];
Card cards[48];
int count;
};
void draw_card(Card *c);
bool point_within_card(Card *c, Vector2 v);
#endif

115
dekiyaku.c Normal file
View File

@ -0,0 +1,115 @@
#include <string.h>
#include <stdio.h>
#include "dekiyaku.h"
void calculate_dekiyaku(const 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++) {
const Card card = h.cards[i];
switch (card.type) {
case BRIGHT: brights++; break;
case RIBBON:
ribbons++;
if (card.month != NOVEMBER) ribbons_except_november++;
switch (card.ribbon_type) {
case RIBBON_BLUE: blue_ribbons++; break;
case RIBBON_POETRY: poetry_ribbons++; break;
default: break;
}
break;
case ANIMAL:
switch (card.month) {
case JUNE: butterflies++; break;
case JULY: boar++; break;
case OCTOBER: deer++; break;
default: break;
}
break;
case CHAFF:
break;
}
}
d->count = 0;
if (brights == 5) {
d->meld[d->count].type = FIVE_BRIGHTS;
d->meld[d->count].value = 12;
d->count++;
}
if (brights == 4) {
d->meld[d->count].type = FOUR_BRIGHTS;
d->meld[d->count].value = 10;
d->count++;
}
if (ribbons_except_november >= 7) {
d->meld[d->count].type = SEVEN_RIBBONS;
d->meld[d->count].value = 3 + ribbons; // Include november ribbons in this count
d->count++;
}
if (poetry_ribbons == 3) {
d->meld[d->count].type = POETRY_RIBBONS;
d->meld[d->count].value = 7;
d->count++;
}
if (blue_ribbons == 3) {
d->meld[d->count].type = BLUE_RIBBONS;
d->meld[d->count].value = 7;
d->count++;
}
if (boar == 1 && deer == 1 && butterflies == 1) {
d->meld[d->count].type = BOAR_DEER_BUTTERFLIES;
d->meld[d->count].value = 7;
d->count++;
}
}
char *meld_name(DekiyakuMeldType d) {
switch (d) {
case FIVE_BRIGHTS:
return "5B";
case FOUR_BRIGHTS:
return "4B";
case SEVEN_RIBBONS:
return "7R";
case POETRY_RIBBONS:
return "PS";
case BLUE_RIBBONS:
return "BS";
case BOAR_DEER_BUTTERFLIES:
return "ISK";
default:
return "None";
}
}
int dekiyaku_value(Dekiyaku *d) {
int value = 0;
for (int i = 0; i < d->count; i++) {
value += d->meld[i].value;
}
return value;
}
void dekiyaku_to_string(Dekiyaku *d, char *str) {
char meld_str[200];
strcpy(str, "Dekiyaku: ");
for (int i = 0; i < d->count; i++) {
sprintf(meld_str, "%s (%d) + ", meld_name(d->meld[i].type), d->meld[i].value);
strcat(str, meld_str);
}
if (d->count == 0) strcat(str, "none (0)");
else {
str[strlen(str) - 2] = '=';
sprintf(meld_str, "%d", dekiyaku_value(d));
strcat(str, meld_str);
}
}

30
dekiyaku.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef _HF_DEKIYAKU_
#define _HF_DEKIYAKU_
#include "card.h"
typedef enum DekiyakuMeldType {
NONE,
FIVE_BRIGHTS,
FOUR_BRIGHTS,
SEVEN_RIBBONS,
POETRY_RIBBONS,
BLUE_RIBBONS,
BOAR_DEER_BUTTERFLIES,
} DekiyakuMeldType;
typedef struct DekiyakuMeld {
DekiyakuMeldType type;
int value;
} DekiyakuMeld;
typedef struct Dekiyaku {
DekiyakuMeld meld[5];
int count;
} Dekiyaku;
void calculate_dekiyaku(const Hand h, Dekiyaku *d);
char *meld_name(DekiyakuMeldType d);
void dekiyaku_to_string(Dekiyaku *d, char *str);
#endif

32
main.c
View File

@ -8,6 +8,7 @@
#include "card.h"
#include "move.h"
#include "teyaku.h"
#include "dekiyaku.h"
char *text = "こんにちわ、 世界!";
@ -68,17 +69,22 @@ int main(int argc, char** argv) {
cards[i] = (Card) { i, t, rt, month, (Vector2) { month * 65, (i % 4) * 110 }, false };
}
float delta;
Vector2 mouse_position;
// float delta;
Vector2 mouse_pos;
char teyaku_calculation[400];
strcpy(teyaku_calculation, "");
char dekiyaku_calculation[400];
strcpy(dekiyaku_calculation, "");
while (!WindowShouldClose()) {
delta = GetFrameTime();
// delta = GetFrameTime();
if (IsMouseButtonPressed(0)) {
Vector2 mouse_pos = GetMousePosition();
mouse_pos = GetMousePosition();
for (int i = 0; i < 48; i++) {
if (point_within_card(&cards[i], mouse_pos)) {
cards[i].selected = !cards[i].selected;
strcpy(teyaku_calculation, "");
break;
}
}
@ -92,16 +98,28 @@ int main(int argc, char** argv) {
draw_card(&cards[i]);
}
if (num_selected == 7) {
if (strlen(teyaku_calculation) == 0) {
Hand h;
h.count = 0;
for (int i = 0; i < 48; i++) {
if (cards[i].selected) memcpy(&h.cards[h.count++], &cards[i], sizeof(Card));
}
char *s = TextFormat("Set: %s(%d) / Chaff: %s(%d) / Total: %d", set_teyaku_english(h), set_teyaku_points(h), chaff_teyaku_english(h), chaff_teyaku_points(h), calculate_teyaku(h));
DrawText(s, 10, 500, 25, BLACK);
if (num_selected == 7) {
Teyaku t;
calculate_teyaku(h, &t);
teyaku_to_string(&t, teyaku_calculation);
} else {
strcpy(teyaku_calculation, "");
}
Dekiyaku d;
calculate_dekiyaku(h, &d);
dekiyaku_to_string(&d, dekiyaku_calculation);
}
DrawText(teyaku_calculation, 10, 450, 25, BLACK);
DrawText(dekiyaku_calculation, 10, 500, 25, BLACK);
EndDrawing();
}

2
move.c
View File

@ -19,5 +19,7 @@ Vector2 move_position(Move *m, float delta) {
((m->destination.x - m->origin.x) * percentage) + m->origin.x,
((m->destination.y - m->origin.y) * percentage) + m->origin.y
};
default:
return m->destination;
}
}

View File

@ -67,22 +67,29 @@ static char *set_teyaku_english_array[11] = { "None", "Triplet", "Standing Tripl
static int chaff_teyaku_points_array[6] = { 0, 2, 3, 3, 4, 4 };
static char *chaff_teyaku_english_array[6] = { "None", "Red", "One Ribbon", "One Animal", "One Bright", "Empty Hand" };
int set_teyaku_points(const Hand h) {
return set_teyaku_points_array[calculate_set_teyaku(h)];
int set_teyaku_points(SetTeyaku st) {
return set_teyaku_points_array[st];
}
int chaff_teyaku_points(const Hand h) {
return chaff_teyaku_points_array[calculate_chaff_teyaku(h)];
int chaff_teyaku_points(ChaffTeyaku ct) {
return chaff_teyaku_points_array[ct];
}
char *set_teyaku_english(const Hand h) {
return set_teyaku_english_array[calculate_set_teyaku(h)];
char *set_teyaku_english(SetTeyaku st) {
return set_teyaku_english_array[st];
}
char *chaff_teyaku_english(const Hand h) {
return chaff_teyaku_english_array[calculate_chaff_teyaku(h)];
char *chaff_teyaku_english(ChaffTeyaku ct) {
return chaff_teyaku_english_array[ct];
}
int calculate_teyaku(const Hand h) {
return chaff_teyaku_points(h) + set_teyaku_points(h);
void calculate_teyaku(const Hand h, Teyaku *t) {
t->chaff = calculate_chaff_teyaku(h);
t->set = calculate_set_teyaku(h);
}
void teyaku_to_string(Teyaku *t, char *str) {
int set_points = set_teyaku_points(t->set);
int chaff_points = chaff_teyaku_points(t->chaff);
sprintf(str, "Set: %s(%d) / Chaff: %s(%d) / Total: %d", set_teyaku_english(t->set), set_points, chaff_teyaku_english(t->chaff), chaff_points, set_points + chaff_points);
}

View File

@ -4,7 +4,7 @@
#include "card.h"
typedef enum SetTeyaku {
SET_TEYAKU_NONE = 0,
SET_TEYAKU_NONE,
TRIPLET,
STANDING_TRIPLET,
TWO_TRIPLETS,
@ -18,7 +18,7 @@ typedef enum SetTeyaku {
} SetTeyaku;
typedef enum ChaffTeyaku {
CHAFF_TEYAKU_NONE = 0,
CHAFF_TEYAKU_NONE,
CHAFF_TEYAKU_RED,
ONE_RIBBON,
ONE_ANIMAL,
@ -26,12 +26,12 @@ typedef enum ChaffTeyaku {
EMPTY_HAND,
} ChaffTeyaku;
int calculate_teyaku(const Hand h);
SetTeyaku calculate_set_teyaku(const Hand h);
ChaffTeyaku calculate_chaff_teyaku(const Hand h);
char *set_teyaku_english(const Hand h);
char *chaff_teyaku_english(const Hand h);
int set_teyaku_points(const Hand h);
int chaff_teyaku_points(const Hand h);
typedef struct Teyaku {
ChaffTeyaku chaff;
SetTeyaku set;
} Teyaku;
void calculate_teyaku(const Hand h, Teyaku *t);
void teyaku_to_string(Teyaku *t, char *str);
#endif