Compare commits
No commits in common. "a40067ff8f28b3a31a1ad72893e533cdd40e31f5" and "3b6d384506d15dd870b75ec1c2e404f474a4963e" have entirely different histories.
a40067ff8f
...
3b6d384506
30
card.c
30
card.c
@ -1,30 +0,0 @@
|
|||||||
#include "card.h"
|
|
||||||
|
|
||||||
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);
|
|
||||||
DrawText(month_english_abbr[c->month], c->position.x + CARD_BORDER + 2, c->position.y + CARD_BORDER + 2, 14, BLACK);
|
|
||||||
switch (c->type) {
|
|
||||||
case CHAFF:
|
|
||||||
break;
|
|
||||||
case RIBBON:
|
|
||||||
Color ribbon_color = RED;
|
|
||||||
if (c->ribbon_type == RIBBON_BLUE) ribbon_color = BLUE;
|
|
||||||
DrawRectangle(c->position.x + 26, c->position.y + 35, 10, 45 , ribbon_color);
|
|
||||||
if (c->ribbon_type == RIBBON_POETRY) {
|
|
||||||
DrawRectangle(c->position.x + 29, c->position.y + 38, 4, 39 , BLACK);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ANIMAL:
|
|
||||||
DrawRectangle(c->position.x + 10, c->position.y + 45, 40, 25 , BLACK);
|
|
||||||
break;
|
|
||||||
case BRIGHT:
|
|
||||||
DrawCircle(c->position.x + 31, c->position.y + 65, 25 , YELLOW);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool point_within_card(Card *c, Vector2 point) {
|
|
||||||
return point.x > c->position.x && point.x < c->position.x + card_size.x &&
|
|
||||||
point.y > c->position.y && point.y < c->position.y + card_size.y;
|
|
||||||
}
|
|
61
card.h
61
card.h
@ -1,61 +0,0 @@
|
|||||||
#ifndef _HF_CARD_
|
|
||||||
#define _HF_CARD_
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <raylib.h>
|
|
||||||
|
|
||||||
typedef struct Card Card;
|
|
||||||
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,
|
|
||||||
RIBBON,
|
|
||||||
ANIMAL,
|
|
||||||
BRIGHT,
|
|
||||||
} CardType;
|
|
||||||
|
|
||||||
typedef enum RibbonType {
|
|
||||||
RIBBON_NONE,
|
|
||||||
RIBBON_PLAIN,
|
|
||||||
RIBBON_BLUE,
|
|
||||||
RIBBON_POETRY,
|
|
||||||
} RibbonType;
|
|
||||||
|
|
||||||
typedef enum Month {
|
|
||||||
JANUARY,
|
|
||||||
FEBRUARY,
|
|
||||||
MARCH,
|
|
||||||
APRIL,
|
|
||||||
MAY,
|
|
||||||
JUNE,
|
|
||||||
JULY,
|
|
||||||
AUGUST,
|
|
||||||
SEPTEMBER,
|
|
||||||
OCTOBER,
|
|
||||||
NOVEMBER,
|
|
||||||
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;
|
|
||||||
RibbonType ribbon_type;
|
|
||||||
Month month;
|
|
||||||
Vector2 position;
|
|
||||||
bool selected;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Hand {
|
|
||||||
Card cards[7];
|
|
||||||
int count;
|
|
||||||
};
|
|
||||||
|
|
||||||
void draw_card(Card *c);
|
|
||||||
|
|
||||||
#endif
|
|
102
main.c
102
main.c
@ -5,103 +5,27 @@
|
|||||||
|
|
||||||
#include <raylib.h>
|
#include <raylib.h>
|
||||||
|
|
||||||
#include "card.h"
|
|
||||||
#include "move.h"
|
|
||||||
#include "teyaku.h"
|
|
||||||
|
|
||||||
char *text = "こんにちわ、 世界!";
|
char *text = "こんにちわ、 世界!";
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
InitWindow(800, 550, "Hanafuda Hachi-Hachi");
|
InitWindow(800, 450, "Hanafuda Hachi-Hachi");
|
||||||
SetTargetFPS(60);
|
SetTargetFPS(60);
|
||||||
|
|
||||||
/*
|
int codepoints_count;
|
||||||
Hand h;
|
int *codepoints = LoadCodepoints(text, &codepoints_count);
|
||||||
h.cards[0] = (Card) { 1, BRIGHT, RIBBON_NONE, NOVEMBER, (Vector2) { 0, 0 } };
|
Font font = LoadFontEx("font/DotGothic16/DotGothic16-Regular.ttf", 48, codepoints, codepoints_count);
|
||||||
h.cards[1] = (Card) { 1, ANIMAL, RIBBON_NONE, NOVEMBER, (Vector2) { 0, 0 } };
|
|
||||||
h.cards[2] = (Card) { 1, RIBBON, RIBBON_PLAIN, NOVEMBER, (Vector2) { 0, 0 } };
|
|
||||||
h.cards[3] = (Card) { 1, CHAFF, RIBBON_NONE, NOVEMBER, (Vector2) { 0, 0 } };
|
|
||||||
h.cards[4] = (Card) { 1, CHAFF, RIBBON_NONE, DECEMBER, (Vector2) { 0, 0 } };
|
|
||||||
h.cards[5] = (Card) { 1, CHAFF, RIBBON_NONE, DECEMBER, (Vector2) { 0, 0 } };
|
|
||||||
h.cards[6] = (Card) { 1, CHAFF, RIBBON_NONE, DECEMBER, (Vector2) { 0, 0 } };
|
|
||||||
h.count = 7;
|
|
||||||
|
|
||||||
printf("Teyaku: %d\n", calculate_teyaku(h));
|
|
||||||
*/
|
|
||||||
|
|
||||||
Card cards[48];
|
|
||||||
for (int i = 0; i < 48; i++) {
|
|
||||||
CardType t = CHAFF;
|
|
||||||
RibbonType rt = RIBBON_NONE;
|
|
||||||
Month month = i / 4;
|
|
||||||
switch (i) {
|
|
||||||
case 0:
|
|
||||||
case 8:
|
|
||||||
case 28:
|
|
||||||
case 40:
|
|
||||||
case 44:
|
|
||||||
t = BRIGHT; break;
|
|
||||||
case 1:
|
|
||||||
case 5:
|
|
||||||
case 9:
|
|
||||||
t = RIBBON; rt = RIBBON_POETRY; break;
|
|
||||||
case 21:
|
|
||||||
case 33:
|
|
||||||
case 37:
|
|
||||||
t = RIBBON; rt = RIBBON_BLUE; break;
|
|
||||||
case 13:
|
|
||||||
case 17:
|
|
||||||
case 25:
|
|
||||||
case 42:
|
|
||||||
t = RIBBON; rt = RIBBON_PLAIN; break;
|
|
||||||
case 4:
|
|
||||||
case 12:
|
|
||||||
case 16:
|
|
||||||
case 20:
|
|
||||||
case 24:
|
|
||||||
case 29:
|
|
||||||
case 32:
|
|
||||||
case 36:
|
|
||||||
case 41:
|
|
||||||
t = ANIMAL; break;
|
|
||||||
}
|
|
||||||
cards[i] = (Card) { i, t, rt, month, (Vector2) { month * 65, (i % 4) * 110 }, false };
|
|
||||||
}
|
|
||||||
|
|
||||||
float delta;
|
|
||||||
Vector2 mouse_position;
|
|
||||||
|
|
||||||
while (!WindowShouldClose()) {
|
while (!WindowShouldClose()) {
|
||||||
delta = GetFrameTime();
|
|
||||||
|
|
||||||
if (IsMouseButtonPressed(0)) {
|
|
||||||
Vector2 mouse_pos = GetMousePosition();
|
|
||||||
for (int i = 0; i < 48; i++) {
|
|
||||||
if (point_within_card(&cards[i], mouse_pos)) {
|
|
||||||
cards[i].selected = !cards[i].selected;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(BLACK);
|
||||||
int num_selected = 0;
|
DrawTextEx(
|
||||||
for (int i = 0; i < 48; i++) {
|
font,
|
||||||
num_selected += cards[i].selected;
|
text,
|
||||||
draw_card(&cards[i]);
|
(Vector2) { 200, 200 },
|
||||||
}
|
48,
|
||||||
|
5.,
|
||||||
if (num_selected == 7) {
|
RAYWHITE
|
||||||
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);
|
|
||||||
}
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
23
move.c
23
move.c
@ -1,23 +0,0 @@
|
|||||||
#include <math.h>
|
|
||||||
#include "move.h"
|
|
||||||
|
|
||||||
Vector2 move_position(Move *m, float delta) {
|
|
||||||
m->current_time += delta;
|
|
||||||
float percentage = m->current_time / m->end_time;
|
|
||||||
if (percentage < 0.0) percentage = 0.0;
|
|
||||||
else if (percentage > 1.0) percentage = 1.0;
|
|
||||||
|
|
||||||
switch (m->curve) {
|
|
||||||
case CURVE_LINEAR:
|
|
||||||
return (Vector2) {
|
|
||||||
((m->destination.x - m->origin.x) * percentage) + m->origin.x,
|
|
||||||
((m->destination.y - m->origin.y) * percentage) + m->origin.y
|
|
||||||
};
|
|
||||||
case CURVE_EASE_IN_OUT:
|
|
||||||
percentage = -(cos(PI * percentage) - 1) / 2;
|
|
||||||
return (Vector2) {
|
|
||||||
((m->destination.x - m->origin.x) * percentage) + m->origin.x,
|
|
||||||
((m->destination.y - m->origin.y) * percentage) + m->origin.y
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
23
move.h
23
move.h
@ -1,23 +0,0 @@
|
|||||||
#ifndef _HF_MOVE_
|
|
||||||
#define _HF_MOVE_
|
|
||||||
|
|
||||||
#include <raylib.h>
|
|
||||||
|
|
||||||
typedef enum Curve {
|
|
||||||
CURVE_LINEAR,
|
|
||||||
CURVE_EASE_IN_OUT,
|
|
||||||
} Curve;
|
|
||||||
|
|
||||||
typedef struct Move Move;
|
|
||||||
|
|
||||||
struct Move {
|
|
||||||
Vector2 origin;
|
|
||||||
Vector2 destination;
|
|
||||||
Curve curve;
|
|
||||||
float current_time;
|
|
||||||
float end_time;
|
|
||||||
};
|
|
||||||
|
|
||||||
Vector2 move_position(Move *m, float delta);
|
|
||||||
|
|
||||||
#endif
|
|
88
teyaku.c
88
teyaku.c
@ -1,88 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "teyaku.h"
|
|
||||||
#include "card.h"
|
|
||||||
|
|
||||||
SetTeyaku 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 };
|
|
||||||
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++; // TODO Pawlonia is weird
|
|
||||||
else triplets++;
|
|
||||||
} else if (month_counts[i] == 2) {
|
|
||||||
pairs++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int total_triplets = triplets + standing_triplets;
|
|
||||||
|
|
||||||
if (four_of_a_kind && total_triplets) return FOUR_THREE;
|
|
||||||
else if (four_of_a_kind && pairs) return ONE_TWO_FOUR;
|
|
||||||
else if (standing_triplets == 2) return TWO_STANDING_TRIPLETS;
|
|
||||||
else if (total_triplets && pairs == 2) return TRIPLET_AND_TWO_PAIRS;
|
|
||||||
else if (triplets == 1 && standing_triplets == 1) return TRIPLET_AND_STANDING_TRIPLET;
|
|
||||||
else if (four_of_a_kind) return FOUR_OF_A_KIND;
|
|
||||||
else if (triplets == 2) return TWO_TRIPLETS;
|
|
||||||
else if (pairs == 3) return THREE_PAIRS;
|
|
||||||
else if (standing_triplets) return STANDING_TRIPLET;
|
|
||||||
else if (triplets) return TRIPLET;
|
|
||||||
|
|
||||||
return SET_TEYAKU_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ChaffTeyaku 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 EMPTY_HAND;
|
|
||||||
else if (chaff == 6 && brights == 1) return ONE_BRIGHT;
|
|
||||||
else if (chaff == 6 && animals == 1) return ONE_ANIMAL;
|
|
||||||
else if (chaff == 6 && ribbons == 1) return ONE_RIBBON;
|
|
||||||
else if (ribbons >= 2 && chaff == 7 - ribbons) return CHAFF_TEYAKU_RED;
|
|
||||||
|
|
||||||
return CHAFF_TEYAKU_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int set_teyaku_points_array[11] = { 0, 2, 3, 6, 7, 8, 4, 6, 7, 8, 20 };
|
|
||||||
static char *set_teyaku_english_array[11] = { "None", "Triplet", "Standing Triplet", "Two Triplets", "Triplet and Standing Triplet", "Two Standing Triplets", "Three Pairs", "Four of a Kind", "Triplet and Two Pairs", "One-Two-Four", "Four-Three" };
|
|
||||||
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(Hand h) {
|
|
||||||
return set_teyaku_points_array[calculate_set_teyaku(h)];
|
|
||||||
}
|
|
||||||
|
|
||||||
int chaff_teyaku_points(Hand h) {
|
|
||||||
return chaff_teyaku_points_array[calculate_chaff_teyaku(h)];
|
|
||||||
}
|
|
||||||
|
|
||||||
char *set_teyaku_english(Hand h) {
|
|
||||||
return set_teyaku_english_array[calculate_set_teyaku(h)];
|
|
||||||
}
|
|
||||||
|
|
||||||
char *chaff_teyaku_english(Hand h) {
|
|
||||||
return chaff_teyaku_english_array[calculate_chaff_teyaku(h)];
|
|
||||||
}
|
|
||||||
|
|
||||||
int calculate_teyaku(Hand h) {
|
|
||||||
return chaff_teyaku_points(h) + set_teyaku_points(h);
|
|
||||||
}
|
|
37
teyaku.h
37
teyaku.h
@ -1,37 +0,0 @@
|
|||||||
#ifndef _HF_TEYAKU_
|
|
||||||
#define _HF_TEYAKU_
|
|
||||||
|
|
||||||
#include "card.h"
|
|
||||||
|
|
||||||
typedef enum SetTeyaku {
|
|
||||||
SET_TEYAKU_NONE = 0,
|
|
||||||
TRIPLET,
|
|
||||||
STANDING_TRIPLET,
|
|
||||||
TWO_TRIPLETS,
|
|
||||||
TRIPLET_AND_STANDING_TRIPLET,
|
|
||||||
TWO_STANDING_TRIPLETS,
|
|
||||||
THREE_PAIRS,
|
|
||||||
FOUR_OF_A_KIND,
|
|
||||||
TRIPLET_AND_TWO_PAIRS,
|
|
||||||
ONE_TWO_FOUR,
|
|
||||||
FOUR_THREE,
|
|
||||||
} SetTeyaku;
|
|
||||||
|
|
||||||
typedef enum ChaffTeyaku {
|
|
||||||
CHAFF_TEYAKU_NONE = 0,
|
|
||||||
CHAFF_TEYAKU_RED,
|
|
||||||
ONE_RIBBON,
|
|
||||||
ONE_ANIMAL,
|
|
||||||
ONE_BRIGHT,
|
|
||||||
EMPTY_HAND,
|
|
||||||
} ChaffTeyaku;
|
|
||||||
|
|
||||||
int calculate_teyaku(Hand h);
|
|
||||||
SetTeyaku calculate_set_teyaku(Hand h);
|
|
||||||
ChaffTeyaku calculate_chaff_teyaku(Hand h);
|
|
||||||
char *set_teyaku_english(Hand h);
|
|
||||||
char *chaff_teyaku_english(Hand h);
|
|
||||||
int set_teyaku_points(Hand h);
|
|
||||||
int chaff_teyaku_points(Hand h);
|
|
||||||
|
|
||||||
#endif
|
|
Loading…
Reference in New Issue
Block a user