From c3094a9a5d7afb4e668bebca07fe2e4b15c6fee4 Mon Sep 17 00:00:00 2001
From: Bill Rossi <bassguitarbill@gmail.com>
Date: Mon, 3 Feb 2025 20:07:22 -0500
Subject: [PATCH] Deal properly

---
 card.c | 21 +++++++++++++++++----
 card.h |  6 +++++-
 game.c | 58 ++++++++++++++++++++++++++++++++++++++++++++--------------
 game.h |  6 ++++++
 move.c | 15 +++++++++++----
 move.h |  3 ++-
 6 files changed, 85 insertions(+), 24 deletions(-)

diff --git a/card.c b/card.c
index 1748867..79d38ad 100644
--- a/card.c
+++ b/card.c
@@ -46,13 +46,26 @@ void shuffle_hand(Hand *h) {
 
 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 };
+
+  c->move.position = &c->position;
+  c->move.origin.x = c->position.x;
+  c->move.origin.y = c->position.y;
+  c->move.destination.x = h->position.x + (h->count * (CARD_WIDTH + 10));
+  c->move.destination.y = h->position.y;
+  c->move.curve = CURVE_EASE_IN_OUT;
+  c->move.current_time = 0.;
+  c->move.end_time = 0.5;
 }
 
-void deal(Hand *from, Hand *to, int count) {
+bool card_done_moving(Card *c) {
+  return c->move.current_time > c->move.end_time;
+}
+
+void deal(Hand *from, Hand *to, int count, bool up) {
   for (int i = 0; i < count; i++) {
-    Card *t = from->cards[from->count - 1];
-    add_to_hand(to, t);
+    Card *c = from->cards[from->count - 1];
+    c->visible = up;
+    add_to_hand(to, c);
     from->count--;
   }
 }
diff --git a/card.h b/card.h
index 92d9110..3c8beb0 100644
--- a/card.h
+++ b/card.h
@@ -4,6 +4,8 @@
 #include <stdbool.h>
 #include <raylib.h>
 
+#include "move.h"
+
 typedef struct Card Card;
 typedef struct Hand Hand;
 #define CARD_WIDTH 73
@@ -47,6 +49,7 @@ struct Card {
   Vector2 position;
   bool selected;
   bool visible;
+  Move move;
 };
 
 struct Hand {
@@ -58,6 +61,7 @@ struct Hand {
 void draw_card(Card *c, Texture2D *cards_texture);
 bool point_within_card(Card *c, Vector2 v);
 void shuffle_hand(Hand *h);
-void deal(Hand *from, Hand *to, int count);
+void deal(Hand *from, Hand *to, int count, bool up);
+bool card_done_moving(Card *c);
 
 #endif
diff --git a/game.c b/game.c
index a2ea379..6f72e0f 100644
--- a/game.c
+++ b/game.c
@@ -13,6 +13,7 @@ char dekiyaku_calculation[400];
 void initialize_game(Game *g) {
   g->deck.count = 0;
   g->should_close = false;
+  g->state = GAME_STATE_INITIALIZING;
   for (int i = 0; i < 48; i++) {
     CardType t = CHAFF;
     RibbonType rt = RIBBON_NONE;
@@ -49,6 +50,8 @@ void initialize_game(Game *g) {
       t = ANIMAL; break;
     }
     g->cards[i] = (Card) { i, t, rt, month, (Vector2) { 800, 100 }, false, false };
+    g->cards[i].move.end_time = 0.;
+    g->cards[i].move.position = &g->cards[i].position;
     g->deck.cards[i] = &g->cards[i];
     g->deck.count++;
   }
@@ -62,27 +65,16 @@ void initialize_game(Game *g) {
   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);
+  g->state = GAME_STATE_DEALING;
 }
 
 bool stale_calculation = true;
-
 void handle_input(Game *g) {
   if (IsMouseButtonPressed(0)) {
     mouse_pos = GetMousePosition();
@@ -96,8 +88,7 @@ void handle_input(Game *g) {
   }
 }
 
-void run_frame(Game *g) {
-  handle_input(g);
+void run_calculation(Game *g) {
   int num_selected = 0;
   if (stale_calculation) {
     Hand h;
@@ -122,6 +113,45 @@ void run_frame(Game *g) {
   }
 }
 
+void run_frame_dealing(Game *g) {
+  if (g->player_hand.count < 4) {
+    deal(&g->deck, &g->player_hand, 4, true);
+  } else if (g->right_hand.count < 4) {
+    deal(&g->deck, &g->right_hand, 4, false);
+  } else if (g->left_hand.count < 4) {
+    deal(&g->deck, &g->left_hand, 4, false);
+  } else if (g->player_hand.count < 7) {
+    deal(&g->deck, &g->player_hand, 3, true);
+  } else if (g->right_hand.count < 7) {
+    deal(&g->deck, &g->right_hand, 3, false);
+  } else if (g->left_hand.count < 7) {
+    deal(&g->deck, &g->left_hand, 3, false);
+  } else {
+    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;
+  }
+  run_calculation(g);
+}
+
 void draw_frame(Game *g) {
   BeginDrawing();
   ClearBackground(RAYWHITE);
diff --git a/game.h b/game.h
index 2ca6dc6..c04ceb3 100644
--- a/game.h
+++ b/game.h
@@ -7,7 +7,13 @@ typedef struct Game Game;
 
 #include "card.h"
 
+typedef enum GameState {
+  GAME_STATE_INITIALIZING,
+  GAME_STATE_DEALING
+} GameState;
+
 struct Game {
+  GameState state;
   bool should_close;
   Card cards[48];
   Texture2D cards_texture;
diff --git a/move.c b/move.c
index 7eed111..6aefbec 100644
--- a/move.c
+++ b/move.c
@@ -1,25 +1,32 @@
 #include <math.h>
 #include "move.h"
 
-Vector2 move_position(Move *m, float delta) {
+void 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;
 
+  Vector2 v;
   switch (m->curve) {
   case CURVE_LINEAR:
-    return (Vector2) {
+    v = (Vector2) {
       ((m->destination.x - m->origin.x) * percentage) + m->origin.x,
       ((m->destination.y - m->origin.y) * percentage) + m->origin.y
     };
+    break;
   case CURVE_EASE_IN_OUT:
     percentage = -(cos(PI * percentage) - 1) / 2;
-    return (Vector2) {
+    v = (Vector2) {
       ((m->destination.x - m->origin.x) * percentage) + m->origin.x,
       ((m->destination.y - m->origin.y) * percentage) + m->origin.y
     };
+    break;
   default:
-    return m->destination;
+    v = m->destination;
+    break;
   }
+
+  m->position->x = v.x;
+  m->position->y = v.y;
 }
diff --git a/move.h b/move.h
index 298efd8..a791342 100644
--- a/move.h
+++ b/move.h
@@ -11,6 +11,7 @@ typedef enum Curve {
 typedef struct Move Move;
 
 struct Move {
+  Vector2 *position;
   Vector2 origin;
   Vector2 destination;
   Curve curve;
@@ -18,6 +19,6 @@ struct Move {
   float end_time;
 };
 
-Vector2 move_position(Move *m, float delta);
+void move_position(Move *m, float delta);
 
 #endif