From 892fc32efaf4eda3e401ef98952f4d7d857e81ec Mon Sep 17 00:00:00 2001
From: Bill Rossi <bassguitarbill@gmail.com>
Date: Mon, 10 Feb 2025 17:27:02 -0500
Subject: [PATCH] The deck now knows where it is

---
 card.c | 19 ++++++++++++++-----
 card.h |  1 +
 game.c | 36 ++++++++++++++++++++++++++++++++++--
 game.h |  1 +
 play.c | 10 ++++++++++
 play.h |  1 +
 6 files changed, 61 insertions(+), 7 deletions(-)

diff --git a/card.c b/card.c
index 1dc2e02..82fad22 100644
--- a/card.c
+++ b/card.c
@@ -48,25 +48,34 @@ void remove_from_hand(Hand *h, Card *c) {
   bool card_found = false;
   for (int i = 0; i < h->count - 1; i++) {
     if (h->cards[i] == c) card_found = true;
-    h->cards[i] = h->cards[i + 1];
+    if (card_found) h->cards[i] = h->cards[i + 1];
   }
   h->count--;
 }
 
 void add_to_hand(Hand *h, Card *c) {
-  h->cards[h->count] = c;
+  int i = 0;
+  for (; i < h->count; i++) {
+    if (h->cards[i] == NULL) break;
+  }
+
+  h->cards[i] = c;
 
   c->move.position = &c->position;
   c->move.origin.x = c->position.x;
   c->move.origin.y = c->position.y;
   switch (h->display_type) {
   case HAND_DISPLAY_ROW:
-    c->move.destination.x = h->position.x + (h->count * (CARD_WIDTH + 10));
+    c->move.destination.x = h->position.x + (i * (CARD_WIDTH + 10));
     c->move.destination.y = h->position.y;
     break;
   case HAND_DISPLAY_FIELD:
-    c->move.destination.x = h->position.x + ((h->count / 2) * (CARD_WIDTH + 10));
-    c->move.destination.y = h->position.y + (h->count % 2 * (CARD_HEIGHT + 10));
+    c->move.destination.x = h->position.x + ((i / 2) * (CARD_WIDTH + 10));
+    c->move.destination.y = h->position.y + (i % 2 * (CARD_HEIGHT + 10));
+    break;
+  case HAND_DISPLAY_DECK:
+    c->move.destination.x = h->position.x;
+    c->move.destination.y = h->position.y;
     break;
   }
   c->move.curve = CURVE_EASE_IN_OUT;
diff --git a/card.h b/card.h
index b949f60..ea0b755 100644
--- a/card.h
+++ b/card.h
@@ -61,6 +61,7 @@ struct Card {
 typedef enum HandDisplayType {
   HAND_DISPLAY_ROW,
   HAND_DISPLAY_FIELD,
+  HAND_DISPLAY_DECK,
 } HandDisplayType;
 
 struct Hand {
diff --git a/game.c b/game.c
index 517c218..39e78f0 100644
--- a/game.c
+++ b/game.c
@@ -13,6 +13,8 @@ char teyaku_calculation[400];
 
 void initialize_game(Game *g) {
   g->deck.count = 0;
+  g->deck.position = (Vector2) { 800, 400 };
+  g->deck.display_type = HAND_DISPLAY_DECK;
   g->should_close = false;
   g->state = GAME_STATE_INITIALIZING;
   g->field_multiplier = NULL;
@@ -144,10 +146,10 @@ void handle_input(Game *g) {
 	    g->current_play_from_hand = selected_card;
 	    g->current_play_target = g->field.cards[i];
 	    printf("Valid\n");
-	    break;
 	  } else {
 	    printf("Invalid\n");
 	  }
+	  break;
 	}
       }
 
@@ -209,7 +211,6 @@ void run_frame_player_choosing_from_hand(Game *g) {
       return;
     }
   }
-
 }
 
 void run_frame_player_choosing_target(Game *g) {
@@ -241,7 +242,35 @@ void run_frame_player_choosing_target(Game *g) {
       add_to_hand(&g->field, g->current_play_from_hand);
       g->current_play_from_hand = NULL;
     }
+    g->state = GAME_STATE_PLAYER_FROM_DECK;
+  }
+}
+
+void run_frame_player_from_deck(Game *g) {
+  Card *top_card = g->deck.cards[g->deck.count - 1];
+  if (top_card->visible) {
+    printf("flipped\n");
+    // if the card's already been flipped up
+    Card *target = valid_target(top_card, &g->field);
+    if (target) {
+      remove_from_hand(&g->field, target);
+      add_to_hand(&g->player_scored, target);
+      remove_from_hand(&g->deck, top_card);
+      add_to_hand(&g->player_scored, top_card);
+    } else {
+      remove_from_hand(&g->deck, top_card);
+      add_to_hand(&g->field, top_card);
+    }
     g->state = GAME_STATE_INITIALIZING;
+  } else {
+    printf("flip top\n");
+    // flip up the top card
+    remove_from_hand(&g->deck, top_card);
+    add_to_hand(&g->deck, top_card);
+    top_card->visible = true;
+    top_card->move.end_time = 0.3;
+    top_card->move.destination.x = top_card->move.destination.x + 100;
+    printf("moving to %f %f\n", top_card->move.destination.x, top_card->move.destination.y);
   }
 }
 
@@ -274,6 +303,9 @@ void run_frame(Game *g) {
   case GAME_STATE_PLAYER_CHOOSING_TARGET:
     run_frame_player_choosing_target(g);
     break;
+  case GAME_STATE_PLAYER_FROM_DECK:
+    run_frame_player_from_deck(g);
+    break;
   }
 }
 
diff --git a/game.h b/game.h
index bc309cd..bc219db 100644
--- a/game.h
+++ b/game.h
@@ -16,6 +16,7 @@ typedef enum GameState {
   GAME_STATE_CALCULATING_TEYAKU,
   GAME_STATE_PLAYER_CHOOSING_FROM_HAND,
   GAME_STATE_PLAYER_CHOOSING_TARGET,
+  GAME_STATE_PLAYER_FROM_DECK,
 } GameState;
 
 struct Game {
diff --git a/play.c b/play.c
index d12c362..f4c66f1 100644
--- a/play.c
+++ b/play.c
@@ -24,3 +24,13 @@ bool valid_play(Hand *field, Card *played, Card *target) {
     return played->month == target->month;
   }
 }
+
+Card *valid_target(Card *active, Hand *field) {
+  for (int i = 0; i < field->count; i++) {
+    if (field->cards[i]->month == active->month) {
+      return field->cards[i];
+    }
+  }
+
+  return NULL;
+}
diff --git a/play.h b/play.h
index 81cfdf1..b67c40b 100644
--- a/play.h
+++ b/play.h
@@ -6,5 +6,6 @@
 #include "card.h"
 
 bool valid_play(Hand *field, Card *played, Card *target);
+Card *valid_target(Card *active, Hand *field);
 
 #endif