#include "server_game_process.h" #include #include #include static const char *basic_deck[deck_size] = { "2^", "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#", "2%", "3%", "4%", "5%", "6%", "7%", "8%", "9%", "10%", "j%", "Q%", "K%", "A%", "2v", "3v", "4v", "5v", "6v", "7v", "8v", "9v", "10v", "Jv", "Qv", "Kv", "Av" }; static int get_random_idx() { return 0 + (int)((double)deck_size*rand()/(RAND_MAX + 1.0)); } char** get_shuffled_deck() { int i, new_idx; char **shuffled_deck = realloc(deck_size, sizeof(char*)); for(i = 0; i < deck_size; ++i) { new_idx = get_random_idx(); while(shuffled_deck[new_idx]) new_idx = get_random_idx(); shuffled_deck[new_idx] = basic_deck[i]; } return shuffled_deck; } void deal_first_cards(char **shuffled_deck, int *cards_left, player_cards *deck) { int i, last_idx; char *str; for(i = 0; i < start_deck_size; ++i) { last_idx = *cards_left-1; str = shuffled_deck[last_idx]; if(str) { push_stack(deck, str); --*cards_left; shuffled_deck[last_idx] = NULL; } } } const char* find_trump_suit(const char **shuffled_deck, int *cards_left) { const char *trump_suit = NULL; trump_suit = shuffled_deck[0] ? shuffled_deck[0] : NULL; if(trump_suit) shuffled_deck[0] = NULL; trump_suit += strlen(trump_suit) - 1; --*cards_left; return trump_suit; } int convert_rank_to_int(const char *card) { int length, rank = 0; char str_rand[2]; length = strlen(card); /* 10 - the only one of its kind */ if(length == 3) return 10; strncpy(str_rank, 1); str_rank[1] = '\0'; if(!strncmp(str_rank, "J", 1)) rank = 11; else if(!strncmp(str_rank, "Q", 1)) rank = 12; else if(!strncmp(str_rank, "K", 1)) rank = 13; else if(!strncmp(str_rank, "A", 1)) rank = 14; else rank = strtol(str_rank, NULL, 10); return rank; } int find_lowest_trump(player_cards deck, char *trump_suit) { const char *card; int lowest_rank = 0; while(deck) { if(!strncmp(card+length-1, trump_suit, 1)) { lowest_rank = convert_rank_to_int(deck->str); if(!lowest_rank || lowest_rank > rank) lowest_rank = rank; } deck = deck->next; } return lowest_rank; } void shift_turn_queue_by_one(struct session **turn_queue, int size) { int i; struct session *tmp = turn_queue[0]; for(i = 1; i < size; ++i) turn_queue[i-1] = turn_queue[i]; turn_queue[i-1] = tmp; } void update_card_quantity_arr(struct server *serv) { int i, j; for(i = 0, j = 0; i < serv->max_sess_arr_size; ++i) if(serv->sess_arr[i]) { serv->card_quantity_arr[j] = find_out_card_quantity_in_deck(serv->sess_arr[i]->deck); ++j; } } struct game_info* get_new_game_info(int players_number, int *card_quantity_arr, int shuffled_cards_left, char *trump_suit, int position_whose_turn, struct card_queue *cq, struct cards_on_table *cot) { struct game_info *gi = malloc(sizeof(game_info)); gi->players_number = players_number; gi->card_quantity_arr = card_quantity_arr; gi->shuffled_cards_left = shuffled_cards_left; gi->trump_suit = trump_suit; gi->position_whose_turn = position_whose_turn; gi->cq = cq; gi->cot = cot; return gi; } void update_game_info(struct game_info *gi, int players_number, int shuffled_cards_left, int position_whose_turn) { gi->players_number = players_number; gi->shuffled_cards_left = shuffled_cards_left; gi->position_whose_turn = position_whose_turn; } int is_card_bit(const char *attack_card, const char *defend_card, const char *trump_suit) { int length, attack_rank, defend_rank; const char *attack_suit, *defend_suit; length = strlen(attack_card); attack_suit= attack_card + length - 1; length = strlen(defend_card); defend_suit = defend_card + length - 1; /* suits matched */ if(!strcmp(attack_suit, defend_suit)) { attack_rank = convert_rank_to_int(attack_card); defend_rank = convert_rank_to_int(defend_card); if(defend_rank > attack_rank) return 1; /* defender has a trump suit */ } else if(!strcmp(defend_suit, trump_suit)) return 1; else return 0; } /* * analyze that each attacker card can be beat * TODO: free memory */ int check_defender_can_defend(struct card_queue *cq, player_cards deck, const char *trump_suit) { int i, is_bited_card; struct card_stack_item *next_defend_card; struct card_queue_item *next_attack_card; player_cards involved_cards; is_bited_card = 0; init_stack(&involved_cards); next_attack_card = NULL; while((next_attack_card = get_next_card_from_queue(cq, next_attack_card))) { /* get first defend card */ next_defend_card = NULL; next_defend_card = get_next_card_from_stack(deck, next_defend_card); /* stack traversal */ 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; } get_next_card_from_stack(deck, next_defend_card); } if(is_bited_card) is_bited_card = 0; else return 0; } return 1; } static int check_matched_ranks(const char *attack_card, const char *not_defender_card) { int attack_rank, not_defender_rank; attack_rank = convert_rank_to_int(attack_card); not_defender_rank = convert_rank_to_int(not_defender_card); return attack_rank == not_defender_rank; } int check_someone_can_toss_card(struct session **turn_queue, int players_quantity, struct card_queue *cq, struct cards_on_table *cot) { int i, j; struct card_queue_item *attack_card_in_queue; struct card_stack item *not_defender_card; for(i = 0; i < players_quantity; ++i) { /* skipping defender's cards */ if(i == 1) continue; /* checking card queue of attack cards */ attack_card_in_queue = NULL; while((attack_card_in_queue = get_next_card_from_queue(cq, attack_card_in_queue))) { not_defender_card = NULL; while((not_defender_card = get_next_card_from_stack(turn_queue[i]->deck, not_defender_card)) && !check_matched_ranks(attack_card_in_queue->str, not_defender_card->str)) {} if(not_defender_card) return 1; } /* checking cards on table */ for(j = cot->card_arr_idx; j >= 0; --j) { if(cot->card_arr[j] == '-' || cot->card_arr[j] == '\') continue; not_defender_card = NULL; while((not_defender_card = get_next_card_from_stack(turn_queue[i]->deck, not_defender_card)) && !check_matched_ranks(cot->card_arr[j], not_defender_card->str)) {} if(not_defender_card) return 1; } } return 0; } int check_player_can_toss_card(player_cards deck, struct cards_on_table *cot) { int i; struct card_stack item *not_defender_card; /* checking cards on table */ for(i = cot->card_arr_idx; i >= 0; --i) { if(cot->card_arr[i] == '-' || cot->card_arr[i] == '\') continue; not_defender_card = NULL; while((not_defender_card = get_next_card_from_stack(turn_queue[i]->deck, not_defender_card)) && !check_matched_ranks(cot->card_arr[i], not_defender_card->str)) {} if(not_defender_card) return 1; } return 0; } int is_correct_tossing_card(const char *card, struct cards_on_table *cot) { int i; for(i = cot->card_arr_idx; i >= 0; --i) { if(cot->card_arr[i] == '-' || cot->card_arr[i] == '\') continue; if(check_matched_ranks(cot->card_arr[i], card)) return 1; } return 0; } /* when defender cannot bit any card */ void put_all_cards_from_queue_to_table(struct cards_on_table *cot, struct card_queue *cq) { const char *card; while(!is_empty_queue(cq)) { card = pop_card_queue(cq); ++cot->card_arr_idx; cot->card_arr[card_arr_idx] = card; ++cot->card_arr_idx; cot->card_arr[card_arr_idx] = "\\"; ++cot->card_arr_idx; cot->card_arr[card_arr_idx] = "-"; } } void put_one_card_from_queue_to_table(struct cards_on_table *cot, struct card_queue *cq) { const char *card; card = pop_card_queue(cq); ++cot->card_arr_idx; cot->card_arr[card_arr_idx] = card; ++cot->card_arr_idx; cot->card_arr[card_arr_idx] = "\\"; ++cot->card_arr_idx; cot->card_arr[card_arr_idx] = "-"; } /* it used by defender to bit attack card */ void put_defender_card_on_table(struct cards_on_table *cot, const char *card) { cot->card_arr[card_arr_idx] = card; } void move_all_cards_to_defender(struct cards_on_table *cot, player_cards *deck) { const char *card; #if 0 while(!is_empty_queue(cq)) { card = pop_card_queue(cq); push_stack(deck, card); } #endif for(i = cot->card_arr_idx; i >= 0; --i) { if(cot->card_arr == '-' || cot->card_arr == '\') continue; push_stack(deck, card); } cot->card_arr_idx = i; } void remove_cards_from_table(struct cards_on_table *cot) { cot->card_arr_idx = -1; } int calculate_defense_card_quantity_on_table(const struct cards_on_table *cot) { int i, counter = 0; for(i = 0; i <= cot->card_arr_idx; ++i) { /* every 3 position meets a defender card */ if(!((i+1) % 3)) { if(!strcmp(cot->card_arr[i], "-")) continue; else ++counter; } } return counter; } int calculate_attack_card_quantity_on_table(const struct cards_on_table *cot) { int i, counter = 0; for(i = 0; i <= cot->card_arr_idx; ++i) if(i == 0 || !(i % 3)) ++counter; return counter; } int check_all_answers_were_received(const session **turn_queue, int size) { int i; for(i = 0; i < size; ++i) if(turn_queue[i]->tm == answer_wait) return 0; return 1; }