Compare commits
	
		
			6 Commits
		
	
	
		
			a836a9e5e4
			...
			879e01a32b
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 879e01a32b | |||
| 6ca6bf06a9 | |||
| 1e8b280271 | |||
| e8a1389cda | |||
| 76da2656b4 | |||
| a0f669b357 | 
							
								
								
									
										8
									
								
								card.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								card.c
									
									
									
									
									
								
							| @ -104,7 +104,7 @@ int first_open_spot(Hand *h) { | |||||||
|   return fos; |   return fos; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void add_to_hand(Hand *h, Card *c) { | void add_to_hand(Hand *h, Card *c, float deal_speed) { | ||||||
|   c->order = first_open_spot(h); |   c->order = first_open_spot(h); | ||||||
|   h->cards[h->count] = c; |   h->cards[h->count] = c; | ||||||
| 
 | 
 | ||||||
| @ -131,7 +131,7 @@ void add_to_hand(Hand *h, Card *c) { | |||||||
|   } |   } | ||||||
|   c->move.curve = CURVE_EASE_IN_OUT; |   c->move.curve = CURVE_EASE_IN_OUT; | ||||||
|   c->move.current_time = 0.; |   c->move.current_time = 0.; | ||||||
|   c->move.end_time = 0.2; |   c->move.end_time = deal_speed; | ||||||
| 
 | 
 | ||||||
|   h->count++; |   h->count++; | ||||||
| } | } | ||||||
| @ -140,11 +140,11 @@ bool card_done_moving(Card *c) { | |||||||
|   return c->move.current_time > c->move.end_time; |   return c->move.current_time > c->move.end_time; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void deal(Hand *from, Hand *to, int count, bool up) { | void deal(Hand *from, Hand *to, int count, bool up, float deal_speed) { | ||||||
|   for (int i = 0; i < count; i++) { |   for (int i = 0; i < count; i++) { | ||||||
|     Card *c = from->cards[from->count - 1]; |     Card *c = from->cards[from->count - 1]; | ||||||
|     c->visible = up; |     c->visible = up; | ||||||
|     add_to_hand(to, c); |     add_to_hand(to, c, deal_speed); | ||||||
|     from->count--; |     from->count--; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								card.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								card.h
									
									
									
									
									
								
							| @ -76,9 +76,9 @@ struct Hand { | |||||||
| 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 shuffle_hand(Hand *h); | ||||||
| void deal(Hand *from, Hand *to, int count, bool up); | void deal(Hand *from, Hand *to, int count, bool up, float deal_speed); | ||||||
| void remove_from_hand(Hand *h, Card *c); | void remove_from_hand(Hand *h, Card *c); | ||||||
| void add_to_hand(Hand *h, Card *c); | void add_to_hand(Hand *h, Card *c, float deal_speed); | ||||||
| bool card_done_moving(Card *c); | bool card_done_moving(Card *c); | ||||||
| Rectangle next_card_position(Hand *h); | Rectangle next_card_position(Hand *h); | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										63
									
								
								dialog.c
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								dialog.c
									
									
									
									
									
								
							| @ -45,6 +45,29 @@ void handle_click_quit(Game *g) { | |||||||
|   g->should_close = true; |   g->should_close = true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void handle_click_claim_set_teyaku(Game *g) { | ||||||
|  |   g->player.teyaku.chaff = CHAFF_TEYAKU_NONE; | ||||||
|  |   teyaku_to_string(&g->player.teyaku, g->player.teyaku_string); | ||||||
|  |   g->state = GAME_STATE_START_OF_TURN; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void handle_click_claim_chaff_teyaku(Game *g) { | ||||||
|  |   g->player.teyaku.set = SET_TEYAKU_NONE; | ||||||
|  |   teyaku_to_string(&g->player.teyaku, g->player.teyaku_string); | ||||||
|  |   g->state = GAME_STATE_START_OF_TURN; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void handle_click_claim_both_teyaku(Game *g) { | ||||||
|  |   g->state = GAME_STATE_START_OF_TURN; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void handle_click_dont_claim_teyaku(Game *g) { | ||||||
|  |   (&g->player.teyaku)->chaff = CHAFF_TEYAKU_NONE; | ||||||
|  |   g->player.teyaku.set = SET_TEYAKU_NONE; | ||||||
|  |   teyaku_to_string(&g->player.teyaku, g->player.teyaku_string); | ||||||
|  |   g->state = GAME_STATE_START_OF_TURN; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void init_dialogs(Game *g) { | void init_dialogs(Game *g) { | ||||||
|   Dialog *cancel_dialog = &dialogs[0]; |   Dialog *cancel_dialog = &dialogs[0]; | ||||||
|   cancel_dialog->text_count = 1; |   cancel_dialog->text_count = 1; | ||||||
| @ -134,6 +157,36 @@ void init_dialogs(Game *g) { | |||||||
|   strcpy(dekiyaku_end_of_round_dialog->options[0].text, "Okay"); |   strcpy(dekiyaku_end_of_round_dialog->options[0].text, "Okay"); | ||||||
|   dekiyaku_end_of_round_dialog->options[0].color = GREEN; |   dekiyaku_end_of_round_dialog->options[0].color = GREEN; | ||||||
|   dekiyaku_end_of_round_dialog->options[0].handle = &handle_click_ok_end_of_round; |   dekiyaku_end_of_round_dialog->options[0].handle = &handle_click_ok_end_of_round; | ||||||
|  | 
 | ||||||
|  |   Dialog *teyaku_dialog = &dialogs[5]; | ||||||
|  |   teyaku_dialog->text_count = 3; | ||||||
|  |   teyaku_dialog->text[0] = malloc(200); | ||||||
|  |   teyaku_dialog->text[1] = malloc(200); | ||||||
|  |   teyaku_dialog->text[2] = malloc(200); | ||||||
|  |   strcpy(teyaku_dialog->text[0], "You can claim some teyaku"); | ||||||
|  |   teyaku_dialog->text_color = BLACK; | ||||||
|  |   teyaku_dialog->options_count = 4; | ||||||
|  |   teyaku_dialog->game = g; | ||||||
|  | 
 | ||||||
|  |   teyaku_dialog->options[0].text = malloc(50); | ||||||
|  |   strcpy(teyaku_dialog->options[0].text, "Claim Set Teyaku"); | ||||||
|  |   teyaku_dialog->options[0].color = SKYBLUE; | ||||||
|  |   teyaku_dialog->options[0].handle = &handle_click_claim_set_teyaku; | ||||||
|  | 
 | ||||||
|  |   teyaku_dialog->options[1].text = malloc(50); | ||||||
|  |   strcpy(teyaku_dialog->options[1].text, "Claim Chaff Teyaku"); | ||||||
|  |   teyaku_dialog->options[1].color = SKYBLUE; | ||||||
|  |   teyaku_dialog->options[1].handle = &handle_click_claim_chaff_teyaku; | ||||||
|  |    | ||||||
|  |   teyaku_dialog->options[2].text = malloc(50); | ||||||
|  |   strcpy(teyaku_dialog->options[2].text, "Claim Both Teyaku"); | ||||||
|  |   teyaku_dialog->options[2].color = GREEN; | ||||||
|  |   teyaku_dialog->options[2].handle = &handle_click_claim_both_teyaku; | ||||||
|  | 
 | ||||||
|  |   teyaku_dialog->options[3].text = malloc(50); | ||||||
|  |   strcpy(teyaku_dialog->options[3].text, "Don't Claim"); | ||||||
|  |   teyaku_dialog->options[3].color = RED; | ||||||
|  |   teyaku_dialog->options[3].handle = &handle_click_dont_claim_teyaku; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void cancel_dialog(Game *g) { g->dialog = &dialogs[0]; } | void cancel_dialog(Game *g) { g->dialog = &dialogs[0]; } | ||||||
| @ -141,14 +194,24 @@ void shoubu_dialog(Game *g) { g->dialog = &dialogs[1]; } | |||||||
| void no_dekiyaku_end_of_round_dialog(Game *g) { g->dialog = &dialogs[2]; } | void no_dekiyaku_end_of_round_dialog(Game *g) { g->dialog = &dialogs[2]; } | ||||||
| void end_of_game_dialog(Game *g) { g->dialog = &dialogs[3]; } | void end_of_game_dialog(Game *g) { g->dialog = &dialogs[3]; } | ||||||
| void dekiyaku_end_of_round_dialog(Game *g) { g->dialog = &dialogs[4]; } | void dekiyaku_end_of_round_dialog(Game *g) { g->dialog = &dialogs[4]; } | ||||||
|  | void teyaku_dialog(Game *g) { g->dialog = &dialogs[5]; } | ||||||
| 
 | 
 | ||||||
| Rectangle dialog_option_outer_rectangle(Dialog *d, int i) { | Rectangle dialog_option_outer_rectangle(Dialog *d, int i) { | ||||||
|  |   if (d->options_count < 4) { | ||||||
|     return (Rectangle) { |     return (Rectangle) { | ||||||
|       ((960 * (i + 1)) / (d->options_count + 1)) - 10 + 200, |       ((960 * (i + 1)) / (d->options_count + 1)) - 10 + 200, | ||||||
|       500, |       500, | ||||||
|       MeasureText(d->options[i].text, DIALOG_OPTION_FONT_SIZE) + 20, |       MeasureText(d->options[i].text, DIALOG_OPTION_FONT_SIZE) + 20, | ||||||
|       40, |       40, | ||||||
|     }; |     }; | ||||||
|  |   } else { | ||||||
|  |     return (Rectangle) { | ||||||
|  |       ((960 * (i % 2)) / ((d->options_count / 2) + 1)) - 10 + 250, | ||||||
|  |       500 + ((i / 2) * 50), | ||||||
|  |       MeasureText(d->options[i].text, DIALOG_OPTION_FONT_SIZE) + 20, | ||||||
|  |       40, | ||||||
|  |     }; | ||||||
|  |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Rectangle dialog_option_inner_rectangle(Dialog *d, int i) { | Rectangle dialog_option_inner_rectangle(Dialog *d, int i) { | ||||||
|  | |||||||
							
								
								
									
										3
									
								
								dialog.h
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								dialog.h
									
									
									
									
									
								
							| @ -21,7 +21,7 @@ struct Dialog { | |||||||
|   char *text[8]; |   char *text[8]; | ||||||
|   int text_count; |   int text_count; | ||||||
|   Color text_color; |   Color text_color; | ||||||
|   DialogOption options[3]; |   DialogOption options[4]; | ||||||
|   int options_count; |   int options_count; | ||||||
|   Game *game; |   Game *game; | ||||||
| }; | }; | ||||||
| @ -32,6 +32,7 @@ void shoubu_dialog(Game *g); | |||||||
| void no_dekiyaku_end_of_round_dialog(Game *g); | void no_dekiyaku_end_of_round_dialog(Game *g); | ||||||
| void end_of_game_dialog(Game *g); | void end_of_game_dialog(Game *g); | ||||||
| void dekiyaku_end_of_round_dialog(Game *g); | void dekiyaku_end_of_round_dialog(Game *g); | ||||||
|  | void teyaku_dialog(Game *g); | ||||||
| void dialog_draw(Dialog *d); | void dialog_draw(Dialog *d); | ||||||
| void dialog_handle_input(Dialog *d); | void dialog_handle_input(Dialog *d); | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										97
									
								
								game.c
									
									
									
									
									
								
							
							
						
						
									
										97
									
								
								game.c
									
									
									
									
									
								
							| @ -1,4 +1,5 @@ | |||||||
| #include <string.h> | #include <string.h> | ||||||
|  | #include <stdlib.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| 
 | 
 | ||||||
| #include "game.h" | #include "game.h" | ||||||
| @ -24,9 +25,15 @@ void initialize_game(Game *g) { | |||||||
|   g->should_close = false; |   g->should_close = false; | ||||||
|   g->state = GAME_STATE_INITIALIZING; |   g->state = GAME_STATE_INITIALIZING; | ||||||
|   g->field_multiplier = NULL; |   g->field_multiplier = NULL; | ||||||
|   g->kan_value = 12; |  | ||||||
|   g->dialog = NULL; |   g->dialog = NULL; | ||||||
| 
 | 
 | ||||||
|  |   g->kan_value = 12; | ||||||
|  |   g->number_of_rounds = 1; | ||||||
|  |   g->black_card_backs = true; | ||||||
|  |   g->deal_speed = 0.2; | ||||||
|  |   g->options = malloc(sizeof(Options)); | ||||||
|  |   load_options_from_game(g); | ||||||
|  | 
 | ||||||
|   init_dialogs(g); |   init_dialogs(g); | ||||||
| 
 | 
 | ||||||
|   for (int i = 0; i < 48; i++) { |   for (int i = 0; i < 48; i++) { | ||||||
| @ -78,6 +85,9 @@ void initialize_game(Game *g) { | |||||||
|   g->player.points_string[0] = '\0'; |   g->player.points_string[0] = '\0'; | ||||||
|   g->right.points_string[0] = '\0'; |   g->right.points_string[0] = '\0'; | ||||||
|   g->left.points_string[0] = '\0'; |   g->left.points_string[0] = '\0'; | ||||||
|  |   g->player.teyaku_string[0] = '\0'; | ||||||
|  |   g->right.teyaku_string[0] = '\0'; | ||||||
|  |   g->left.teyaku_string[0] = '\0'; | ||||||
|   g->player.name = "Player"; |   g->player.name = "Player"; | ||||||
|   g->right.name = "Right"; |   g->right.name = "Right"; | ||||||
|   g->left.name = "Left"; |   g->left.name = "Left"; | ||||||
| @ -132,9 +142,8 @@ void initialize_game(Game *g) { | |||||||
|     break; |     break; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   g->number_of_rounds = 1; |  | ||||||
|   g->current_round = 0; |   g->current_round = 0; | ||||||
|   g->state = GAME_STATE_INITIALIZING; |   g->state = GAME_STATE_OPTIONS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Player *current_player(Game *g) { | Player *current_player(Game *g) { | ||||||
| @ -155,15 +164,19 @@ bool is_player_turn(Game *g) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void handle_input(Game *g) { | void handle_input(Game *g) { | ||||||
|   if (IsKeyPressed(KEY_R)) { |   if (g->state == GAME_STATE_OPTIONS) { | ||||||
|     g->state = GAME_STATE_INITIALIZING; |     return options_handle_input(g); | ||||||
|     return; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (g->dialog) { |   if (g->dialog) { | ||||||
|     return dialog_handle_input(g->dialog); |     return dialog_handle_input(g->dialog); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   if (IsKeyPressed(KEY_R)) { | ||||||
|  |     g->state = GAME_STATE_INITIALIZING; | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   if (!is_player_turn(g)) return; |   if (!is_player_turn(g)) return; | ||||||
| 
 | 
 | ||||||
|   switch (g->state) { |   switch (g->state) { | ||||||
| @ -262,16 +275,16 @@ void capture_card_from_field(Game *g, Card *played, Card *target, Hand *hand, Ha | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   remove_from_hand(hand, played); |   remove_from_hand(hand, played); | ||||||
|   add_to_hand(scored, played); |   add_to_hand(scored, played, g->deal_speed); | ||||||
| 
 | 
 | ||||||
|   if (same_month_card_count == 3) { |   if (same_month_card_count == 3) { | ||||||
|     for (int i = 0; i < 3; i++) { |     for (int i = 0; i < 3; i++) { | ||||||
|       remove_from_hand(&g->field, same_month_card[i]); |       remove_from_hand(&g->field, same_month_card[i]); | ||||||
|       add_to_hand(scored, same_month_card[i]); |       add_to_hand(scored, same_month_card[i], g->deal_speed); | ||||||
|     } |     } | ||||||
|   } else { |   } else { | ||||||
|     remove_from_hand(&g->field, target); |     remove_from_hand(&g->field, target); | ||||||
|     add_to_hand(scored, target); |     add_to_hand(scored, target, g->deal_speed); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -286,7 +299,7 @@ void run_frame_ai_playing(Game *g) { | |||||||
|     capture_card_from_field(g, play.played, play.target, hand, scored); |     capture_card_from_field(g, play.played, play.target, hand, scored); | ||||||
|   } else { |   } else { | ||||||
|     remove_from_hand(hand, play.played); |     remove_from_hand(hand, play.played); | ||||||
|     add_to_hand(&g->field, play.played); |     add_to_hand(&g->field, play.played, g->deal_speed); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -308,6 +321,10 @@ void run_frame_initializing(Game *g) { | |||||||
|   g->right.dekiyaku_action = DEKIYAKU_ACTION_NONE; |   g->right.dekiyaku_action = DEKIYAKU_ACTION_NONE; | ||||||
|   g->left.dekiyaku_action = DEKIYAKU_ACTION_NONE; |   g->left.dekiyaku_action = DEKIYAKU_ACTION_NONE; | ||||||
| 
 | 
 | ||||||
|  |   strcpy(g->player.teyaku_string, ""); | ||||||
|  |   strcpy(g->right.teyaku_string, ""); | ||||||
|  |   strcpy(g->left.teyaku_string, ""); | ||||||
|  | 
 | ||||||
|   g->current_play_from_hand = NULL; |   g->current_play_from_hand = NULL; | ||||||
|   g->current_play_target = NULL; |   g->current_play_target = NULL; | ||||||
| 
 | 
 | ||||||
| @ -315,7 +332,7 @@ void run_frame_initializing(Game *g) { | |||||||
|   for (int i = 0; i < 48; i++) { |   for (int i = 0; i < 48; i++) { | ||||||
|     Card *c = &g->cards[i]; |     Card *c = &g->cards[i]; | ||||||
|     c->visible = false; |     c->visible = false; | ||||||
|     add_to_hand(&g->deck, c); |     add_to_hand(&g->deck, c, g->deal_speed); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   shuffle_hand(&g->deck); |   shuffle_hand(&g->deck); | ||||||
| @ -342,15 +359,15 @@ bool misdeal(Game *g) { | |||||||
| 
 | 
 | ||||||
| void run_frame_dealing(Game *g) { | void run_frame_dealing(Game *g) { | ||||||
|   if (current_player(g)->hand.count < 4) { |   if (current_player(g)->hand.count < 4) { | ||||||
|     deal(&g->deck, ¤t_player(g)->hand, 4, is_player_turn(g)); |     deal(&g->deck, ¤t_player(g)->hand, 4, is_player_turn(g), g->deal_speed); | ||||||
|     g->turn_number++; |     g->turn_number++; | ||||||
|   } else if (g->field.count < 3) { |   } else if (g->field.count < 3) { | ||||||
|     deal(&g->deck, &g->field, 3, true); |     deal(&g->deck, &g->field, 3, true, g->deal_speed); | ||||||
|   } else if (current_player(g)->hand.count < 7) { |   } else if (current_player(g)->hand.count < 7) { | ||||||
|     deal(&g->deck, ¤t_player(g)->hand, 3, is_player_turn(g)); |     deal(&g->deck, ¤t_player(g)->hand, 3, is_player_turn(g), g->deal_speed); | ||||||
|     g->turn_number++; |     g->turn_number++; | ||||||
|   } else if (g->field.count < 6) { |   } else if (g->field.count < 6) { | ||||||
|     deal(&g->deck, &g->field, 3, true); |     deal(&g->deck, &g->field, 3, true, g->deal_speed); | ||||||
|   } else { |   } else { | ||||||
|     if (misdeal(g)) { |     if (misdeal(g)) { | ||||||
|       printf("misdeal\n"); |       printf("misdeal\n"); | ||||||
| @ -369,9 +386,19 @@ void run_frame_calculating_field_multiplier(Game *g) { | |||||||
| 
 | 
 | ||||||
| void run_frame_calculating_teyaku(Game *g) { | void run_frame_calculating_teyaku(Game *g) { | ||||||
|   calculate_teyaku(g->player.hand, &g->player.teyaku); |   calculate_teyaku(g->player.hand, &g->player.teyaku); | ||||||
|  |   teyaku_to_string(&g->player.teyaku, g->player.teyaku_string); | ||||||
|   calculate_teyaku(g->right.hand, &g->right.teyaku); |   calculate_teyaku(g->right.hand, &g->right.teyaku); | ||||||
|  |   teyaku_to_string(&g->right.teyaku, g->right.teyaku_string); | ||||||
|   calculate_teyaku(g->left.hand, &g->left.teyaku); |   calculate_teyaku(g->left.hand, &g->left.teyaku); | ||||||
|  |   teyaku_to_string(&g->left.teyaku, g->left.teyaku_string); | ||||||
|  | 
 | ||||||
|  |   if (teyaku_points(&g->player.teyaku) > 0) { | ||||||
|  |     teyaku_dialog(g); | ||||||
|  |     set_teyaku_to_string(&g->player.teyaku, g->dialog->text[1]); | ||||||
|  |     chaff_teyaku_to_string(&g->player.teyaku, g->dialog->text[2]); | ||||||
|  |   } else { | ||||||
|     g->state = GAME_STATE_START_OF_TURN; |     g->state = GAME_STATE_START_OF_TURN; | ||||||
|  |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void run_frame_start_of_turn(Game *g) { | void run_frame_start_of_turn(Game *g) { | ||||||
| @ -451,7 +478,7 @@ void run_frame_choosing_target(Game *g) { | |||||||
|     } else { |     } else { | ||||||
|       g->current_play_from_hand->selected = false; |       g->current_play_from_hand->selected = false; | ||||||
|       remove_from_hand(&g->player.hand, g->current_play_from_hand); |       remove_from_hand(&g->player.hand, g->current_play_from_hand); | ||||||
|       add_to_hand(&g->field, g->current_play_from_hand); |       add_to_hand(&g->field, g->current_play_from_hand, g->deal_speed); | ||||||
|       g->current_play_from_hand = NULL; |       g->current_play_from_hand = NULL; | ||||||
|     } |     } | ||||||
|     g->state = GAME_STATE_SHOWING_CARD_FROM_DECK; |     g->state = GAME_STATE_SHOWING_CARD_FROM_DECK; | ||||||
| @ -461,7 +488,7 @@ void run_frame_choosing_target(Game *g) { | |||||||
| void run_frame_showing_card_from_deck(Game *g) { | void run_frame_showing_card_from_deck(Game *g) { | ||||||
|   Card *top_card = g->deck.cards[g->deck.count - 1]; |   Card *top_card = g->deck.cards[g->deck.count - 1]; | ||||||
|   remove_from_hand(&g->deck, top_card); |   remove_from_hand(&g->deck, top_card); | ||||||
|   add_to_hand(&g->deck, top_card); |   add_to_hand(&g->deck, top_card, g->deal_speed); | ||||||
|   top_card->visible = true; |   top_card->visible = true; | ||||||
|   top_card->move.end_time = 0.3; |   top_card->move.end_time = 0.3; | ||||||
|   top_card->move.destination.y = top_card->move.destination.y + 150; |   top_card->move.destination.y = top_card->move.destination.y + 150; | ||||||
| @ -481,7 +508,7 @@ void run_frame_playing_from_deck(Game *g) { | |||||||
|     g->state = GAME_STATE_CHECKING_FOR_NEW_DEKIYAKU; |     g->state = GAME_STATE_CHECKING_FOR_NEW_DEKIYAKU; | ||||||
|   } else if(target_count == 0) { |   } else if(target_count == 0) { | ||||||
|     remove_from_hand(&g->deck, top_card); |     remove_from_hand(&g->deck, top_card); | ||||||
|     add_to_hand(&g->field, top_card); |     add_to_hand(&g->field, top_card, g->deal_speed); | ||||||
|     g->state = GAME_STATE_CHECKING_FOR_NEW_DEKIYAKU; |     g->state = GAME_STATE_CHECKING_FOR_NEW_DEKIYAKU; | ||||||
|   } else { |   } else { | ||||||
|     g->state = GAME_STATE_CHOOSING_TARGET_FROM_DECK; |     g->state = GAME_STATE_CHOOSING_TARGET_FROM_DECK; | ||||||
| @ -543,6 +570,19 @@ void run_frame_selecting_dekiyaku_action(Game *g) { | |||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void pay_teyaku_to_player(Game *g, Player *p) { | ||||||
|  |   int points = teyaku_points(&p->teyaku); | ||||||
|  |   transfer_kan(g, &p->points, &g->player.points, points); | ||||||
|  |   transfer_kan(g, &p->points, &g->right.points, points); | ||||||
|  |   transfer_kan(g, &p->points, &g->left.points, points); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void pay_teyaku(Game *g) { | ||||||
|  |   pay_teyaku_to_player(g, &g->player); | ||||||
|  |   pay_teyaku_to_player(g, &g->right); | ||||||
|  |   pay_teyaku_to_player(g, &g->left); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void run_frame_calculating_scores(Game *g) { | void run_frame_calculating_scores(Game *g) { | ||||||
|   no_dekiyaku_end_of_round_dialog(g); |   no_dekiyaku_end_of_round_dialog(g); | ||||||
| 
 | 
 | ||||||
| @ -599,6 +639,7 @@ void run_frame_calculating_scores(Game *g) { | |||||||
|       if (hp[1] > hp[2]) g->dealer = &g->right; |       if (hp[1] > hp[2]) g->dealer = &g->right; | ||||||
|       else g->dealer = &g->left; |       else g->dealer = &g->left; | ||||||
|     } |     } | ||||||
|  |     pay_teyaku(g); | ||||||
|     break; |     break; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @ -639,8 +680,9 @@ void run_frame_calculating_dekiyaku_score(Game *g) { | |||||||
|   } else if (g->left.dekiyaku_action == DEKIYAKU_ACTION_CANCEL || g->left.dekiyaku_action == DEKIYAKU_ACTION_SHOUBU) { |   } else if (g->left.dekiyaku_action == DEKIYAKU_ACTION_CANCEL || g->left.dekiyaku_action == DEKIYAKU_ACTION_SHOUBU) { | ||||||
|     calculate_dekiyaku_score(g, &g->left); |     calculate_dekiyaku_score(g, &g->left); | ||||||
|   } else { |   } else { | ||||||
|     // Hands are exhausted
 |     // TODO: Hands are exhausted
 | ||||||
|   } |   } | ||||||
|  |   pay_teyaku(g); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void run_frame_end_of_round(Game *g) { | void run_frame_end_of_round(Game *g) { | ||||||
| @ -788,6 +830,8 @@ void run_frame(Game *g) { | |||||||
|   case GAME_STATE_NEW_GAME: |   case GAME_STATE_NEW_GAME: | ||||||
|     run_frame_new_game(g); |     run_frame_new_game(g); | ||||||
|     break; |     break; | ||||||
|  |   case GAME_STATE_OPTIONS: | ||||||
|  |     break; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -820,6 +864,12 @@ void draw_frame(Game *g) { | |||||||
| 
 | 
 | ||||||
|   draw_cards(g); |   draw_cards(g); | ||||||
| 
 | 
 | ||||||
|  |   if (g->state == GAME_STATE_OPTIONS) { | ||||||
|  |     options_draw(g); | ||||||
|  |     EndDrawing(); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   if (g->state == GAME_STATE_DEALING) { |   if (g->state == GAME_STATE_DEALING) { | ||||||
|     DrawText("Dealing....", 60, 385, 40, BLACK); |     DrawText("Dealing....", 60, 385, 40, BLACK); | ||||||
|   } else if (g->field_multiplier) { |   } else if (g->field_multiplier) { | ||||||
| @ -827,11 +877,14 @@ void draw_frame(Game *g) { | |||||||
|     DrawText(g->field_multiplier->explanation, 60, 445, 20, BLACK); |     DrawText(g->field_multiplier->explanation, 60, 445, 20, BLACK); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   DrawText(g->player.points_string, 40, 700, 20, BLACK); |   DrawText(g->player.points_string, 40, 650, 20, BLACK); | ||||||
|   DrawText(g->right.points_string, 40, 750, 20, BLACK); |   DrawText(g->player.teyaku_string, 40, 680, 20, BLACK); | ||||||
|  |   DrawText(g->right.points_string, 40, 725, 20, BLACK); | ||||||
|  |   DrawText(g->right.teyaku_string, 40, 755, 20, BLACK); | ||||||
|   DrawText(g->left.points_string, 40, 800, 20, BLACK); |   DrawText(g->left.points_string, 40, 800, 20, BLACK); | ||||||
|  |   DrawText(g->left.teyaku_string, 40, 830, 20, BLACK); | ||||||
| 
 | 
 | ||||||
|   char round_text[20]; |   char round_text[40]; | ||||||
|   if (g->current_round < g->number_of_rounds) |   if (g->current_round < g->number_of_rounds) | ||||||
|     sprintf(round_text, "Round %d / %d", g->current_round+1, g->number_of_rounds); |     sprintf(round_text, "Round %d / %d", g->current_round+1, g->number_of_rounds); | ||||||
|   else |   else | ||||||
|  | |||||||
							
								
								
									
										9
									
								
								game.h
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								game.h
									
									
									
									
									
								
							| @ -12,6 +12,7 @@ typedef struct Game Game; | |||||||
| #include "points.h" | #include "points.h" | ||||||
| #include "player.h" | #include "player.h" | ||||||
| #include "dialog.h" | #include "dialog.h" | ||||||
|  | #include "options.h" | ||||||
| 
 | 
 | ||||||
| typedef enum GameState { | typedef enum GameState { | ||||||
|   GAME_STATE_INITIALIZING, |   GAME_STATE_INITIALIZING, | ||||||
| @ -33,6 +34,7 @@ typedef enum GameState { | |||||||
|   GAME_STATE_END_OF_GAME, |   GAME_STATE_END_OF_GAME, | ||||||
|   GAME_STATE_NEW_GAME, |   GAME_STATE_NEW_GAME, | ||||||
|   GAME_STATE_TITLE_SCREEN, |   GAME_STATE_TITLE_SCREEN, | ||||||
|  |   GAME_STATE_OPTIONS, | ||||||
| } GameState; | } GameState; | ||||||
| 
 | 
 | ||||||
| struct Game { | struct Game { | ||||||
| @ -43,14 +45,17 @@ struct Game { | |||||||
|   Hand deck, field; |   Hand deck, field; | ||||||
|   FieldMultiplier *field_multiplier; |   FieldMultiplier *field_multiplier; | ||||||
|   Card *current_play_from_hand, *current_play_target; |   Card *current_play_from_hand, *current_play_target; | ||||||
|   int kan_value; |  | ||||||
|   Player player, right, left; |   Player player, right, left; | ||||||
|   int temp_points; |   int temp_points; | ||||||
|   int turn_number; |   int turn_number; | ||||||
|   Dialog *dialog; |   Dialog *dialog; | ||||||
|   Player *dealer; |   Player *dealer; | ||||||
|   int number_of_rounds; |  | ||||||
|   int current_round; |   int current_round; | ||||||
|  |   int kan_value; | ||||||
|  |   int number_of_rounds; | ||||||
|  |   bool black_card_backs; | ||||||
|  |   float deal_speed; | ||||||
|  |   Options *options; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| void initialize_game(Game *g); | void initialize_game(Game *g); | ||||||
|  | |||||||
							
								
								
									
										129
									
								
								options.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								options.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,129 @@ | |||||||
|  | #include "options.h" | ||||||
|  | 
 | ||||||
|  | int kan_value_from_index(int index) { return index == 0 ? 10 : 12; } | ||||||
|  | int index_from_kan_value(int kan_value) { return kan_value == 10 ? 0 : 1; } | ||||||
|  | int number_of_rounds_from_index(int index) { | ||||||
|  |   int r[] = { 1, 3, 6, 12 }; | ||||||
|  |   return r[index]; | ||||||
|  | } | ||||||
|  | int index_from_number_of_rounds(int number_of_rounds) { | ||||||
|  |   int r[] = { 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 3 }; | ||||||
|  |   return r[number_of_rounds]; | ||||||
|  | } | ||||||
|  | float deal_speed_from_index(int index) { return (index + 1) / 10. ; } | ||||||
|  | float index_from_deal_speed(float deal_speed) { return (int) (deal_speed * 10) - 1 ; } | ||||||
|  | 
 | ||||||
|  | void load_options_from_game(Game *g) { | ||||||
|  |   g->options->kan_value = index_from_kan_value(g->kan_value); | ||||||
|  |   g->options->number_of_rounds = index_from_number_of_rounds(g->number_of_rounds); | ||||||
|  |   g->options->card_backs = g->black_card_backs; | ||||||
|  |   g->options->deal_speed = index_from_deal_speed(g->deal_speed); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void save_options_to_game(Game *g) { | ||||||
|  |   g->kan_value = kan_value_from_index(g->options->kan_value); | ||||||
|  |   g->number_of_rounds = number_of_rounds_from_index(g->options->number_of_rounds); | ||||||
|  |   g->black_card_backs = g->options->card_backs; | ||||||
|  |   g->deal_speed = deal_speed_from_index(g->options->deal_speed); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void handle_options_save(Game *g) { | ||||||
|  |   save_options_to_game(g); | ||||||
|  |   g->state = GAME_STATE_INITIALIZING; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void handle_options_cancel(Game *g) { | ||||||
|  |   load_options_from_game(g); | ||||||
|  |   g->state = GAME_STATE_INITIALIZING; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void handle_select_kan(Game *g, int index) { | ||||||
|  |   g->options->kan_value = index; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void handle_select_number_of_rounds(Game *g, int index) { | ||||||
|  |   g->options->number_of_rounds = index; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void handle_select_card_backs(Game *g, int index) { | ||||||
|  |   g->options->card_backs = index; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void handle_select_deal_speed(Game *g, int index) { | ||||||
|  |   g->options->deal_speed = index; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | OptionsChoices kan_choices = {              { "Ten", "Twelve" },                                    2, 250, &handle_select_kan }; | ||||||
|  | OptionsChoices number_of_rounds_choices = { { "One", "Three", "Six", "Twelve" },                    4, 400, &handle_select_number_of_rounds }; | ||||||
|  | OptionsChoices card_backs_choices = {       { "Red", "Black" },                                     2, 550, &handle_select_card_backs }; | ||||||
|  | OptionsChoices deal_speed_choices = {       { "Very Fast", "Fast", "Medium", "Slow", "Very Slow" }, 5, 700, &handle_select_deal_speed }; | ||||||
|  | OptionsChoices *oc[4] = { &kan_choices, &number_of_rounds_choices, &card_backs_choices, &deal_speed_choices }; | ||||||
|  | 
 | ||||||
|  | void options_handle_input(Game *g) { | ||||||
|  |   if (!IsMouseButtonPressed(0)) return; | ||||||
|  | 
 | ||||||
|  |   int left = 250; | ||||||
|  |   int width = 900; | ||||||
|  | 
 | ||||||
|  |   Vector2 mouse_pos = GetMousePosition(); | ||||||
|  |   int x = mouse_pos.x, y = mouse_pos.y; | ||||||
|  |   for (int i = 0; i < 4; i++) { | ||||||
|  |     OptionsChoices *choices = oc[i]; | ||||||
|  |     if (y < choices->y || y > choices->y + 30) continue; | ||||||
|  | 
 | ||||||
|  |     for (int j = 0; j < choices->count; j++) { | ||||||
|  |       char *choice = choices->choice[j]; | ||||||
|  |       int w = MeasureText(choice, 30); | ||||||
|  |       int center = left + (width / (choices->count + 1)) * (j + 1); | ||||||
|  |       int min = center - (w/2); | ||||||
|  |       int max = center + (w/2); | ||||||
|  |       if (x > min && x < max) { | ||||||
|  | 	choices->handle(g, j); | ||||||
|  | 	return; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if (x > 400 && x < 400 + MeasureText("Save", 30) + 12 && y > 800 && y < 836) { | ||||||
|  |     handle_options_save(g); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   if (x > 900 && x < 900 + MeasureText("Cancel", 30) + 12 && y > 800 && y < 836) { | ||||||
|  |     handle_options_cancel(g); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void DrawTextCentered(char *text, int center_x, int y, int point, Color color) { | ||||||
|  |   int width = MeasureText(text, point); | ||||||
|  |   DrawText(text, center_x - (width / 2), y, point, color); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void draw_option_choices(OptionsChoices *choices, int selected_index) { | ||||||
|  |   int left = 250; | ||||||
|  |   int width = 900; | ||||||
|  |   for (int i = 0; i < choices->count; i++) { | ||||||
|  |     Color color = i == selected_index ? RED : BLACK; | ||||||
|  |     DrawTextCentered(choices->choice[i], left + (width / (choices->count + 1)) * (i + 1), choices->y, 30, color); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void options_draw(Game *g) { | ||||||
|  |   DrawTextCentered("Options", 700, 50, 60, BLACK); | ||||||
|  |   DrawTextCentered("Kan Value", 700, 175, 40, BLACK); | ||||||
|  |   draw_option_choices(&kan_choices, g->options->kan_value); | ||||||
|  |   DrawTextCentered("Number of Rounds", 700, 325, 40, BLACK); | ||||||
|  |   draw_option_choices(&number_of_rounds_choices, g->options->number_of_rounds); | ||||||
|  |   DrawTextCentered("Card Backs", 700, 475, 40, BLACK); | ||||||
|  |   draw_option_choices(&card_backs_choices, g->options->card_backs); | ||||||
|  |   DrawTextCentered("Deal Speed", 700, 625, 40, BLACK); | ||||||
|  |   draw_option_choices(&deal_speed_choices, g->options->deal_speed); | ||||||
|  | 
 | ||||||
|  |   DrawRectangle(400, 800, MeasureText("Save", 30) + 12, 36, BLACK); | ||||||
|  |   DrawRectangle(403, 803, MeasureText("Save", 30) + 6, 30, GREEN); | ||||||
|  |   DrawText("Save", 406, 806, 30, BLACK); | ||||||
|  | 
 | ||||||
|  |   DrawRectangle(900, 800, MeasureText("Cancel", 30) + 12, 36, BLACK); | ||||||
|  |   DrawRectangle(903, 803, MeasureText("Cancel", 30) + 6, 30, RED); | ||||||
|  |   DrawText("Cancel", 906, 806, 30, BLACK); | ||||||
|  | } | ||||||
							
								
								
									
										28
									
								
								options.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								options.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | #ifndef _HF_OPTIONS_ | ||||||
|  | #define _HF_OPTIONS_ | ||||||
|  | 
 | ||||||
|  | typedef struct Options Options; | ||||||
|  | typedef struct OptionsChoices OptionsChoices; | ||||||
|  | 
 | ||||||
|  | #include "game.h" | ||||||
|  | 
 | ||||||
|  | struct Options { | ||||||
|  |   int kan_value; | ||||||
|  |   int number_of_rounds; | ||||||
|  |   int card_backs; | ||||||
|  |   int deal_speed; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct OptionsChoices { | ||||||
|  |   char *choice[5]; | ||||||
|  |   int count; | ||||||
|  |   int y; | ||||||
|  |   void (*handle)(Game*, int); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | void load_options_from_game(Game *g); | ||||||
|  | void save_options_to_game(Game *g); | ||||||
|  | void options_handle_input(Game *g); | ||||||
|  | void options_draw(Game *g); | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										1
									
								
								player.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								player.h
									
									
									
									
									
								
							| @ -20,6 +20,7 @@ struct Player { | |||||||
|   int dekiyaku_score; |   int dekiyaku_score; | ||||||
|   int points; |   int points; | ||||||
|   char points_string[20]; |   char points_string[20]; | ||||||
|  |   char teyaku_string[50]; | ||||||
|   bool ai; |   bool ai; | ||||||
|   bool dealer; |   bool dealer; | ||||||
| }; | }; | ||||||
|  | |||||||
							
								
								
									
										16
									
								
								teyaku.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								teyaku.c
									
									
									
									
									
								
							| @ -75,6 +75,10 @@ int chaff_teyaku_points(ChaffTeyaku ct) { | |||||||
|   return chaff_teyaku_points_array[ct]; |   return chaff_teyaku_points_array[ct]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | int teyaku_points(Teyaku *t) { | ||||||
|  |   return set_teyaku_points(t->set) + chaff_teyaku_points(t->chaff); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| char *set_teyaku_english(SetTeyaku st) { | char *set_teyaku_english(SetTeyaku st) { | ||||||
|   return set_teyaku_english_array[st]; |   return set_teyaku_english_array[st]; | ||||||
| } | } | ||||||
| @ -89,8 +93,18 @@ void calculate_teyaku(const Hand h, Teyaku *t) { | |||||||
|   t->calculated = true; |   t->calculated = true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void set_teyaku_to_string(Teyaku *t, char *str) { | ||||||
|  |   sprintf(str, "Set: %s(%d)", set_teyaku_english(t->set), set_teyaku_points(t->set)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void chaff_teyaku_to_string(Teyaku *t, char *str) { | ||||||
|  |   sprintf(str, "Chaff: %s(%d)", chaff_teyaku_english(t->chaff), chaff_teyaku_points(t->chaff)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void teyaku_to_string(Teyaku *t, char *str) { | void teyaku_to_string(Teyaku *t, char *str) { | ||||||
|   int set_points = set_teyaku_points(t->set); |   int set_points = set_teyaku_points(t->set); | ||||||
|   int chaff_points = chaff_teyaku_points(t->chaff); |   int chaff_points = chaff_teyaku_points(t->chaff); | ||||||
|   sprintf(str, "Set: %s(%d) / Chaff: %s(%d) / Total: %d", set_teyaku_english(t->set), set_points, chaff_teyaku_english(t->chaff), chaff_points, set_points + chaff_points); |   // sprintf(str, "Set: %s(%d) / Chaff: %s(%d) / Total: %d", set_teyaku_english(t->set), set_points, chaff_teyaku_english(t->chaff), chaff_points, set_points + chaff_points);
 | ||||||
|  |   if (set_points + chaff_points > 0) sprintf(str, "Teyaku: %d", set_points + chaff_points); | ||||||
|  |   else sprintf(str, ""); | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										3
									
								
								teyaku.h
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								teyaku.h
									
									
									
									
									
								
							| @ -34,7 +34,10 @@ typedef struct Teyaku { | |||||||
|   bool calculated; |   bool calculated; | ||||||
| } Teyaku; | } Teyaku; | ||||||
| 
 | 
 | ||||||
|  | int teyaku_points(Teyaku *t); | ||||||
| void calculate_teyaku(const Hand h, Teyaku *t); | void calculate_teyaku(const Hand h, Teyaku *t); | ||||||
|  | void set_teyaku_to_string(Teyaku *t, char *str); | ||||||
|  | void chaff_teyaku_to_string(Teyaku *t, char *str); | ||||||
| void teyaku_to_string(Teyaku *t, char *str); | void teyaku_to_string(Teyaku *t, char *str); | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user