133 lines
3.5 KiB
C
133 lines
3.5 KiB
C
// Copyright 2025 Bill Rossi
|
|
//
|
|
// This file is part of Hanafuda Hachi-Hachi.
|
|
//
|
|
// Hanafuda Hachi-Hachi is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
//
|
|
// Hanafuda Hachi-Hachi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License along with Hanafuda Hachi-Hachi. If not, see <https://www.gnu.org/licenses/>.
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
#include "dekiyaku.h"
|
|
|
|
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];
|
|
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);
|
|
}
|
|
}
|
|
|
|
int dekiyaku_score(Dekiyaku *d) {
|
|
int score = 0;
|
|
for (int i = 0; i < d->count; i++) {
|
|
score += d->meld[i].value;
|
|
}
|
|
return score;
|
|
}
|