diff options
-rw-r--r-- | client/card_stack.c | 65 | ||||
-rw-r--r-- | client/client.c | 42 | ||||
-rw-r--r-- | client/printing_game_frames.c | 45 | ||||
-rw-r--r-- | client/verification_client_input.c | 10 | ||||
-rw-r--r-- | server/card_queue.c | 15 | ||||
-rw-r--r-- | server/card_queue.h | 1 | ||||
-rw-r--r-- | server/card_stack.c | 12 | ||||
-rw-r--r-- | server/card_stack.h | 1 | ||||
-rw-r--r-- | server/server.c | 41 | ||||
-rw-r--r-- | server/server.h | 4 | ||||
-rw-r--r-- | server/server_data_processing.c | 38 | ||||
-rw-r--r-- | server/server_game_process.c | 44 | ||||
-rw-r--r-- | server/server_game_process.h | 5 |
13 files changed, 144 insertions, 179 deletions
diff --git a/client/card_stack.c b/client/card_stack.c index 6f0a673..fc4057c 100644 --- a/client/card_stack.c +++ b/client/card_stack.c @@ -38,36 +38,6 @@ int is_empty_stack(player_cards deck) return deck == NULL; } -#if 0 -static int convert_rank_to_int(const char *card) -{ - int length; - char str_rank[2]; - - length = strlen(card); - /* 10 - the only one of its kind */ - if(length == 3) - return 10; - - str_rank[0] = card[0]; - str_rank[1] = '\0'; - - switch(card[0]) { - case 'J': - return 11; - case 'Q': - return 12; - case 'K': - return 13; - case 'A': - return 14; - default: - return strtol(str_rank, NULL, 10); - } - return 0; -} -#endif - void add_hint_letters_stack(player_cards deck) { unsigned char letter = 'a'; @@ -145,30 +115,6 @@ void mark_card_for_attackers_stack(player_cards deck) if(check_no_attackers_cards_marked(tmp_begin_deck)) mark_all_card_stack(tmp_begin_deck); } -#if 0 -static int is_card_beaten(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; - return 0; -} -#endif void mark_card_for_defenders_stack(player_cards deck, struct cards_on_table *cot, char *trump_suit) @@ -186,17 +132,6 @@ void mark_card_for_defenders_stack(player_cards deck, deck = deck->next; } } -#if 0 -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; -} -#endif void mark_card_for_tossing_stack(player_cards deck, struct cards_on_table *cot) { diff --git a/client/client.c b/client/client.c index 5d49e1a..66bfb01 100644 --- a/client/client.c +++ b/client/client.c @@ -4,7 +4,7 @@ #include <unistd.h> #include <stdlib.h> #include <string.h> -#include <stdio.h> /* test */ +#include <stdio.h> /* for debug */ #include "client.h" #include "data_decryption.h" @@ -12,7 +12,13 @@ #include "verification_client_input.h" static const char *ip = "127.0.0.1"; -static const int port = 8082; +static const int port = 1025; + +static void clean_up_resources(struct client *cl) +{ + free(cl->cc.number_arr); + clear_stack(&cl->deck); +} static void get_data_from_server(struct client *cl, fd_set *readfds) { @@ -24,9 +30,12 @@ static void get_data_from_server(struct client *cl, fd_set *readfds) if(FD_ISSET(cl->fd, readfds)) { if(!cl->data_left_in_buffer) { cl->data_left_in_buffer = read(cl->fd, cl->buffer, max_buffer_size); - /* end of file -- closed connection */ - if(!cl->data_left_in_buffer) + /* end of file -- closed connection (from server) */ + if(!cl->data_left_in_buffer) { + clean_up_resources(cl); + pgf_disconnect(); exit(0); + } #ifdef DEBUG printf("%d\n", cl->data_left_in_buffer); for(i = 0; i < cl->data_left_in_buffer; ++i) @@ -47,13 +56,13 @@ static void get_data_from_server(struct client *cl, fd_set *readfds) cl->total_players = decrypt_get_number(end_p+1, &end_p); break; case display_only_table: - case attack: - case defense: case tossing_expectation: case tossing: /* last arg will contain pointer to '\n' */ decrypt_set_base_info(cl, end_p+1, &end_p); break; + case attack: + case defense: case attack_expectation: decrypt_set_base_info(cl, end_p+1, &end_p); decrypt_set_position_whose_turn(cl, end_p+1, &end_p); @@ -163,14 +172,26 @@ static void change_client_frame(struct client *cl) } } +static int check_users_exti(enum client_states state, const char *buffer, + int size) +{ + if((state == first_player || state == confirmation_waiting) && + size == 2 && (buffer[0] == 'q' && buffer[1] == '\n')) + return 1; + + return size == 3 && !strncmp(buffer, "qq", 2) && buffer[2] == '\n'; +} + static void send_data_to_server(struct client *cl, fd_set *readfds) { - int input_result = 0; + int input_result = 0, data_size; if(FD_ISSET(0, readfds)) { /* 0 - stdin */ - read(0, cl->buffer, max_buffer_size); - if(cl->buffer[0] == 'q' && cl->buffer[1] == 'q') { + data_size = read(0, cl->buffer, max_buffer_size); + if(check_users_exti(cl->state, cl->buffer, data_size)) { close(cl->fd); + clean_up_resources(cl); + pgf_disconnect(); exit(0); } @@ -202,6 +223,7 @@ static int check_tracking_client_input(enum client_states state, return 0; switch(state) { + case first_player: case confirmation_waiting: case attack: case defense: @@ -246,9 +268,7 @@ static void init_client(struct client *cl) cl->total_cards_left = 0; cl->player_position = 0; cl->cc.number_arr = NULL; -#if 0 cl->cc.number_arr_idx = -1; -#endif cl->cot.card_arr_idx = -1; cl->deck = NULL; cl->pending_server_response = 0; diff --git a/client/printing_game_frames.c b/client/printing_game_frames.c index bda1208..6b2131a 100644 --- a/client/printing_game_frames.c +++ b/client/printing_game_frames.c @@ -2,6 +2,7 @@ #include "card_stack.h" #include <stdio.h> +#include <unistd.h> void pgf_new_frame() { @@ -34,29 +35,39 @@ void pgf_first_player() printf("=======================================\n" " You're the first player\n" "Waiting for other players to connect...\n" + " Press q <Enter> to exit\n" "=======================================\n"); } void pgf_confirmation_waiting(int total_players) { printf("=======================================\n" - " To start game press <Enter> key \n" - " Connected players: %u/8 \n" + " To start game press <Enter> key\n" + " Connected players: %u/8\n" + " Press q <Enter> to exit\n" "=======================================\n", total_players); } +static int move_indication_condition(const struct client *cl, + int current_player) +{ + return + current_player == cl->position_whose_turn && + (cl->state == attack_expectation || cl->state == defense_expectation || + cl->state == attack || cl->state == defense || + (cl->state == spectator && (cl->sp_mode == spectator_attack || + cl->sp_mode == spectator_defense))); +} + void pgf_table(struct client *cl) { struct card_stack_item *deck = NULL; int i; for(i = 0; i <= cl->cc.number_arr_idx; ++i) - /* printing who will move */ - if(cl->state == attack_expectation || cl->state == defense_expectation) - printf("<%c%u > ", cl->position_whose_turn-1 == i ? '*' : ' ', - cl->cc.number_arr[i]); - else - printf("< %u > ", cl->cc.number_arr[i]); + printf("<%s %u %c> ", cl->player_position == i+1 ? "YOU" : " ", + cl->cc.number_arr[i], move_indication_condition(cl, i+1) ? + '*' : ' '); printf(" %s [ %u ]", cl->trump_card, cl->total_cards_left); printf("\n\n\n"); /* ================= cards on table ================ */ @@ -64,7 +75,7 @@ void pgf_table(struct client *cl) printf(" %s %s %s\n", cl->cot.card_arr[i], cl->cot.card_arr[i+1], cl->cot.card_arr[i+2]); /* for the defender, the cards in the queue are hidden */ - if(cl->state == defense_expectation) + if(cl->state == defense_expectation || cl->state == spectator) for(i = 0; i <= cl->cq.card_arr_idx; ++i) printf(" %s \\ -\n", cl->cq.card_arr[i]); if(cl->cot.card_arr_idx != -1) @@ -88,6 +99,7 @@ void pgf_suggestions(struct client *cl) { struct card_stack_item *deck = NULL; + printf("qq - exit the game\n"); if(cl->state == attack || cl->state == tossing) printf("you can specify more than one card\n"); deck = cl->deck; @@ -152,7 +164,20 @@ void pgf_game_result(int durak_position) "=======================================\n", durak_position); } +static void clear_input() +{ + int key; + + while((key = getchar()) != '\n') + {} +} + void pgf_disconnect() { - printf("Server connection disconnected\n"); + char key; + + printf("Server connection disconnected\n" + "Press <Enter> to close program\n"); + while((key = getchar()) != '\n') + clear_input(); } diff --git a/client/verification_client_input.c b/client/verification_client_input.c index 171cd64..fa88b54 100644 --- a/client/verification_client_input.c +++ b/client/verification_client_input.c @@ -39,6 +39,7 @@ int vci_attack_or_tossing(int fd, char *buffer, player_cards deck, if(state == tossing && buffer[0] == '\n') { /* cancel card tossing */ write(fd, buffer, 1); + printf("skipping the card toss\n"); return 1; } @@ -72,9 +73,9 @@ int vci_attack_or_tossing(int fd, char *buffer, player_cards deck, ++free_pos; } if(state == attack && buffer[0] == '\n') { - printf("incorrect input\n> "); - fflush(stdout); - return 0; + printf("incorrect input\n> "); + fflush(stdout); + return 0; } output_buffer[free_pos] = '\n'; write(fd, output_buffer, free_pos+1); @@ -92,6 +93,7 @@ int vci_defense(int fd, char *buffer, player_cards deck) if(buffer[0] == '\n') { /* the player does not want to keep the defense */ write(fd, buffer, 1); + printf("accepting cards\n"); return 1; } if(buffer[1] != '\n') { @@ -107,5 +109,7 @@ int vci_defense(int fd, char *buffer, player_cards deck) return 1; } /* card is not found in the deck or cannot be used */ + printf("incorrect input\n> "); + fflush(stdout); return 0; } diff --git a/server/card_queue.c b/server/card_queue.c index 194ea0c..c5d59a8 100644 --- a/server/card_queue.c +++ b/server/card_queue.c @@ -45,6 +45,8 @@ const char* pop_card_queue(struct card_queue *cq) cq->first = cq->first->next; card = tmp->str; free(tmp); + if(!cq->first) + cq->last = NULL; return card; } @@ -59,3 +61,16 @@ int find_out_card_quantity_in_cq(const struct card_queue *cq) } return counter; } + +void clear_queue(struct card_queue *cq) +{ + struct card_queue_item *tmp; + + while(cq->first) { + tmp = cq->first; + cq->first = cq->first->next; + free(tmp); + } + cq->first = NULL; + cq->last = NULL; +} diff --git a/server/card_queue.h b/server/card_queue.h index 778ece4..ebe2bb8 100644 --- a/server/card_queue.h +++ b/server/card_queue.h @@ -18,5 +18,6 @@ struct card_queue_item* get_next_card_from_queue(struct card_queue *cq, int find_out_card_quantity_in_cq(const struct card_queue *cq); int is_empty_queue(struct card_queue *cq); const char* pop_card_queue(struct card_queue *cq); +void clear_queue(struct card_queue *cq); #endif diff --git a/server/card_stack.c b/server/card_stack.c index bce0133..077707e 100644 --- a/server/card_stack.c +++ b/server/card_stack.c @@ -86,3 +86,15 @@ int find_card_in_stack(player_cards involved_cards, const char *str) } return 0; } + +void clear_stack(player_cards *deck) +{ + struct card_stack_item *tmp; + + while(*deck) { + tmp = *deck; + free(tmp); + *deck = (*deck)->next; + } + *deck = NULL; +} diff --git a/server/card_stack.h b/server/card_stack.h index 8581eec..9b204ab 100644 --- a/server/card_stack.h +++ b/server/card_stack.h @@ -18,5 +18,6 @@ struct card_stack_item* get_next_card_from_stack(player_cards deck, player_cards prev); int find_card_in_stack(player_cards involved_cards, const char *str); void pop_stack(player_cards *deck); +void clear_stack(player_cards *deck); #endif diff --git a/server/server.c b/server/server.c index f842a70..8ebc937 100644 --- a/server/server.c +++ b/server/server.c @@ -14,7 +14,6 @@ #include "card_stack.h" #include "card_queue.h" - static void init_session(struct session *new_session, struct sockaddr_in *from, int fd, int player_position) { @@ -62,12 +61,24 @@ static void close_connection(struct server *serv) if(!serv->sess_arr[i]) continue; serv->sess_arr[i]->state = disconnect; - send_disconnect_status(serv->sess_arr[i]->fd); - close(serv->sess_arr[i]->fd); + if(serv->sess_arr[i]->fd != -1) { + send_disconnect_status(serv->sess_arr[i]->fd); + close(serv->sess_arr[i]->fd); + } + clear_stack(&serv->sess_arr[i]->deck); free(serv->sess_arr[i]); serv->sess_arr[i] = NULL; } serv->connected_players_counter = 0; + free(serv->cc.number_arr); + free(serv->shuffled_deck); + free(serv->turn_queue); + free(serv->gi); + serv->cc.number_arr = NULL; + serv->shuffled_deck = NULL; + serv->turn_queue = NULL; + serv->gi = NULL; + clear_queue(&serv->cq); } static int check_playable_player_number(struct server *serv) @@ -93,10 +104,6 @@ static void init_new_game(struct server *serv) serv->trump_card = extract_trump_card(serv->shuffled_deck, &serv->shuffled_deck_size); serv->trump_suit = serv->trump_card + strlen(serv->trump_card) - 1; -#if 0 - serv->trump_suit = find_trump_suit(serv->shuffled_deck, - &serv->shuffled_deck_size); -#endif serv->turn_queue = malloc(sizeof(struct session*) * serv->connected_players_counter); serv->turn_queue_size = serv->connected_players_counter; @@ -354,7 +361,7 @@ static void define_phase_after_tossing(struct server *serv) } else { put_all_cards_from_queue_to_table(&serv->cot, &serv->cq); - if(is_receiving_cards_limit(&serv->cot, serv->turn_queue[1]->deck, + if(!is_receiving_cards_limit(&serv->cot, serv->turn_queue[1]->deck, &serv->cq) && check_someone_can_toss_card(serv->turn_queue, serv->turn_queue_size, @@ -383,7 +390,7 @@ static void define_phase_after_tossing(struct server *serv) } else { serv->turn_queue[1]->defense_lost = 1; put_all_cards_from_queue_to_table(&serv->cot, &serv->cq); - if(is_receiving_cards_limit(&serv->cot, + if(!is_receiving_cards_limit(&serv->cot, serv->turn_queue[1]->deck, &serv->cq) && check_someone_can_toss_card(serv->turn_queue, @@ -692,7 +699,7 @@ static int check_server_state_change_conditions(struct server *serv) static void make_data_transfer(struct server *serv, fd_set *readfds, fd_set *writefds) { - int i, result; + int i, result, close_connection_status = 0; for(i = 0; i < serv->max_sess_arr_size; ++i) { if(!serv->sess_arr[i]) continue; @@ -749,12 +756,12 @@ static void make_data_transfer(struct server *serv, fd_set *readfds, get_cards_from_tossing_player(serv->sess_arr[i], serv->turn_queue[1]->deck, &serv->cot, &serv->cq); - if(result == 1 || result == 2) + if(result == answer_got || result == anwer_got_with_limit) serv->sess_arr[i]->tm = answer_got; - if(result == 2) + if(result == anwer_got_with_limit) serv->tossing_limit = 1; - else if(result == 3) + else if(result == cancel) serv->sess_arr[i]->tm = cancel; } break; @@ -765,6 +772,12 @@ static void make_data_transfer(struct server *serv, fd_set *readfds, print_game_result(serv->sess_arr[i], serv->durak_position); break; } + if(!result) { + close(i); + serv->sess_arr[i]->fd = -1; + close_connection_status = 1; + result = 1; /* next can be reading that's not ready */ + } } if(serv->state == start_game || serv->state == table || serv->state == end_game) @@ -772,7 +785,7 @@ static void make_data_transfer(struct server *serv, fd_set *readfds, if(check_server_state_change_conditions(serv)) serv->change_server_state = 1; /* connection is closed */ - if(!result) { + if(close_connection_status) { close_connection(serv); serv->change_server_state = 0; serv->state = no_players; diff --git a/server/server.h b/server/server.h index 5f7ffcc..552f899 100644 --- a/server/server.h +++ b/server/server.h @@ -47,10 +47,11 @@ enum client_game_states { }; enum tossing_mode { + none, cancel, answer_wait, answer_got, - none + anwer_got_with_limit, }; enum spectator_mode { @@ -94,7 +95,6 @@ struct server { struct session **sess_arr; int max_sess_arr_size; int connected_players_counter; - /* TODO: make static allocation memory */ const char **shuffled_deck; int shuffled_deck_size; const char *trump_suit; diff --git a/server/server_data_processing.c b/server/server_data_processing.c index df95b7f..99ac579 100644 --- a/server/server_data_processing.c +++ b/server/server_data_processing.c @@ -177,6 +177,12 @@ int print_game_part(const struct session *client, /* let the client print card tips and wait for input */ case attack: case defense: + /* other clents will be waiting particular player */ + case attack_expectation: + free_pos += sprintf(output_buffer + free_pos, "%u:", + gi->position_whose_turn); + *(output_buffer + free_pos-1) = '\n'; + break; /* * who haven't got tossing card (including defender) must wait * when other players make moves @@ -186,12 +192,6 @@ int print_game_part(const struct session *client, /* instead of last ':' */ *(output_buffer + free_pos-1) = '\n'; break; - /* other clents will be waiting particular player */ - case attack_expectation: - free_pos += sprintf(output_buffer + free_pos, "%u:", - gi->position_whose_turn); - *(output_buffer + free_pos-1) = '\n'; - break; case defense_expectation: case spectator: /* copying whose turn */ @@ -219,18 +219,6 @@ int print_game_part(const struct session *client, } return write_to_client(client->fd, free_pos); } -#if 0 -static int is_receiving_cards_limit(int total_defense_cards, int total_attack_cards) -{ - if(total_defense_cards >= start_deck_size && - total_attack_cards == start_deck_size) { - return 1; - } else if(total_defense_cards == total_attack_cards) - return 1; - return 0; -} -#endif - /* * example: 7v\2#\A^\'\n' @@ -313,9 +301,10 @@ int get_card_from_defender(struct session *client, struct cards_on_table *cot, /* * 0 - buffer overflow or client closed connection - * 1 - some number of cards added to card queue + * 1 - some number of cards added to card queue (answer_got) * 2 - card toss limit was reached when accepting cards from this player - * 3 - player refused to toss the card + * (anwer_got_with_limit) + * 3 - player refused to toss the card (cancel) * * example: 10#\A^\7v\'\n' * or: '\n' @@ -341,7 +330,7 @@ int get_cards_from_tossing_player(struct session *client, /* cancellation */ if(client->buffer[0] == '\n') - return 3; + return cancel; for(i = 0, j = 0; i < read_result; ++i) { if(client->buffer[i] == '\\') { @@ -351,7 +340,7 @@ int get_cards_from_tossing_player(struct session *client, data_length = sprintf(output_buffer, "%d\n", tossing_limit_status); write_to_client(client->fd, data_length); - return 3; + return cancel; } given_card[j] = '\0'; j = 0; @@ -371,14 +360,13 @@ int get_cards_from_tossing_player(struct session *client, ++j; } - /* 7 -- state for result of received cards */ data_length = sprintf(output_buffer, "%d:%s\n", card_acceptance_status, all_cards_received_status ? "all" : "not all"); write_to_client(client->fd, data_length); if(all_cards_received_status) - return 1; + return answer_got; else - return 2; + return anwer_got_with_limit; } void print_game_result(const struct session *client, int durak_position) diff --git a/server/server_game_process.c b/server/server_game_process.c index d6fc4be..369f3d6 100644 --- a/server/server_game_process.c +++ b/server/server_game_process.c @@ -115,19 +115,6 @@ const char* extract_trump_card(const char **shuffled_deck, int *cards_left) } return trump_card; } -#if 0 -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; -} -#endif int convert_rank_to_int(const char *card) { @@ -207,16 +194,6 @@ void update_card_quantity_arr(struct session **turn_queue, struct card_count cc) cc.number_arr[key] = find_out_card_quantity_in_deck(turn_queue[i]->deck); } - - -#if 0 - for(i = 0; i < serv->max_sess_arr_size; ++i) - if(serv->sess_arr[i]) { - player_position_idx = serv->sess_arr[i]->player_position - 1; - serv->cc.number_arr[player_position_idx] = - find_out_card_quantity_in_deck(serv->sess_arr[i]->deck); - } -#endif } struct game_info* get_new_game_info(int players_number, int *card_quantity_arr, @@ -517,14 +494,7 @@ void put_defender_card_on_table(struct cards_on_table *cot, const char *card) void move_all_cards_to_defender(struct cards_on_table *cot, player_cards *deck) { int i; -#if 0 - const char *card; - 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[i][0] == '-' || cot->card_arr[i][0] == '\\') continue; @@ -617,17 +587,3 @@ int check_everyone_can_replanish_deck(int shuffled_cards_left, } return shuffled_cards_left >= 0; } -#if 0 -void find_out_who_dropped_all_cards(struct session **turn_queue, - int turn_queue_size, int *number_arr) -{ - int i, key, player_deck_size; - - for(i = 0; i < turn_queue_size; ++i) { - key = turn_queue[i]->player_position - 1; - player_deck_size = number_arr[key]; - if(!player_deck_size) - turn_queue[i]->state = discarded_cards; - } -} -#endif diff --git a/server/server_game_process.h b/server/server_game_process.h index f384fdc..0259751 100644 --- a/server/server_game_process.h +++ b/server/server_game_process.h @@ -29,9 +29,6 @@ void deal_one_card_in_turn(const char **shuffled_deck, int *shuffled_cards_left, struct session **turn_queue, int turn_queue_size, struct card_count cc); const char* extract_trump_card(const char **shuffled_deck, int *cards_left); -#if 0 -const char* find_trump_suit(const char **shuffled_deck, int *cards_left); -#endif int find_lowest_trump(player_cards deck, const char *trump); void shift_turn_queue_by_one(struct session **turn_queue, int turn_queue_size); void move_turn_queue_two_players_ahead(struct session **turn_queue, @@ -84,7 +81,5 @@ void clear_defense_lost_status(struct session *defender); int check_everyone_can_replanish_deck(int shuffled_cards_left, struct session **turn_queue, int turn_queue_size, int *number_arr); -void find_out_who_dropped_all_cards(struct session **turn_queue, - int turn_queue_size, int *number_arr); #endif |