#include #include #include "game.h" #include "card.h" #include "teyaku.h" #include "dekiyaku.h" #include "field_multiplier.h" Vector2 mouse_pos; char teyaku_calculation[400]; void initialize_game(Game *g) { g->deck.count = 0; g->should_close = false; g->state = GAME_STATE_INITIALIZING; g->field_multiplier = NULL; g->player_teyaku.calculated = false; g->left_teyaku.calculated = false; g->right_teyaku.calculated = 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, { 800, 100 }, false, false }; g->cards[i].move.end_time = 0.; g->cards[i].move.position = &g->cards[i].position; g->cards[i].move.destination = (Vector2) { 800, 300 }; g->deck.cards[i] = &g->cards[i]; g->deck.count++; } shuffle_hand(&g->deck); g->player_hand.count = 0; g->player_hand.position = (Vector2) { 300, 550 }; g->player_hand.display_type = HAND_DISPLAY_ROW; g->right_hand.count = 0; g->right_hand.position = (Vector2) { 20, 100 }; g->right_hand.display_type = HAND_DISPLAY_ROW; g->left_hand.count = 0; g->left_hand.position = (Vector2) { 600, 100 }; g->left_hand.display_type = HAND_DISPLAY_ROW; g->field.count = 0; g->field.position = (Vector2) { 400, 250 }; g->field.display_type = HAND_DISPLAY_FIELD; strcpy(teyaku_calculation, ""); Image cards_image = LoadImage("img/cards.png"); g->cards_texture = LoadTextureFromImage(cards_image); UnloadImage(cards_image); g->state = GAME_STATE_DEALING; } 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_calculation(Game *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, ""); } stale_calculation = false; } } void run_frame_dealing(Game *g) { if (g->player_hand.count < 4) { deal(&g->deck, &g->player_hand, 4, true); } else if (g->left_hand.count < 4) { deal(&g->deck, &g->left_hand, 4, false); } else if (g->right_hand.count < 4) { deal(&g->deck, &g->right_hand, 4, false); } else if (g->field.count < 3) { deal(&g->deck, &g->field, 3, true); } else if (g->player_hand.count < 7) { deal(&g->deck, &g->player_hand, 3, true); } else if (g->left_hand.count < 7) { deal(&g->deck, &g->left_hand, 3, false); } else if (g->right_hand.count < 7) { deal(&g->deck, &g->right_hand, 3, false); } else if (g->field.count < 6) { deal(&g->deck, &g->field, 3, true); } else { g->state = GAME_STATE_CALCULATING_FIELD_MULTIPLIER; } } void run_frame_calculating_field_multiplier(Game *g) { g->field_multiplier = calculate_field_multiplier(&g->field); g->state = GAME_STATE_CALCULATING_TEYAKU; } void run_frame_calculating_teyaku(Game *g) { calculate_teyaku(g->player_hand, &g->player_teyaku); g->state = GAME_STATE_INITIALIZING; } void run_frame(Game *g) { float delta = GetFrameTime(); bool done_moving = true; for (int i = 0; i < 48; i++) { move_position(&g->cards[i].move, delta); if (!card_done_moving(&g->cards[i])) done_moving = false; } if (!done_moving) return; handle_input(g); switch (g->state) { case GAME_STATE_INITIALIZING: return; case GAME_STATE_DEALING: run_frame_dealing(g); break; case GAME_STATE_CALCULATING_FIELD_MULTIPLIER: run_frame_calculating_field_multiplier(g); break; case GAME_STATE_CALCULATING_TEYAKU: run_frame_calculating_teyaku(g); break; } run_calculation(g); } void draw_frame(Game *g) { BeginDrawing(); ClearBackground(RAYWHITE); for (int i = 0; i < 48; i++) { draw_card(&g->cards[i], &g->cards_texture); } if (g->field_multiplier) DrawText(g->field_multiplier->name, 60, 385, 40, BLACK); if (g->player_teyaku.calculated) { char s[200]; teyaku_to_string(&g->player_teyaku, s); DrawText(s, 5, 25, 30, BLACK); } EndDrawing(); } void run_until_closing(Game *g) { while (!WindowShouldClose() && !g->should_close) { run_frame(g); draw_frame(g); } }