From 58859768f06a26ccb2a0e997464727282a0b2092 Mon Sep 17 00:00:00 2001 From: Bill Rossi Date: Sat, 1 Feb 2025 06:40:33 -0500 Subject: [PATCH] Teyaku calculations --- card.h | 22 ++++++++++++++++++++ main.c | 13 ++++++++++++ teyaku.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ teyaku.h | 8 +++++++ 4 files changed, 106 insertions(+) create mode 100644 teyaku.c create mode 100644 teyaku.h diff --git a/card.h b/card.h index 9f8a272..7122db2 100644 --- a/card.h +++ b/card.h @@ -5,6 +5,7 @@ #include typedef struct Card Card; +typedef struct Hand Hand; #define CARD_WIDTH 63 #define CARD_HEIGHT 105 static Vector2 card_size = (Vector2) { CARD_WIDTH, CARD_HEIGHT }; @@ -23,13 +24,34 @@ typedef enum RibbonType { RIBBON_POETRY, } RibbonType; +typedef enum Month { + JANUARY, + FEBRUARY, + MARCH, + APRIL, + MAY, + JUNE, + JULY, + AUGUST, + SEPTEMBER, + OCTOBER, + NOVEMBER, + DECEMBER +} Month; + struct Card { int index; CardType type; RibbonType ribbon_type; + Month month; Vector2 position; }; +struct Hand { + Card cards[7]; + int count; +}; + void draw_card(Card *c); #endif diff --git a/main.c b/main.c index 98cae18..739ac01 100644 --- a/main.c +++ b/main.c @@ -7,6 +7,7 @@ #include "card.h" #include "move.h" +#include "teyaku.h" char *text = "こんにちわ、 世界!"; @@ -14,6 +15,18 @@ int main(int argc, char** argv) { InitWindow(800, 450, "Hanafuda Hachi-Hachi"); SetTargetFPS(60); + Hand h; + h.cards[0] = (Card) { 1, CHAFF, RIBBON_NONE, JANUARY, (Vector2) { 0, 0 } }; + h.cards[1] = (Card) { 1, CHAFF, RIBBON_NONE, JANUARY, (Vector2) { 0, 0 } }; + h.cards[2] = (Card) { 1, CHAFF, RIBBON_NONE, JANUARY, (Vector2) { 0, 0 } }; + h.cards[3] = (Card) { 1, ANIMAL, RIBBON_NONE, JANUARY, (Vector2) { 0, 0 } }; + h.cards[4] = (Card) { 1, ANIMAL, RIBBON_NONE, MAY, (Vector2) { 0, 0 } }; + h.cards[5] = (Card) { 1, CHAFF, RIBBON_BLUE, MAY, (Vector2) { 0, 0 } }; + h.cards[6] = (Card) { 1, CHAFF, RIBBON_PLAIN, MAY, (Vector2) { 0, 0 } }; + h.count = 7; + + printf("Teyaku: %d\n", calculate_teyaku(h)); + Card *c = malloc(sizeof(Card)); c->position = (Vector2) { 200, 200 }; diff --git a/teyaku.c b/teyaku.c new file mode 100644 index 0000000..77e7872 --- /dev/null +++ b/teyaku.c @@ -0,0 +1,63 @@ +#include "card.h" + +int calculate_set_teyaku(Hand h) { + int month_counts[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int month_stands[12] = { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1 }; // TODO Pawlonia is weird + for (int i = 0; i < h.count; i++) { + Card c = h.cards[i]; + month_counts[c.month]++; + } + + int triplets = 0, standing_triplets = 0, pairs = 0, four_of_a_kind = 0; + for (int i = 0; i < 12; i++) { + if (month_counts[i] == 4) { + four_of_a_kind++; + } else if (month_counts[i] == 3) { + if (month_stands[i]) standing_triplets++; + else triplets++; + } else if (month_counts[i] == 2) { + pairs++; + } + } + int total_triplets = triplets + standing_triplets; + + if (four_of_a_kind && total_triplets) return 20; // 四三 + else if (four_of_a_kind && pairs) return 8; // 一二四 + else if (standing_triplets == 2) return 8; // 二立三本 + else if (total_triplets && pairs == 2) return 7; // 跳剣 + else if (triplets == 1 && standing_triplets == 1) return 7; // 三本立三本 + else if (four_of_a_kind) return 6; // 手四 + else if (triplets == 2) return 6; // 二三本 + else if (pairs == 3) return 4; // 二三本 + else if (standing_triplets) return 3; // 立三本 + else if (triplets) return 2; // 三本 + + return 0; +} + +int calculate_chaff_teyaku(Hand h) { + int ribbons = 0; + int animals = 0; + int brights = 0; + int chaff = 0; + + for (int i = 0; i < h.count; i++) { + Card c = h.cards[i]; + if (c.month == NOVEMBER) chaff++; // November cards are all counted as chaff here + else if (c.type == BRIGHT) brights++; + else if (c.type == RIBBON) ribbons++; + else if (c.type == ANIMAL) animals++; + else chaff++; + } + + if (chaff == 7) return 4; // 空素 - Empty Hand + else if (chaff == 6 && brights == 1) return 4; // 光一 - One Bright + else if (chaff == 6 && animals == 1) return 3; // 十一 - One Animal + else if (chaff == 6 && ribbons == 1) return 3; // 短一 - One Ribbon + else if (ribbons >= 2 && chaff == 7 - ribbons) return 2; // 赤 - Red + else return 0; +} + +int calculate_teyaku(Hand h) { + return calculate_chaff_teyaku(h) + calculate_set_teyaku(h); +} diff --git a/teyaku.h b/teyaku.h new file mode 100644 index 0000000..e14da25 --- /dev/null +++ b/teyaku.h @@ -0,0 +1,8 @@ +#ifndef _HF_TEYAKU_ +#define _HF_TEYAKU_ + +#include "card.h" + +int calculate_teyaku(Hand h); + +#endif