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,10 +386,20 @@ 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) {
|
||||||
g->turn_number++;
|
g->turn_number++;
|
||||||
@ -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