Compare commits
	
		
			No commits in common. "5ad8fa1534676ba1b8ce3776a5065be25e45696c" and "6a58fa2601da7612032a48b266ce4f81cf897448" have entirely different histories.
		
	
	
		
			5ad8fa1534
			...
			6a58fa2601
		
	
		
| @ -7,7 +7,6 @@ typedef enum DekiyakuAction { | ||||
|   DEKIYAKU_ACTION_NONE, | ||||
|   DEKIYAKU_ACTION_SAGE, | ||||
|   DEKIYAKU_ACTION_SHOUBU, | ||||
|   DEKIYAKU_ACTION_CANCEL, | ||||
| } DekiyakuAction; | ||||
| 
 | ||||
| typedef enum DekiyakuMeldType { | ||||
|  | ||||
							
								
								
									
										13
									
								
								dialog.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								dialog.c
									
									
									
									
									
								
							| @ -9,21 +9,10 @@ | ||||
| Dialog dialogs[2]; | ||||
| 
 | ||||
| void handle_click_cancel_yes(Game *g) { | ||||
|   g->player.dekiyaku_action = DEKIYAKU_ACTION_CANCEL; | ||||
|   g->state = GAME_STATE_CALCULATING_DEKIYAKU_SCORE; | ||||
| } | ||||
| 
 | ||||
| void handle_click_cancel_no(Game *g) { | ||||
|   g->state = GAME_STATE_CHOOSING_FROM_HAND; | ||||
| } | ||||
| 
 | ||||
| void handle_click_shoubu(Game *g) { | ||||
|   g->player.dekiyaku_action = DEKIYAKU_ACTION_SHOUBU; | ||||
|   g->state = GAME_STATE_CALCULATING_DEKIYAKU_SCORE; | ||||
| } | ||||
| 
 | ||||
| void handle_click_sage(Game *g) { | ||||
|   g->player.dekiyaku_action = DEKIYAKU_ACTION_SAGE; | ||||
| void handle_click_cancel_no(Game *g) { | ||||
|   g->state = GAME_STATE_CHOOSING_FROM_HAND; | ||||
| } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										199
									
								
								game.c
									
									
									
									
									
								
							
							
						
						
									
										199
									
								
								game.c
									
									
									
									
									
								
							| @ -14,19 +14,23 @@ Vector2 mouse_pos; | ||||
| char teyaku_calculation[400]; | ||||
| 
 | ||||
| void initialize_game(Game *g) { | ||||
|   Image cards_image = LoadImage("img/cards.png"); | ||||
|   g->cards_texture = LoadTextureFromImage(cards_image); | ||||
|   UnloadImage(cards_image); | ||||
| 
 | ||||
|   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; | ||||
|   g->player.teyaku.calculated = false; | ||||
|   g->left.teyaku.calculated = false; | ||||
|   g->right.teyaku.calculated = false; | ||||
|   g->player.dekiyaku_score = 0; | ||||
|   g->left.dekiyaku_score = 0; | ||||
|   g->right.dekiyaku_score = 0; | ||||
|   g->kan_value = 12; | ||||
|   g->current_play_from_hand = NULL; | ||||
|   g->current_play_target = NULL; | ||||
|   g->turn_number = -1; | ||||
|   g->dialog = NULL; | ||||
| 
 | ||||
|   init_dialogs(g); | ||||
| 
 | ||||
|   for (int i = 0; i < 48; i++) { | ||||
| @ -70,8 +74,12 @@ void initialize_game(Game *g) { | ||||
|     g->cards[i].move.destination = (Vector2) { 800, 400 }; | ||||
|     g->cards[i].order = i; | ||||
|     g->cards[i].selected = false; | ||||
|     g->deck.cards[i] = &g->cards[i]; | ||||
|     g->deck.count++; | ||||
|   } | ||||
| 
 | ||||
|   shuffle_hand(&g->deck); | ||||
| 
 | ||||
|   g->player.points = 10 * g->kan_value; | ||||
|   g->right.points = 10 * g->kan_value; | ||||
|   g->left.points = 10 * g->kan_value; | ||||
| @ -79,28 +87,34 @@ void initialize_game(Game *g) { | ||||
|   g->right.points_string[0] = '\0'; | ||||
|   g->left.points_string[0] = '\0'; | ||||
| 
 | ||||
|   g->player.teyaku.calculated = false; | ||||
|   g->right.teyaku.calculated = false; | ||||
|   g->left.teyaku.calculated = false; | ||||
| 
 | ||||
|   g->player.hand.count = 0; | ||||
|   g->player.hand.position = (Vector2) { 300, 600 }; | ||||
|   g->player.hand.display_type = HAND_DISPLAY_ROW; | ||||
|   g->right.hand.count = 0; | ||||
|   g->right.hand.position = (Vector2) { 750, 125 }; | ||||
|   g->right.hand.display_type = HAND_DISPLAY_ROW; | ||||
|   g->left.hand.count = 0; | ||||
|   g->left.hand.position = (Vector2) { 50, 125 }; | ||||
|   g->left.hand.display_type = HAND_DISPLAY_ROW; | ||||
|   g->field.count = 0; | ||||
|   g->field.position = (Vector2) { 400, 300 }; | ||||
|   g->field.display_type = HAND_DISPLAY_FIELD; | ||||
|   g->player.scored.count = 0; | ||||
|   g->player.scored.position = (Vector2) { 300, 750 }; | ||||
|   g->player.scored.display_type = HAND_DISPLAY_SCORED; | ||||
|   g->right.scored.count = 0; | ||||
|   g->right.scored.position = (Vector2) { 750, 25 }; | ||||
|   g->right.scored.display_type = HAND_DISPLAY_SCORED; | ||||
|   g->left.scored.count = 0; | ||||
|   g->left.scored.position = (Vector2) { 50, 25 }; | ||||
|   g->left.scored.display_type = HAND_DISPLAY_SCORED; | ||||
| 
 | ||||
|   strcpy(teyaku_calculation, ""); | ||||
| 
 | ||||
|   g->state = GAME_STATE_INITIALIZING; | ||||
|   Image cards_image = LoadImage("img/cards.png"); | ||||
|   g->cards_texture = LoadTextureFromImage(cards_image); | ||||
|   UnloadImage(cards_image); | ||||
|   g->state = GAME_STATE_DEALING; | ||||
| } | ||||
| 
 | ||||
| Player *current_player(Game *g) { | ||||
| @ -112,19 +126,14 @@ Player *current_player(Game *g) { | ||||
|   case 2: | ||||
|     return &g->left; | ||||
|   } | ||||
| 
 | ||||
|   return NULL; | ||||
| } | ||||
| 
 | ||||
| bool is_player_turn(Game *g) { | ||||
|   return current_player(g) == &g->player; | ||||
| } | ||||
| 
 | ||||
| bool stale_calculation = true; | ||||
| void handle_input(Game *g) { | ||||
|   if (IsKeyPressed(KEY_R)) { | ||||
|     g->state = GAME_STATE_INITIALIZING; | ||||
|     return; | ||||
|   } | ||||
|   if (!is_player_turn(g)) return; | ||||
|   if (g->dialog) return dialog_handle_input(g->dialog); | ||||
| 
 | ||||
| @ -195,31 +204,6 @@ void handle_input(Game *g) { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void capture_card_from_field(Game *g, Card *played, Card *target, Hand *hand, Hand *scored) { | ||||
|   // capture all three cards if they play the fourth
 | ||||
|   Card *same_month_card[3]; | ||||
|   int same_month_card_count = 0; | ||||
|   for (int i = 0; i < g->field.count; i++) { | ||||
|     Card *c = g->field.cards[i]; | ||||
|     if (c->month == played->month) { | ||||
|       same_month_card[same_month_card_count++] = c; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   remove_from_hand(hand, played); | ||||
|   add_to_hand(scored, played); | ||||
| 
 | ||||
|   if (same_month_card_count == 3) { | ||||
|     for (int i = 0; i < 3; i++) { | ||||
|       remove_from_hand(&g->field, same_month_card[i]); | ||||
|       add_to_hand(scored, same_month_card[i]); | ||||
|     } | ||||
|   } else { | ||||
|     remove_from_hand(&g->field, target); | ||||
|     add_to_hand(scored, target); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void run_frame_ai_playing(Game *g) { | ||||
|   Hand *hand = ¤t_player(g)->hand; | ||||
|   Hand *scored = ¤t_player(g)->scored; | ||||
| @ -228,64 +212,22 @@ void run_frame_ai_playing(Game *g) { | ||||
|   play.played->visible = true; | ||||
| 
 | ||||
|   if (play.target) { | ||||
|     capture_card_from_field(g, play.played, play.target, hand, scored); | ||||
|     remove_from_hand(hand, play.played); | ||||
|     add_to_hand(scored, play.played); | ||||
|     remove_from_hand(&g->field, play.target); | ||||
|     add_to_hand(scored, play.target); | ||||
|   } else { | ||||
|     remove_from_hand(hand, play.played); | ||||
|     add_to_hand(&g->field, play.played); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void run_frame_initializing(Game *g) { | ||||
|   // TODO: choose the dealer in a more effective manner
 | ||||
|   g->turn_number = -1; | ||||
| 
 | ||||
|   g->player.hand.count = 0; | ||||
|   g->right.hand.count = 0; | ||||
|   g->left.hand.count = 0; | ||||
|   g->field.count = 0; | ||||
|   g->player.scored.count = 0; | ||||
|   g->right.scored.count = 0; | ||||
|   g->left.scored.count = 0; | ||||
|   g->player.dekiyaku_score = 0; | ||||
|   g->left.dekiyaku_score = 0; | ||||
|   g->right.dekiyaku_score = 0; | ||||
| 
 | ||||
|   g->player.dekiyaku_action = DEKIYAKU_ACTION_NONE; | ||||
|   g->right.dekiyaku_action = DEKIYAKU_ACTION_NONE; | ||||
|   g->left.dekiyaku_action = DEKIYAKU_ACTION_NONE; | ||||
| 
 | ||||
|   g->current_play_from_hand = NULL; | ||||
|   g->current_play_target = NULL; | ||||
| 
 | ||||
|   g->deck.count = 0; | ||||
|   for (int i = 0; i < 48; i++) { | ||||
|     Card *c = &g->cards[i]; | ||||
|     c->visible = false; | ||||
|     add_to_hand(&g->deck, c); | ||||
|   } | ||||
| 
 | ||||
|   shuffle_hand(&g->deck); | ||||
| 
 | ||||
| void run_frame_dealing(Game *g) { | ||||
|   // TODO maybe we only need these once per game
 | ||||
|   kan_points_string(g, g->player.points, g->player.points_string); | ||||
|   kan_points_string(g, g->right.points, g->right.points_string); | ||||
|   kan_points_string(g, g->left.points, g->left.points_string); | ||||
|   g->state = GAME_STATE_DEALING; | ||||
| } | ||||
| 
 | ||||
| bool misdeal(Game *g) { | ||||
|   int month_count[12] = { 0,0,0,0,0,0,0,0,0,0,0,0 }; | ||||
|   for (int i = 0; i < g->field.count; i++) { | ||||
|     Card *c = g->field.cards[i]; | ||||
|     month_count[c->month]++; | ||||
|   } | ||||
| 
 | ||||
|   for (int i = 0; i < 12; i++) | ||||
|     if (month_count[i] >= 4) return true; | ||||
| 
 | ||||
|   return 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) { | ||||
| @ -302,14 +244,9 @@ void run_frame_dealing(Game *g) { | ||||
|     deal(&g->deck, &g->right.hand, 3, false); | ||||
|   } else if (g->field.count < 6) { | ||||
|     deal(&g->deck, &g->field, 3, true); | ||||
|   } else { | ||||
|     if (misdeal(g)) { | ||||
|       printf("misdeal\n"); | ||||
|       g->state = GAME_STATE_INITIALIZING; | ||||
|   } else { | ||||
|     g->state = GAME_STATE_CALCULATING_FIELD_MULTIPLIER; | ||||
|   } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void run_frame_calculating_field_multiplier(Game *g) { | ||||
| @ -334,11 +271,21 @@ void run_frame_start_of_turn(Game *g) { | ||||
| } | ||||
| 
 | ||||
| void run_frame_checking_for_cancel(Game *g) { | ||||
|   if (g->dialog) return; | ||||
|   if (is_player_turn(g)) { g->dialog = cancel_dialog(); return; } | ||||
| 
 | ||||
|   if (current_player(g)->dekiyaku_action == DEKIYAKU_ACTION_SAGE) { | ||||
|     if (is_player_turn(g)) { | ||||
|       g->dialog = cancel_dialog(); | ||||
|       // check for player canceling
 | ||||
|       // if they do:
 | ||||
|       // g->state = GAME_STATE_CALCULATING_DEKIYAKU_SCORE;
 | ||||
|       // else
 | ||||
|       g->state = GAME_STATE_CHOOSING_FROM_HAND; | ||||
|     } else { | ||||
|       // TODO: the AI might want to cancel at some point
 | ||||
|       // AI decides whether to cancel or not
 | ||||
|       // if they do:
 | ||||
|       // g->state = GAME_STATE_CALCULATING_DEKIYAKU_SCORE;
 | ||||
|       // else
 | ||||
|       g->state = GAME_STATE_CHOOSING_FROM_HAND; | ||||
|     } | ||||
|   } else { | ||||
| @ -386,16 +333,10 @@ void run_frame_choosing_target(Game *g) { | ||||
|   if (g->current_play_from_hand) { | ||||
|     if (g->current_play_target) { | ||||
|       g->current_play_from_hand->selected = false; | ||||
| 
 | ||||
|       capture_card_from_field( | ||||
| 			      g, | ||||
| 			      g->current_play_from_hand, | ||||
| 			      g->current_play_target, | ||||
| 			      &g->player.hand, | ||||
| 			      &g->player.scored | ||||
| 			      ); | ||||
| 
 | ||||
| 
 | ||||
|       remove_from_hand(&g->player.hand, g->current_play_from_hand); | ||||
|       add_to_hand(&g->player.scored, g->current_play_from_hand); | ||||
|       remove_from_hand(&g->field, g->current_play_target); | ||||
|       add_to_hand(&g->player.scored, g->current_play_target); | ||||
|       g->current_play_from_hand = NULL; | ||||
|       g->current_play_target = NULL; | ||||
|     } else { | ||||
| @ -415,7 +356,10 @@ void run_frame_playing_from_deck(Game *g) { | ||||
|   if (top_card->visible) { | ||||
|     Card *target = valid_target(top_card, &g->field); | ||||
|     if (target) { | ||||
|       capture_card_from_field(g, top_card, target, &g->deck, to_hand); | ||||
|       remove_from_hand(&g->field, target); | ||||
|       add_to_hand(to_hand, target); | ||||
|       remove_from_hand(&g->deck, top_card); | ||||
|       add_to_hand(to_hand, top_card); | ||||
|     } else { | ||||
|       remove_from_hand(&g->deck, top_card); | ||||
|       add_to_hand(&g->field, top_card); | ||||
| @ -436,13 +380,8 @@ void run_frame_checking_for_new_dekiyaku(Game *g) { | ||||
|   int new_score = dekiyaku_score(&cp->dekiyaku); | ||||
|   if (new_score != cp->dekiyaku_score) { | ||||
|     cp->dekiyaku_score = new_score; | ||||
|     if (is_player_turn(g)) { | ||||
|       g->dialog = shoubu_dialog(); | ||||
|     } else { | ||||
|       // TODO: better AI
 | ||||
|       cp->dekiyaku_action = DEKIYAKU_ACTION_SHOUBU; | ||||
|       g->state = GAME_STATE_CALCULATING_DEKIYAKU_SCORE; | ||||
|     } | ||||
|     cp->dekiyaku_action = DEKIYAKU_ACTION_NONE; | ||||
|     g->state = GAME_STATE_SELECTING_DEKIYAKU_ACTION; | ||||
|   } else { | ||||
|     g->state = GAME_STATE_START_OF_TURN; | ||||
|   } | ||||
| @ -453,7 +392,8 @@ void run_frame_selecting_dekiyaku_action(Game *g) { | ||||
|     if (g->player.dekiyaku_action != DEKIYAKU_ACTION_NONE) { | ||||
|       g->state = GAME_STATE_CALCULATING_DEKIYAKU_SCORE; | ||||
|     } else { | ||||
|       g->dialog = shoubu_dialog(); | ||||
|       printf("Hey you can't choose a dekiyaku action yet, sorry\n"); | ||||
|       g->player.dekiyaku_action = DEKIYAKU_ACTION_SAGE; | ||||
|     } | ||||
|   } else { | ||||
|     // TODO: better AI
 | ||||
| @ -498,35 +438,23 @@ void run_frame_calculating_scores(Game *g) { | ||||
| } | ||||
| 
 | ||||
| void run_frame_calculating_dekiyaku_score(Game *g) { | ||||
|   printf("Somebody won with dekiyaku. Cool.\n"); fflush(stdout); | ||||
|   printf("Somebody won with dekiyaku. Cool.\n"); | ||||
|   g->state = GAME_STATE_INITIALIZING; | ||||
| } | ||||
| 
 | ||||
| void move_cards(Game *g) { | ||||
|   float delta = GetFrameTime(); | ||||
|   for (int i = 0; i < 48; i++) { | ||||
|     move_position(&g->cards[i].move, delta); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| bool done_moving(Game *g) { | ||||
|   for (int i = 0; i < 48; i++) { | ||||
|     if (!card_done_moving(&g->cards[i])) return false; | ||||
|   } | ||||
| 
 | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| void run_frame(Game *g) { | ||||
|   handle_input(g); | ||||
|   if (g->dialog) return; | ||||
| 
 | ||||
|   move_cards(g); | ||||
|   if (!done_moving(g)) return; | ||||
|   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; | ||||
| 
 | ||||
|   switch (g->state) { | ||||
|   case GAME_STATE_INITIALIZING: | ||||
|     run_frame_initializing(g); | ||||
|     return; | ||||
|   case GAME_STATE_DEALING: | ||||
|     run_frame_dealing(g); | ||||
| @ -575,7 +503,6 @@ void draw_frame(Game *g) { | ||||
|   } | ||||
| 
 | ||||
|   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); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user