From 880b8be2c28d761505b2eecc1386919d5add6f2f Mon Sep 17 00:00:00 2001 From: scratko Date: Wed, 14 Aug 2024 02:35:56 +0300 Subject: Global fixes v1.0 Defense hint now only takes into account unbeaten cards. The client accounts for sticky data in one packet via TCP. Changed delimiter when sending data related to cards on the table and the queue (from '0' to '='). Accepting cards from a client (verification_client_input.c) is heavily patched. Cards are taken from the stack at the hint's prompt. Added pop_stack(). The trump card is retrieved from the end of the array. Changed the check of the defender's ability to beat all cards. --- server/server_game_process.c | 121 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 103 insertions(+), 18 deletions(-) (limited to 'server/server_game_process.c') diff --git a/server/server_game_process.c b/server/server_game_process.c index 8bf4e60..46a9535 100644 --- a/server/server_game_process.c +++ b/server/server_game_process.c @@ -12,7 +12,7 @@ static const char *basic_deck[deck_size] = { "3#", "4#", "5#", "6#", "7#", "8#", "9#", "10#", "J#", "Q#", "K#", "A#", "2%", "3%", "4%", "5%", "6%", "7%", "8%", "9%", "10%", - "j%", "Q%", "K%", "A%", "2v", "3v", "4v", + "J%", "Q%", "K%", "A%", "2v", "3v", "4v", "5v", "6v", "7v", "8v", "9v", "10v", "Jv", "Qv", "Kv", "Av" }; @@ -66,7 +66,7 @@ void deal_cards(const char **shuffled_deck, int *shuffled_cards_left, for(j = 0; j < card_shortage_quantity; ++j) { last_idx = *shuffled_cards_left-1; /* shuffled deck is empty */ - if(last_idx == 0 || last_idx < 0) + if(last_idx < 0) return; extracted_card = shuffled_deck[last_idx]; push_stack(&turn_queue[i]->deck, extracted_card); @@ -81,9 +81,10 @@ const char* extract_trump_card(const char **shuffled_deck, int *cards_left) { const char *trump_card = NULL; - trump_card = shuffled_deck[0] ? shuffled_deck[0] : NULL; + trump_card = shuffled_deck[*cards_left-1] ? + shuffled_deck[*cards_left-1] : NULL; if(trump_card) { - shuffled_deck[0] = NULL; + shuffled_deck[*cards_left-1] = NULL; --*cards_left; } return trump_card; @@ -226,6 +227,56 @@ int is_card_bit(const char *attack_card, const char *defend_card, return 1; return 0; } + +static void find_out_trump_cards_in_deck(player_cards *trump_cards, + player_cards deck, + const char *trump_suit) +{ + const char *suit = NULL, *card = NULL; + + while(deck) { + card = deck->str; + suit= card + strlen(card) - 1; + if(*suit == *trump_suit) + push_stack(trump_cards, card); + deck = deck->next; + } +} + +static int is_same_suit_and_not_meet(player_cards involved_cards, + struct card_stack_item *defend_card, + struct card_queue_item *attack_card) + +{ + int length; + const char *attack_suit, *defend_suit; + + if(!find_card_in_stack(involved_cards, defend_card->str)) { + length = strlen(attack_card->str); + attack_suit= attack_card->str + length - 1; + length = strlen(defend_card->str); + defend_suit = defend_card->str + length - 1; + return *attack_suit == *defend_suit; + } + return 0; +} + +static int trump_cards_left_uncovered(player_cards remaining_cards, + const char *trump_suit) +{ + const char *suit; + const char *card = NULL; + + while(remaining_cards) { + card = remaining_cards->str; + suit = card + strlen(card) - 1; + if(*suit == *trump_suit) + return 1; + remaining_cards = remaining_cards->next; + } + return 0; +} + /* * analyze that each attacker card can be beat * TODO: free memory @@ -233,13 +284,18 @@ int is_card_bit(const char *attack_card, const char *defend_card, int check_defender_can_defend(struct card_queue *cq, player_cards deck, const char *trump_suit) { - int is_bited_card; + int current_rank = 0, min_rank = 0; struct card_stack_item *next_defend_card; struct card_queue_item *next_attack_card; - player_cards involved_cards; + const char* card_with_min_rank = NULL; + + player_cards involved_cards, trump_cards, remaining_attack_cards; - is_bited_card = 0; init_stack(&involved_cards); + init_stack(&trump_cards); + init_stack(&remaining_attack_cards); + + find_out_trump_cards_in_deck(&trump_cards, deck, trump_suit); next_attack_card = NULL; while((next_attack_card = get_next_card_from_queue(cq, next_attack_card))) { @@ -247,23 +303,47 @@ int check_defender_can_defend(struct card_queue *cq, next_defend_card = NULL; next_defend_card = get_next_card_from_stack(deck, next_defend_card); - /* stack traversal */ + card_with_min_rank = NULL; + min_rank = 0; + while(next_defend_card) { if(is_card_bit(next_attack_card->str, next_defend_card->str, trump_suit)) - /* if card doesn't meet */ - if(!find_card_in_stack(involved_cards, next_defend_card->str)) { - push_stack(&involved_cards, next_defend_card->str); - is_bited_card = 1; - break; + { + if(is_same_suit_and_not_meet(involved_cards, next_defend_card, + next_attack_card)) + { + current_rank = convert_rank_to_int(next_defend_card->str); + if(!card_with_min_rank || min_rank > current_rank) { + card_with_min_rank = next_defend_card->str; + min_rank = current_rank; + } } - get_next_card_from_stack(deck, next_defend_card); + } + next_defend_card = get_next_card_from_stack(deck, next_defend_card); } - if(is_bited_card) - is_bited_card = 0; - else - return 0; + if(card_with_min_rank) { + push_stack(&involved_cards, card_with_min_rank); + if(find_card_in_stack(trump_cards, card_with_min_rank)) + remove_card_from_stack(&trump_cards, card_with_min_rank); + } else + push_stack(&remaining_attack_cards, next_attack_card->str); } + /* + * there are trump attacking uncovered cards remaining + * if the defender also has trump cards, they are of a lower rank + */ + if(trump_cards_left_uncovered(remaining_attack_cards, trump_suit)) + return 0; + while(remaining_attack_cards) { + if(!is_empty_stack(trump_cards)) { + pop_stack(&trump_cards); + pop_stack(&remaining_attack_cards); + } else + break; + } + if(!is_empty_stack(remaining_attack_cards)) + return 0; return 1; } @@ -473,3 +553,8 @@ int is_receiving_cards_limit(const struct cards_on_table *cot, return 1; return 0; } + +void clear_defense_lost_status(struct session *defender) +{ + defender->defense_lost = 0; +} -- cgit v1.2.3