Compare commits
	
		
			5 Commits
		
	
	
		
			b5721105b1
			...
			95264cb3df
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 95264cb3df | |||
| e0e4013b1f | |||
| 6114c2d5d4 | |||
| 2b3dbc5fec | |||
| ec0459e35b | 
							
								
								
									
										8
									
								
								card.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								card.c
									
									
									
									
									
								
							| @ -14,6 +14,10 @@ void draw_card(Card *c, Texture2D *cards_texture, int index) { | |||||||
| 
 | 
 | ||||||
|   Color color = index == 1 ? BLACK : BRICKRED; |   Color color = index == 1 ? BLACK : BRICKRED; | ||||||
| 
 | 
 | ||||||
|  |   if (c->selected) { | ||||||
|  |     DrawRectangleRec((Rectangle) { c->position.x - 6, c->position.y - 6, card_size.x + 12, card_size.y + 12 }, BLUE); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   if (c->visible) { |   if (c->visible) { | ||||||
|     DrawTexturePro( |     DrawTexturePro( | ||||||
| 		   *cards_texture, | 		   *cards_texture, | ||||||
| @ -27,9 +31,6 @@ void draw_card(Card *c, Texture2D *cards_texture, int index) { | |||||||
|     DrawRectangleRec((Rectangle) { c->position.x, c->position.y, card_size.x, card_size.y }, color); |     DrawRectangleRec((Rectangle) { c->position.x, c->position.y, card_size.x, card_size.y }, color); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (c->selected) { |  | ||||||
|     DrawCircle(c->position.x + 10, c->position.y + 10, 10, BLUE); |  | ||||||
|   } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool point_within_card(Card *c, Vector2 point) { | bool point_within_card(Card *c, Vector2 point) { | ||||||
| @ -76,6 +77,7 @@ void order_deck(Hand *h) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void remove_from_hand(Hand *h, Card *c) { | void remove_from_hand(Hand *h, Card *c) { | ||||||
|  |   c->selected = false; | ||||||
|   bool card_found = false; |   bool card_found = false; | ||||||
|   for (int i = 0; i < h->count - 1; i++) { |   for (int i = 0; i < h->count - 1; i++) { | ||||||
|     if (h->cards[i] == c) card_found = true; |     if (h->cards[i] == c) card_found = true; | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								dialog.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								dialog.c
									
									
									
									
									
								
							| @ -24,6 +24,7 @@ void handle_click_shoubu(Game *g) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void handle_click_sage(Game *g) { | void handle_click_sage(Game *g) { | ||||||
|  |   if (!g->first_sage) g->first_sage = &g->player; | ||||||
|   g->player.dekiyaku_action = DEKIYAKU_ACTION_SAGE; |   g->player.dekiyaku_action = DEKIYAKU_ACTION_SAGE; | ||||||
|   g->turn_number++; |   g->turn_number++; | ||||||
|   g->state = GAME_STATE_CHOOSING_FROM_HAND; |   g->state = GAME_STATE_CHOOSING_FROM_HAND; | ||||||
| @ -142,10 +143,11 @@ void init_dialogs(Game *g) { | |||||||
|   end_of_game_dialog->options[1].handle = &handle_click_quit; |   end_of_game_dialog->options[1].handle = &handle_click_quit; | ||||||
| 
 | 
 | ||||||
|   Dialog *dekiyaku_end_of_round_dialog = &dialogs[4]; |   Dialog *dekiyaku_end_of_round_dialog = &dialogs[4]; | ||||||
|   dekiyaku_end_of_round_dialog->text_count = 3; |   dekiyaku_end_of_round_dialog->text_count = 4; | ||||||
|   dekiyaku_end_of_round_dialog->text[0] = malloc(200); |   dekiyaku_end_of_round_dialog->text[0] = malloc(200); | ||||||
|   dekiyaku_end_of_round_dialog->text[1] = malloc(200); |   dekiyaku_end_of_round_dialog->text[1] = malloc(200); | ||||||
|   dekiyaku_end_of_round_dialog->text[2] = malloc(200); |   dekiyaku_end_of_round_dialog->text[2] = malloc(200); | ||||||
|  |   dekiyaku_end_of_round_dialog->text[3] = malloc(200); | ||||||
|   strcpy(dekiyaku_end_of_round_dialog->text[0], "Player score"); |   strcpy(dekiyaku_end_of_round_dialog->text[0], "Player score"); | ||||||
|   strcpy(dekiyaku_end_of_round_dialog->text[1], "Right score"); |   strcpy(dekiyaku_end_of_round_dialog->text[1], "Right score"); | ||||||
|   strcpy(dekiyaku_end_of_round_dialog->text[2], "Left score"); |   strcpy(dekiyaku_end_of_round_dialog->text[2], "Left score"); | ||||||
|  | |||||||
							
								
								
									
										83
									
								
								game.c
									
									
									
									
									
								
							
							
						
						
									
										83
									
								
								game.c
									
									
									
									
									
								
							| @ -339,15 +339,18 @@ void run_frame_initializing(Game *g) { | |||||||
|   g->current_play_from_hand = NULL; |   g->current_play_from_hand = NULL; | ||||||
|   g->current_play_target = NULL; |   g->current_play_target = NULL; | ||||||
| 
 | 
 | ||||||
|  |   g->first_sage = NULL; | ||||||
|  | 
 | ||||||
|   g->deck.count = 0; |   g->deck.count = 0; | ||||||
|   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; | ||||||
|  |     c->selected = false; | ||||||
|     add_to_hand(&g->deck, c, g->deal_speed); |     add_to_hand(&g->deck, c, g->deal_speed); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   shuffle_hand(&g->deck); |   // shuffle_hand(&g->deck);
 | ||||||
|   // order_deck(&g->deck);
 |   order_deck(&g->deck); | ||||||
| 
 | 
 | ||||||
|   kan_points_string(g, g->player.points, g->player.points_string); |   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->right.points, g->right.points_string); | ||||||
| @ -415,7 +418,14 @@ void run_frame_calculating_teyaku(Game *g) { | |||||||
| void run_frame_start_of_turn(Game *g) { | void run_frame_start_of_turn(Game *g) { | ||||||
|   g->turn_number++; |   g->turn_number++; | ||||||
|   if(g->player.hand.count == 0 && g->right.hand.count == 0 && g->left.hand.count == 0) { |   if(g->player.hand.count == 0 && g->right.hand.count == 0 && g->left.hand.count == 0) { | ||||||
|  |     if ( | ||||||
|  | 	g->player.dekiyaku_action == DEKIYAKU_ACTION_NONE && | ||||||
|  | 	g->left.dekiyaku_action == DEKIYAKU_ACTION_NONE && | ||||||
|  | 	g->right.dekiyaku_action == DEKIYAKU_ACTION_NONE) { | ||||||
|       g->state = GAME_STATE_CALCULATING_SCORES; |       g->state = GAME_STATE_CALCULATING_SCORES; | ||||||
|  |     } else { | ||||||
|  |       g->state = GAME_STATE_CALCULATING_DEKIYAKU_SCORE; | ||||||
|  |     } | ||||||
|   } else { |   } else { | ||||||
|     g->state = GAME_STATE_CHECKING_FOR_CANCEL; |     g->state = GAME_STATE_CHECKING_FOR_CANCEL; | ||||||
|   } |   } | ||||||
| @ -458,19 +468,24 @@ void run_frame_choosing_target(Game *g) { | |||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   Card *selected_card = NULL; | ||||||
|   bool no_cards_selected = true; |   bool no_cards_selected = true; | ||||||
|   for (int i = 0; i < g->player.hand.count; i++) { |   for (int i = 0; i < g->player.hand.count; i++) { | ||||||
|     if (g->player.hand.cards[i]->selected) { |     if (g->player.hand.cards[i]->selected) { | ||||||
|       no_cards_selected = false; |       selected_card = g->player.hand.cards[i]; | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (no_cards_selected) { |   if (!selected_card) { | ||||||
|     g->state = GAME_STATE_CHOOSING_FROM_HAND; |     g->state = GAME_STATE_CHOOSING_FROM_HAND; | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   for (int i = 0; i < g->field.count; i++) { | ||||||
|  |     g->field.cards[i]->selected = g->field.cards[i]->month == selected_card->month; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   if (g->current_play_from_hand) { |   if (g->current_play_from_hand) { | ||||||
|     if (g->current_play_target) { |     if (g->current_play_target) { | ||||||
|       g->current_play_from_hand->selected = false; |       g->current_play_from_hand->selected = false; | ||||||
| @ -492,6 +507,9 @@ void run_frame_choosing_target(Game *g) { | |||||||
|       add_to_hand(&g->field, g->current_play_from_hand, g->deal_speed); |       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; | ||||||
|     } |     } | ||||||
|  |     for (int i = 0; i < g->player.scored.count; i++) { | ||||||
|  |       g->player.scored.cards[i]->selected = false; | ||||||
|  |     } | ||||||
|     g->state = GAME_STATE_SHOWING_CARD_FROM_DECK; |     g->state = GAME_STATE_SHOWING_CARD_FROM_DECK; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @ -536,7 +554,14 @@ void run_frame_choosing_target_from_deck(Game *g) { | |||||||
|   valid_targets(top_card, &g->field, &targets[0], &target_count); |   valid_targets(top_card, &g->field, &targets[0], &target_count); | ||||||
| 
 | 
 | ||||||
|   if (is_player_turn(g)) { |   if (is_player_turn(g)) { | ||||||
|  |     for (int i = 0; i < target_count; i++) { | ||||||
|  |       targets[i]->selected = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if (g->current_play_target) { |     if (g->current_play_target) { | ||||||
|  |       for (int i = 0; i < target_count; i++) { | ||||||
|  | 	targets[i]->selected = false; | ||||||
|  |       } | ||||||
|       capture_card_from_field(g, top_card, g->current_play_target, &g->deck, to_hand); |       capture_card_from_field(g, top_card, g->current_play_target, &g->deck, to_hand); | ||||||
|       g->state = GAME_STATE_CHECKING_FOR_NEW_DEKIYAKU; |       g->state = GAME_STATE_CHECKING_FOR_NEW_DEKIYAKU; | ||||||
|       g->current_play_from_hand = NULL; |       g->current_play_from_hand = NULL; | ||||||
| @ -559,6 +584,7 @@ void run_frame_checking_for_new_dekiyaku(Game *g) { | |||||||
|       shoubu_dialog(g); |       shoubu_dialog(g); | ||||||
|     } else { |     } else { | ||||||
|       // TODO: better AI
 |       // TODO: better AI
 | ||||||
|  |       // TODO: if it can sage, set "first sage" if possible
 | ||||||
|       cp->dekiyaku_action = DEKIYAKU_ACTION_SHOUBU; |       cp->dekiyaku_action = DEKIYAKU_ACTION_SHOUBU; | ||||||
|       g->state = GAME_STATE_CALCULATING_DEKIYAKU_SCORE; |       g->state = GAME_STATE_CALCULATING_DEKIYAKU_SCORE; | ||||||
|     } |     } | ||||||
| @ -655,7 +681,7 @@ void run_frame_calculating_scores(Game *g) { | |||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void calculate_dekiyaku_score(Game *g, Player *p) { | int calculate_dekiyaku_score(Game *g, Player *p) { | ||||||
|   Dekiyaku d; |   Dekiyaku d; | ||||||
|   calculate_dekiyaku(&p->scored, &d); |   calculate_dekiyaku(&p->scored, &d); | ||||||
|   if (p->dekiyaku_action == DEKIYAKU_ACTION_SHOUBU) { |   if (p->dekiyaku_action == DEKIYAKU_ACTION_SHOUBU) { | ||||||
| @ -665,6 +691,7 @@ void calculate_dekiyaku_score(Game *g, Player *p) { | |||||||
|     transfer_kan(g, &p->points, &g->player.points, dekiyaku_score(&d)); |     transfer_kan(g, &p->points, &g->player.points, dekiyaku_score(&d)); | ||||||
|     transfer_kan(g, &p->points, &g->right.points, dekiyaku_score(&d)); |     transfer_kan(g, &p->points, &g->right.points, dekiyaku_score(&d)); | ||||||
|     transfer_kan(g, &p->points, &g->left.points, dekiyaku_score(&d)); |     transfer_kan(g, &p->points, &g->left.points, dekiyaku_score(&d)); | ||||||
|  |     return dekiyaku_score(&d) * g->kan_value; | ||||||
|   } else { |   } else { | ||||||
|     sprintf(g->dialog->text[0], "%s cancels with dekiyaku!", p->name); |     sprintf(g->dialog->text[0], "%s cancels with dekiyaku!", p->name); | ||||||
|     dekiyaku_to_string(&d, g->dialog->text[1]); |     dekiyaku_to_string(&d, g->dialog->text[1]); | ||||||
| @ -679,9 +706,24 @@ void calculate_dekiyaku_score(Game *g, Player *p) { | |||||||
|       transfer_kan(g, &p->points, &g->right.points, dekiyaku_score(&d) / 2); |       transfer_kan(g, &p->points, &g->right.points, dekiyaku_score(&d) / 2); | ||||||
|       transfer_kan(g, &p->points, &g->left.points, dekiyaku_score(&d) / 2); |       transfer_kan(g, &p->points, &g->left.points, dekiyaku_score(&d) / 2); | ||||||
|     } |     } | ||||||
|  |     return (dekiyaku_score(&d) * g->kan_value) / 2; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void calculate_exhausted_dekiyaku_score(Game *g) { | ||||||
|  |   g->player.dekiyaku_action = DEKIYAKU_ACTION_CANCEL; | ||||||
|  |   int p_score = calculate_dekiyaku_score(g, &g->player); | ||||||
|  |   g->right.dekiyaku_action = DEKIYAKU_ACTION_CANCEL; | ||||||
|  |   int r_score = calculate_dekiyaku_score(g, &g->right); | ||||||
|  |   g->left.dekiyaku_action = DEKIYAKU_ACTION_CANCEL; | ||||||
|  |   int l_score = calculate_dekiyaku_score(g, &g->left); | ||||||
|  |   printf("%d %d %d\n", p_score, r_score, l_score); | ||||||
|  |   sprintf(g->dialog->text[0], "Hands are exhausted (half dekiyaku scores)"); | ||||||
|  |   sprintf(g->dialog->text[1], "Player scores %d points", p_score); | ||||||
|  |   sprintf(g->dialog->text[2], "Right scores %d points", r_score); | ||||||
|  |   sprintf(g->dialog->text[3], "Left scores %d points", l_score); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void run_frame_calculating_dekiyaku_score(Game *g) { | void run_frame_calculating_dekiyaku_score(Game *g) { | ||||||
|   dekiyaku_end_of_round_dialog(g); |   dekiyaku_end_of_round_dialog(g); | ||||||
|   if (g->player.dekiyaku_action == DEKIYAKU_ACTION_CANCEL || g->player.dekiyaku_action == DEKIYAKU_ACTION_SHOUBU) { |   if (g->player.dekiyaku_action == DEKIYAKU_ACTION_CANCEL || g->player.dekiyaku_action == DEKIYAKU_ACTION_SHOUBU) { | ||||||
| @ -691,7 +733,8 @@ 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 { | ||||||
|     // TODO: Hands are exhausted
 |     g->dealer = g->first_sage; | ||||||
|  |     calculate_exhausted_dekiyaku_score(g); | ||||||
|   } |   } | ||||||
|   pay_teyaku(g); |   pay_teyaku(g); | ||||||
| } | } | ||||||
| @ -901,12 +944,12 @@ 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, 650, 20, BLACK); |   DrawText(g->player.points_string, 1000, 650, 20, BLACK); | ||||||
|   DrawText(g->player.teyaku_string, 40, 680, 20, BLACK); |   DrawText(g->player.teyaku_string, 1000, 680, 20, BLACK); | ||||||
|   DrawText(g->right.points_string, 40, 725, 20, BLACK); |   DrawText(g->right.points_string, 1000, 260, 20, BLACK); | ||||||
|   DrawText(g->right.teyaku_string, 40, 755, 20, BLACK); |   DrawText(g->right.teyaku_string, 1100, 260, 20, BLACK); | ||||||
|   DrawText(g->left.points_string, 40, 800, 20, BLACK); |   DrawText(g->left.points_string, 200, 260, 20, BLACK); | ||||||
|   DrawText(g->left.teyaku_string, 40, 830, 20, BLACK); |   DrawText(g->left.teyaku_string, 300, 260, 20, BLACK); | ||||||
| 
 | 
 | ||||||
|   char round_text[40]; |   char round_text[40]; | ||||||
|   if (g->current_round < g->number_of_rounds) |   if (g->current_round < g->number_of_rounds) | ||||||
| @ -923,7 +966,21 @@ void draw_frame(Game *g) { | |||||||
|       break; |       break; | ||||||
|     case GAME_STATE_CHOOSING_TARGET: |     case GAME_STATE_CHOOSING_TARGET: | ||||||
|       DrawText("Choose a target on the field", 60, 485, 20, BLACK); |       DrawText("Choose a target on the field", 60, 485, 20, BLACK); | ||||||
|       DrawRectangleRec(next_card_position(&g->field), BLUE); | 
 | ||||||
|  |       Card *selected_card = NULL; | ||||||
|  |       for (int i = 0; i < g->player.hand.count; i++) { | ||||||
|  | 	if (g->player.hand.cards[i]->selected) { | ||||||
|  | 	  selected_card = g->player.hand.cards[i]; | ||||||
|  | 	  break; | ||||||
|  | 	} | ||||||
|  |       } | ||||||
|  |       if (!selected_card) break; | ||||||
|  | 
 | ||||||
|  |       bool draw_next_rec = true; | ||||||
|  |       for (int i = 0; i < g->field.count; i++) { | ||||||
|  | 	if (g->field.cards[i]->month == selected_card->month) draw_next_rec = false; | ||||||
|  |       } | ||||||
|  |       if (draw_next_rec) DrawRectangleRec(next_card_position(&g->field), BLUE); | ||||||
|       break; |       break; | ||||||
|     default: |     default: | ||||||
|       break; |       break; | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								game.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								game.h
									
									
									
									
									
								
							| @ -47,6 +47,7 @@ struct Game { | |||||||
|   FieldMultiplier *field_multiplier; |   FieldMultiplier *field_multiplier; | ||||||
|   Card *current_play_from_hand, *current_play_target; |   Card *current_play_from_hand, *current_play_target; | ||||||
|   Player player, right, left; |   Player player, right, left; | ||||||
|  |   Player *first_sage; | ||||||
|   int temp_points; |   int temp_points; | ||||||
|   int turn_number; |   int turn_number; | ||||||
|   Dialog *dialog; |   Dialog *dialog; | ||||||
|  | |||||||
							
								
								
									
										9
									
								
								teyaku.c
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								teyaku.c
									
									
									
									
									
								
							| @ -6,9 +6,11 @@ | |||||||
| SetTeyaku calculate_set_teyaku(const Hand h) { | SetTeyaku calculate_set_teyaku(const Hand h) { | ||||||
|   int month_counts[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; |   int month_counts[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; | ||||||
|   int month_stands[12] = { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1 }; |   int month_stands[12] = { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1 }; | ||||||
|  |   int pawlonia_chaff = 0; | ||||||
|   for (int i = 0; i < h.count; i++) { |   for (int i = 0; i < h.count; i++) { | ||||||
|     Card c = *h.cards[i]; |     Card c = *h.cards[i]; | ||||||
|     month_counts[c.month]++; |     month_counts[c.month]++; | ||||||
|  |     if (c.index >= 45) pawlonia_chaff++; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   int triplets = 0, standing_triplets = 0, pairs = 0, four_of_a_kind = 0; |   int triplets = 0, standing_triplets = 0, pairs = 0, four_of_a_kind = 0; | ||||||
| @ -16,8 +18,11 @@ SetTeyaku calculate_set_teyaku(const Hand h) { | |||||||
|     if (month_counts[i] == 4) { |     if (month_counts[i] == 4) { | ||||||
|       four_of_a_kind++; |       four_of_a_kind++; | ||||||
|     } else if (month_counts[i] == 3) { |     } else if (month_counts[i] == 3) { | ||||||
|       if (month_stands[i]) standing_triplets++; // TODO Pawlonia is weird
 |       if (month_stands[i] && (i != 12 || pawlonia_chaff == 3)) { | ||||||
|       else triplets++; | 	standing_triplets++; | ||||||
|  |       } else { | ||||||
|  | 	triplets++; | ||||||
|  |       } | ||||||
|     } else if (month_counts[i] == 2) { |     } else if (month_counts[i] == 2) { | ||||||
|       pairs++; |       pairs++; | ||||||
|     } |     } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user