Compare commits
3 Commits
69be5acad2
...
de975d524d
Author | SHA1 | Date | |
---|---|---|---|
de975d524d | |||
f852af7cd7 | |||
f17bd76b83 |
46
card.c
46
card.c
@ -1,3 +1,5 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "card.h"
|
#include "card.h"
|
||||||
|
|
||||||
static Vector2 card_size = (Vector2) { CARD_WIDTH, CARD_HEIGHT };
|
static Vector2 card_size = (Vector2) { CARD_WIDTH, CARD_HEIGHT };
|
||||||
@ -9,14 +11,19 @@ void draw_card(Card *c, Texture2D *cards_texture) {
|
|||||||
int pos_vert = i_vert * CARD_HEIGHT;
|
int pos_vert = i_vert * CARD_HEIGHT;
|
||||||
int pos_horiz = i_horiz * CARD_WIDTH;
|
int pos_horiz = i_horiz * CARD_WIDTH;
|
||||||
|
|
||||||
DrawTexturePro(
|
if (c->visible) {
|
||||||
*cards_texture,
|
DrawTexturePro(
|
||||||
(Rectangle) { pos_horiz, pos_vert, CARD_WIDTH, CARD_HEIGHT },
|
*cards_texture,
|
||||||
(Rectangle) { c->position.x, c->position.y, card_size.x, card_size.y },
|
(Rectangle) { pos_horiz, pos_vert, CARD_WIDTH, CARD_HEIGHT },
|
||||||
(Vector2) { 0, 0 },
|
(Rectangle) { c->position.x, c->position.y, card_size.x, card_size.y },
|
||||||
0.,
|
(Vector2) { 0, 0 },
|
||||||
RAYWHITE
|
0.,
|
||||||
);
|
RAYWHITE
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
DrawRectangleRec((Rectangle) { c->position.x, c->position.y, card_size.x, card_size.y }, BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
if (c->selected) {
|
if (c->selected) {
|
||||||
DrawCircle(c->position.x + 10, c->position.y + 10, 10, BLUE);
|
DrawCircle(c->position.x + 10, c->position.y + 10, 10, BLUE);
|
||||||
}
|
}
|
||||||
@ -26,3 +33,26 @@ bool point_within_card(Card *c, Vector2 point) {
|
|||||||
return point.x > c->position.x && point.x < c->position.x + card_size.x &&
|
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;
|
point.y > c->position.y && point.y < c->position.y + card_size.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void shuffle_hand(Hand *h) {
|
||||||
|
Card *swap;
|
||||||
|
for (int i = h->count - 1; i >= 0; i--) {
|
||||||
|
int index = rand() % (i + 1);
|
||||||
|
swap = h->cards[i];
|
||||||
|
h->cards[i] = h->cards[index];
|
||||||
|
h->cards[index] = swap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_to_hand(Hand *h, Card *c) {
|
||||||
|
h->cards[h->count++] = c;
|
||||||
|
c->position = (Vector2) { h->position.x + (h->count * (CARD_WIDTH + 10)), h->position.y };
|
||||||
|
}
|
||||||
|
|
||||||
|
void deal(Hand *from, Hand *to, int count) {
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
Card *t = from->cards[from->count - 1];
|
||||||
|
add_to_hand(to, t);
|
||||||
|
from->count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
6
card.h
6
card.h
@ -46,14 +46,18 @@ struct Card {
|
|||||||
Month month;
|
Month month;
|
||||||
Vector2 position;
|
Vector2 position;
|
||||||
bool selected;
|
bool selected;
|
||||||
|
bool visible;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Hand {
|
struct Hand {
|
||||||
Card cards[48];
|
Card *cards[48];
|
||||||
int count;
|
int count;
|
||||||
|
Vector2 position;
|
||||||
};
|
};
|
||||||
|
|
||||||
void draw_card(Card *c, Texture2D *cards_texture);
|
void draw_card(Card *c, Texture2D *cards_texture);
|
||||||
bool point_within_card(Card *c, Vector2 v);
|
bool point_within_card(Card *c, Vector2 v);
|
||||||
|
void shuffle_hand(Hand *h);
|
||||||
|
void deal(Hand *from, Hand *to, int count);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
10
dekiyaku.c
10
dekiyaku.c
@ -6,20 +6,20 @@
|
|||||||
void calculate_dekiyaku(const Hand h, Dekiyaku *d) {
|
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;
|
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++) {
|
for (int i = 0; i < h.count; i++) {
|
||||||
const Card card = h.cards[i];
|
Card *card = h.cards[i];
|
||||||
switch (card.type) {
|
switch (card->type) {
|
||||||
case BRIGHT: brights++; break;
|
case BRIGHT: brights++; break;
|
||||||
case RIBBON:
|
case RIBBON:
|
||||||
ribbons++;
|
ribbons++;
|
||||||
if (card.month != NOVEMBER) ribbons_except_november++;
|
if (card->month != NOVEMBER) ribbons_except_november++;
|
||||||
switch (card.ribbon_type) {
|
switch (card->ribbon_type) {
|
||||||
case RIBBON_BLUE: blue_ribbons++; break;
|
case RIBBON_BLUE: blue_ribbons++; break;
|
||||||
case RIBBON_POETRY: poetry_ribbons++; break;
|
case RIBBON_POETRY: poetry_ribbons++; break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ANIMAL:
|
case ANIMAL:
|
||||||
switch (card.month) {
|
switch (card->month) {
|
||||||
case JUNE: butterflies++; break;
|
case JUNE: butterflies++; break;
|
||||||
case JULY: boar++; break;
|
case JULY: boar++; break;
|
||||||
case OCTOBER: deer++; break;
|
case OCTOBER: deer++; break;
|
||||||
|
142
game.c
Normal file
142
game.c
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "game.h"
|
||||||
|
#include "card.h"
|
||||||
|
#include "teyaku.h"
|
||||||
|
#include "dekiyaku.h"
|
||||||
|
|
||||||
|
Vector2 mouse_pos;
|
||||||
|
char teyaku_calculation[400];
|
||||||
|
char dekiyaku_calculation[400];
|
||||||
|
|
||||||
|
void initialize_game(Game *g) {
|
||||||
|
g->deck.count = 0;
|
||||||
|
g->should_close = false;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
g->cards[i] = (Card) { i, t, rt, month, (Vector2) { 800, 100 }, false, false };
|
||||||
|
g->deck.cards[i] = &g->cards[i];
|
||||||
|
g->deck.count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
shuffle_hand(&g->deck);
|
||||||
|
|
||||||
|
g->player_hand.count = 0;
|
||||||
|
g->player_hand.position = (Vector2) { 20, 450 };
|
||||||
|
g->right_hand.count = 0;
|
||||||
|
g->right_hand.position = (Vector2) { 20, 100 };
|
||||||
|
g->left_hand.count = 0;
|
||||||
|
g->left_hand.position = (Vector2) { 20, 300 };
|
||||||
|
|
||||||
|
deal(&g->deck, &g->player_hand, 4);
|
||||||
|
deal(&g->deck, &g->right_hand, 4);
|
||||||
|
deal(&g->deck, &g->left_hand, 4);
|
||||||
|
deal(&g->deck, &g->player_hand, 3);
|
||||||
|
deal(&g->deck, &g->right_hand, 3);
|
||||||
|
deal(&g->deck, &g->left_hand, 3);
|
||||||
|
|
||||||
|
for (int i = 0; i < g->player_hand.count; i++) {
|
||||||
|
g->player_hand.cards[i]->visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(teyaku_calculation, "");
|
||||||
|
strcpy(dekiyaku_calculation, "");
|
||||||
|
|
||||||
|
Image cards_image = LoadImage("img/cards.png");
|
||||||
|
g->cards_texture = LoadTextureFromImage(cards_image);
|
||||||
|
UnloadImage(cards_image);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool stale_calculation = true;
|
||||||
|
|
||||||
|
void handle_input(Game *g) {
|
||||||
|
if (IsMouseButtonPressed(0)) {
|
||||||
|
mouse_pos = GetMousePosition();
|
||||||
|
for (int i = 0; i < 48; i++) {
|
||||||
|
if (point_within_card(&g->cards[i], mouse_pos)) {
|
||||||
|
g->cards[i].selected = !g->cards[i].selected;
|
||||||
|
stale_calculation = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_frame(Game *g) {
|
||||||
|
handle_input(g);
|
||||||
|
int num_selected = 0;
|
||||||
|
if (stale_calculation) {
|
||||||
|
Hand h;
|
||||||
|
h.count = 0;
|
||||||
|
for (int i = 0; i < 48; i++) {
|
||||||
|
num_selected += g->cards[i].selected;
|
||||||
|
if (g->cards[i].selected) h.cards[h.count++] = &g->cards[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
stale_calculation = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_frame(Game *g) {
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
for (int i = 0; i < 48; i++) {
|
||||||
|
draw_card(&g->cards[i], &g->cards_texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawText(teyaku_calculation, 10, 550, 25, BLACK);
|
||||||
|
DrawText(dekiyaku_calculation, 10, 500, 25, BLACK);
|
||||||
|
EndDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_until_closing(Game *g) {
|
||||||
|
while (!WindowShouldClose() && !g->should_close) {
|
||||||
|
run_frame(g);
|
||||||
|
draw_frame(g);
|
||||||
|
}
|
||||||
|
}
|
20
game.h
Normal file
20
game.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef _HF_GAME_
|
||||||
|
#define _HF_GAME_
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct Game Game;
|
||||||
|
|
||||||
|
#include "card.h"
|
||||||
|
|
||||||
|
struct Game {
|
||||||
|
bool should_close;
|
||||||
|
Card cards[48];
|
||||||
|
Texture2D cards_texture;
|
||||||
|
Hand player_hand, left_hand, right_hand, deck;
|
||||||
|
};
|
||||||
|
|
||||||
|
void initialize_game(Game *g);
|
||||||
|
void run_until_closing(Game *g);
|
||||||
|
|
||||||
|
#endif
|
129
main.c
129
main.c
@ -2,132 +2,25 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#include <raylib.h>
|
#include <raylib.h>
|
||||||
|
|
||||||
#include "card.h"
|
#include "game.h"
|
||||||
#include "move.h"
|
|
||||||
#include "teyaku.h"
|
|
||||||
#include "dekiyaku.h"
|
|
||||||
|
|
||||||
char *text = "こんにちわ、 世界!";
|
char *text = "こんにちわ、 世界!";
|
||||||
|
Texture2D cards_texture;
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
InitWindow(900, 600, "Hanafuda Hachi-Hachi");
|
srand(time(NULL));
|
||||||
SetTargetFPS(60);
|
InitWindow(900, 600, "Hanafuda Hachi-Hachi");
|
||||||
|
SetTargetFPS(60);
|
||||||
|
|
||||||
Image cards_image = LoadImage("img/cards.png");
|
Game g;
|
||||||
Texture2D cards_texture = LoadTextureFromImage(cards_image);
|
initialize_game(&g);
|
||||||
UnloadImage(cards_image);
|
|
||||||
|
|
||||||
/*
|
run_until_closing(&g);
|
||||||
Hand h;
|
|
||||||
h.cards[0] = (Card) { 1, BRIGHT, RIBBON_NONE, NOVEMBER, (Vector2) { 0, 0 } };
|
|
||||||
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));
|
CloseWindow();
|
||||||
*/
|
return 0;
|
||||||
|
|
||||||
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 * 75, (i % 4) * 123 }, false };
|
|
||||||
}
|
|
||||||
|
|
||||||
// float delta;
|
|
||||||
Vector2 mouse_pos;
|
|
||||||
char teyaku_calculation[400];
|
|
||||||
strcpy(teyaku_calculation, "");
|
|
||||||
char dekiyaku_calculation[400];
|
|
||||||
strcpy(dekiyaku_calculation, "");
|
|
||||||
|
|
||||||
while (!WindowShouldClose()) {
|
|
||||||
// delta = GetFrameTime();
|
|
||||||
|
|
||||||
if (IsMouseButtonPressed(0)) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BeginDrawing();
|
|
||||||
ClearBackground(RAYWHITE);
|
|
||||||
int num_selected = 0;
|
|
||||||
for (int i = 0; i < 48; i++) {
|
|
||||||
num_selected += cards[i].selected;
|
|
||||||
draw_card(&cards[i], &cards_texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
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, 550, 25, BLACK);
|
|
||||||
DrawText(dekiyaku_calculation, 10, 500, 25, BLACK);
|
|
||||||
EndDrawing();
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseWindow();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
4
teyaku.c
4
teyaku.c
@ -7,7 +7,7 @@ SetTeyaku calculate_set_teyaku(const Hand h) {
|
|||||||
int month_counts[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
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 };
|
int month_stands[12] = { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1 };
|
||||||
for (int i = 0; i < h.count; i++) {
|
for (int i = 0; i < h.count; i++) {
|
||||||
Card c = h.cards[i];
|
Card c = *h.cards[i];
|
||||||
month_counts[c.month]++;
|
month_counts[c.month]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ ChaffTeyaku calculate_chaff_teyaku(const Hand h) {
|
|||||||
int chaff = 0;
|
int chaff = 0;
|
||||||
|
|
||||||
for (int i = 0; i < h.count; i++) {
|
for (int i = 0; i < h.count; i++) {
|
||||||
Card c = h.cards[i];
|
Card c = *h.cards[i];
|
||||||
if (c.month == NOVEMBER) chaff++; // November cards are all counted as chaff here
|
if (c.month == NOVEMBER) chaff++; // November cards are all counted as chaff here
|
||||||
else if (c.type == BRIGHT) brights++;
|
else if (c.type == BRIGHT) brights++;
|
||||||
else if (c.type == RIBBON) ribbons++;
|
else if (c.type == RIBBON) ribbons++;
|
||||||
|
Loading…
Reference in New Issue
Block a user