diff options
-rw-r--r-- | Makefile | 17 | ||||
-rw-r--r-- | card_queue.c | 13 | ||||
-rw-r--r-- | card_queue.h | 2 | ||||
-rw-r--r-- | card_stack.c | 6 | ||||
-rw-r--r-- | card_stack.h | 8 | ||||
-rw-r--r-- | server.c | 307 | ||||
-rw-r--r-- | server.h | 16 | ||||
-rw-r--r-- | server_data_processing.c | 83 | ||||
-rw-r--r-- | server_data_processing.h | 5 | ||||
-rw-r--r-- | server_game_process.c | 147 | ||||
-rw-r--r-- | server_game_process.h | 45 |
11 files changed, 373 insertions, 276 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6fb2c5c --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +SRCMODULES = card_stack.c card_queue.c server_data_processing.c server_game_process.c server.c +OBJMODULES = $(SRCMODULES:.c=.o) +CC = gcc +CFLAGS = -Wall -g -c + +all: server + +%.o: %.с %.h + $(CC) $(CFLAGS) $< -o $@ + +server: $(OBJMODULES) + $(CC) $(LIBS) $^ -o $@ + +-include deps.mk + +deps.mk: $(SRCMODULES) + $(CC) -MM $^ > $@ diff --git a/card_queue.c b/card_queue.c index ec42b3b..194ea0c 100644 --- a/card_queue.c +++ b/card_queue.c @@ -14,11 +14,11 @@ void push_queue(struct card_queue *cq, const char *str) tmp->str = str; tmp->next = NULL; if(!cq->first) { - cd->first = tmp; - cd->last = tmp; + cq->first = tmp; + cq->last = tmp; } else { - cd->last->next = tmp; - cd->last = tmp; + cq->last->next = tmp; + cq->last = tmp; } } @@ -51,10 +51,11 @@ const char* pop_card_queue(struct card_queue *cq) int find_out_card_quantity_in_cq(const struct card_queue *cq) { int counter = 0; + struct card_queue_item *tmp = cq->first; - while(cq) { + while(tmp) { ++counter; - cq = cq->next; + tmp = tmp->next; } return counter; } diff --git a/card_queue.h b/card_queue.h index 475a93e..778ece4 100644 --- a/card_queue.h +++ b/card_queue.h @@ -16,5 +16,7 @@ void push_queue(struct card_queue *cq, const char *str); struct card_queue_item* get_next_card_from_queue(struct card_queue *cq, struct card_queue_item *prev); 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); #endif diff --git a/card_stack.c b/card_stack.c index b9b61f6..aa8af71 100644 --- a/card_stack.c +++ b/card_stack.c @@ -8,9 +8,9 @@ void init_stack(player_cards *deck) *deck = NULL; } -void push_stack(player_cards *deck, char *str) +void push_stack(player_cards *deck, const char *str) { - struct card_stack_item new_card = malloc(sizeof(struct card_stack_item)); + struct card_stack_item *new_card = malloc(sizeof(struct card_stack_item)); new_card->str = str; new_card->next = *deck; if(new_card->next) @@ -24,7 +24,7 @@ int is_empty_stack(const player_cards deck) return !deck; } -int find_out_card_quantity_in_deck(const player_cards deck) +int find_out_card_quantity_in_deck(player_cards deck) { int counter = 0; diff --git a/card_stack.h b/card_stack.h index 37612aa..d380ded 100644 --- a/card_stack.h +++ b/card_stack.h @@ -2,7 +2,7 @@ #define CARD_STACK_H_SENTRY struct card_stack_item { - char *str; + const char *str; struct card_stack_item *next; struct card_stack_item *prev; }; @@ -10,14 +10,12 @@ struct card_stack_item { typedef struct card_stack_item* player_cards; void init_stack(player_cards *deck); -void push_stack(player_cards *deck, char *str); +void push_stack(player_cards *deck, const char *str); int is_empty_stack(const player_cards deck); -int find_out_card_quantity_in_deck(const player_cards deck); +int find_out_card_quantity_in_deck(player_cards deck); const char* remove_card_from_stack(player_cards *deck, const char *str); 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); -int is_empty_queue(struct card_queue *cq); -const char* pop_card_queue(struct card_queue *cq); #endif @@ -24,12 +24,12 @@ static void init_session(struct session *new_session, struct sockaddr_in *from, new_session->player_position = player_position; new_session->tm = none; new_session->defense_lost = 0; - init_stack(new_session->deck); + init_stack(&new_session->deck); } static int accept_client(struct server *serv) { - int fd, i, flags; + int fd, i; struct sockaddr_in addr; struct session *new_session; socklen_t len = sizeof(addr); @@ -74,7 +74,7 @@ static void init_new_game(struct server *serv) serv->shuffled_deck = get_shuffled_deck(); serv->trump_suit = find_trump_suit(serv->shuffled_deck, - serv->shuffled_deck_size); + &serv->shuffled_deck_size); serv->turn_queue = malloc(sizeof(struct session*) * serv->connected_players_counter); serv->card_quantity_arr = malloc(sizeof(int) * @@ -89,13 +89,13 @@ static void init_new_game(struct server *serv) for(i = 0, j = 0; i < serv->max_sess_arr_size; ++i) { if(serv->sess_arr[i]) { serv->turn_queue[j] = serv->sess_arr[i]; - deal_first_cards(serv->shuffled_deck, &serv->deck_size, + deal_first_cards(serv->shuffled_deck, &serv->shuffled_deck_size, &serv->sess_arr[i]->deck); - found_trump = find_lowest_trump(serv->sess_arr[i]->deck, - serv->trump_suit); - if(found_trump) - if(!lowest_trump || found_trump < lowest_trump) { - lowest_trump = found_trump; + current_trump = find_lowest_trump(serv->sess_arr[i]->deck, + serv->trump_suit); + if(current_trump) + if(!lowest_trump || current_trump < lowest_trump) { + lowest_trump = current_trump; who_attack = j; } ++j; @@ -130,6 +130,7 @@ static void set_whose_turn(struct server *serv, enum client_game_states state) serv->position_whose_turn = serv->turn_queue[1]->player_position; break; case tossing: + default: serv->position_whose_turn = 0; } } @@ -148,34 +149,42 @@ static void set_state_for_client(struct server *serv, break; case tossing: serv->turn_queue[1]->state = tossing_expectation; + default: + {} } - for(i = 0; i < serv->max_sess_arr_size; ++i) { + for(i = 0; i < serv->connected_players_counter; ++i) { switch(state) { case attack: - if(serv->sess_arr[i] && serv->sess_arr[i] != serv->turn_queue[0]) - serv->sess_arr[i]->state = attack_expectation; + if(serv->turn_queue[i] && serv->turn_queue[i] != + serv->turn_queue[0]) + serv->turn_queue[i]->state = attack_expectation; break; case defense: - if(serv->sess_arr[i] && serv->sess_arr[i] != serv->turn_queue[1]) - serv->sess_arr[i]->state = defense_expectation; + if(serv->turn_queue[i] && serv->turn_queue[i] != + serv->turn_queue[1]) + serv->turn_queue[i]->state = defense_expectation; break; case tossing: - if(serv->sess_arr[i] && serv->sess_arr[i] != serv->turn_queue[1]) { - if(check_player_can_tossing(serv->sess_arr[i]->deck, - serv->cot)) { - serv->sess_arr[i]->answer_wait; - serv->sess_arr[i]->state = tossing; + if(serv->turn_queue[i] && serv->turn_queue[i] != + serv->turn_queue[1]) { + if(check_player_can_toss_card(serv->turn_queue[i]->deck, + serv->cot)) + { + serv->turn_queue[i]->tm = answer_wait; + serv->turn_queue[i]->state = tossing; } else { - serv->sess_arr[i]->none; - serv->sess_arr[i]->state = tossing_expectation; + serv->turn_queue[i]->tm = none; + serv->turn_queue[i]->state = tossing_expectation; } } break; case display_only_table: - if(serv->sess_arr[i]) - serv->sess_arr[i]->state = display_only_table; + if(serv->turn_queue[i]) + serv->turn_queue[i]->state = display_only_table; break; + default: + {} } } } @@ -203,10 +212,31 @@ static int defense_condition(struct server *serv) serv->trump_suit); } -static void define_phase_after_defense(struct serve *serv) +static void define_phase_after_attack(struct server *serv) +{ + if(print_table_condition(serv)) { + set_state_for_client(serv, display_only_table); + put_all_cards_from_queue_to_table(serv->cot, serv->cq); + serv->turn_queue[1]->defense_lost = 1; + serv->state = table; + } else if(defense_condition(serv)) { + set_state_for_client(serv, defense); + set_whose_turn(serv, defense); + put_one_card_from_queue_to_table(serv->cot, serv->cq); + serv->state = defense_phase_out; + } else { + set_state_for_client(serv, tossing); + set_whose_turn(serv, tossing); + put_all_cards_from_queue_to_table(serv->cot, serv->cq); + serv->turn_queue[1]->defense_lost = 1; + serv->state = tossing_phase_out; + } +} + +static void define_phase_after_defense(struct server *serv) { /* card wasn't beated */ - if(serv->cot->card_arr[serv->cot->card_arr_idx] == '-') { + if(serv->cot->card_arr[serv->cot->card_arr_idx][0] == '-') { serv->turn_queue[1]->defense_lost = 1; put_all_cards_from_queue_to_table(serv->cot, serv->cq); if(check_someone_can_toss_card(serv->turn_queue, @@ -218,26 +248,22 @@ static void define_phase_after_defense(struct serve *serv) serv->state = tossing_phase_out; /* then begin new attack */ } else { - move_all_cards_to_defender(serv->cot, &serv->turn_queue[1]->deck); - set_state_for_client(serv, attack); - /* add shifting of turn arr*/ - set_whose_turn(serv, attack); - serv->state = attack_phase_out; + set_state_for_client(serv, display_only_table); + serv->state = table; } /* can defender continue defense? */ } else { if(is_empty_queue(serv->cq)) { - if(check_something_can_toss_card(serv->turn_queue, - serv->connected_players_counter, - serv->cq, serv->cot)) + if(check_someone_can_toss_card(serv->turn_queue, + serv->connected_players_counter, + serv->cq, serv->cot)) { set_state_for_client(serv, tossing); set_whose_turn(serv, tossing); serv->state = tossing_phase_out; } else { - /* remove cards from table */ - remove_cards_from_table(serv->cot); - /* TODO: deal cards, shift turn queue */ + set_state_for_client(serv, display_only_table); + serv->state = table; } /* card queue contains some cards for defender */ } else { @@ -247,7 +273,9 @@ static void define_phase_after_defense(struct serve *serv) set_state_for_client(serv, defense); set_whose_turn(serv, defense); serv->state = defense_phase_out; + } /* defender can't defense */ +#if 0 } else { serv->turn_queue[1]->defense_lost = 1; put_all_cards_from_queue_to_table(serv->cot, serv->cq); @@ -267,14 +295,66 @@ static void define_phase_after_defense(struct serve *serv) serv->state = attack_phase_out; } } +#endif } } } -static void determine_server_state(struct server *serv) +static void define_phase_after_tossing(struct server *serv) { - int i; + if(serv->turn_queue[1]->defense_lost) { + if(is_empty_queue(serv->cq)) { + /* nobody's put any cards on the table */ + set_state_for_client(serv, display_only_table); + serv->state = table; + } + else { + put_all_cards_from_queue_to_table(serv->cot, serv->cq); + if(check_someone_can_toss_card(serv->turn_queue, + serv->connected_players_counter, + serv->cq, serv->cot)) + { + set_state_for_client(serv, tossing); + set_whose_turn(serv, tossing); + serv->state = tossing_phase_out; + } else { + set_state_for_client(serv, display_only_table); + serv->state = table; + } + } + /* defense continue? */ + } else { + if(is_empty_queue(serv->cq)) { + set_state_for_client(serv, display_only_table); + serv->state = table; + } else { + if(check_defender_can_defend(serv->cq, serv->turn_queue[1]->deck, + serv->trump_suit)) { + put_one_card_from_queue_to_table(serv->cot, serv->cq); + set_state_for_client(serv, defense); + set_whose_turn(serv, defense); + serv->state = defense_phase_out; + } else { + serv->turn_queue[1]->defense_lost = 1; + put_all_cards_from_queue_to_table(serv->cot, serv->cq); + if(check_someone_can_toss_card(serv->turn_queue, + serv->connected_players_counter, + serv->cq, serv->cot)) + { + set_state_for_client(serv, tossing); + set_whose_turn(serv, tossing); + serv->state = tossing_phase_out; + } else { + set_state_for_client(serv, display_only_table); + serv->state = table; + } + } + } + } +} +static void determine_server_state(struct server *serv) +{ switch(serv->state) { case no_players: serv->state = first_player; @@ -284,11 +364,9 @@ static void determine_server_state(struct server *serv) serv->state = confirmation_waiting; break; case confirmation_waiting: - if(serv->confirmation_status || is_max_playable_player_number(serv)) { set_record_status_for_all(serv); init_new_game(serv); serv->state = start_game; - } break; case start_game: set_state_for_client(serv, attack); @@ -300,107 +378,46 @@ static void determine_server_state(struct server *serv) serv->state = attack_phase_in; break; case attack_phase_in: - if(print_table_condition(serv)) { - set_state_for_client(serv, display_only_table); - put_all_cards_from_queue_to_table(serv->cot, serv->cq); - serv->state = table; - } else if(defense_condition(serv)) { - set_state_for_client(serv, defense); - set_whose_turn(serv, defense); - put_one_card_from_queue_to_table(serv->cot, serv->cq); - serv->state = defense_phase_out; - } else { - set_state_for_client(serv, tossing); - set_whose_turn(serv, tossing); - put_all_cards_from_queue_to_table(serv->cot, serv->cq); - /* ??? */ - serv->state = tossing_phase_out; - } + case defense_phase_in: + case tossing_phase_in: + if(serv->state == attack_phase_in) + define_phase_after_attack(serv); + else if(serv->state == defense_phase_in) + define_phase_after_defense(serv); + else + /* all answers received or the limit on card tossing was reached */ + define_phase_after_tossing(serv); set_record_status_for_all(serv); update_card_quantity_arr(serv); update_game_info(serv->gi, serv->connected_players_counter, serv->shuffled_deck_size, serv->position_whose_turn); break; case table: - move_all_cards_to_defender(serv->cot, &serv->turn_queue[1]->deck); + if(serv->turn_queue[1]->defense_lost) { + move_all_cards_to_defender(serv->cot, &serv->turn_queue[1]->deck); + move_turn_queue_two_players_ahead(serv->turn_queue, + serv->connected_players_counter); + } + else { + remove_cards_from_table(serv->cot); + shift_turn_queue_by_one(serv->turn_queue, + serv->connected_players_counter); + } set_record_status_for_all(serv); set_state_for_client(serv, attack); - /* add shifting of turn arr*/ set_whose_turn(serv, attack); + update_card_quantity_arr(serv); + deal_cards(serv->shuffled_deck, &serv->shuffled_deck_size, + serv->turn_queue, serv->connected_players_counter, + serv->card_quantity_arr); serv->state = attack_phase_out; break; case defense_phase_out: serv->state = defense_phase_in; break; - case defense_phase_in: - define_phase_after_defense(serv); - set_record_status_for_all(serv); - update_card_quantity_arr(serv); - update_game_info(serv->gi, serv->connected_players_counter, - serv->shuffled_deck_size, serv->position_whose_turn); - break; case tossing_phase_out: serv->state = tossing_phase_in; break; - /* all answers received or the limit on card tossing was reached */ - case tossing_phase_in: - if(turn_queue[1]->defense_lost) { - if(is_empty_queue(serv->cq)) { - /* nobody's put any cards on the table */ - /* add shifting */ - set_state_for_client(serv, attack); - set_whose_turn(serv, attack); - serv->state = attack_phase_out; - } - else { - put_all_cards_from_queue_to_table(serv->cot, serv->cq); - if(check_someone_can_toss_card(serv->turn_queue, - serv->connected_players_counter, - serv->cq, serv->cot)) - { - set_state_for_client(serv, tossing); - set_whose_turn(serv, tossing); - serv->state = tossing_phase_out; - } else { - set_state_for_client(serv, display_only_table); - serv->state = table; - } - } - } else { - if(is_empty_queue(serv->cq)) { - remove_cards_from_table(serv->cot); - /* add shifting of queue */ - set_state_for_client(serv, attack); - set_whose_turn(serv, attack); - serv->state = attack_phase_out; - } else { - if(check_defender_can_defend(serv->cq, serv->turn_queue[1], - serv->trump_suit)) { - put_one_card_from_queue_to_table(serv->cot, serv->cq); - set_state_for_client(serv, defense); - set_whose_turn(serv, defense); - serv->state = defense_phase_out; - } else { - serv->turn_queue[1]->defense_lost = 1; - put_all_cards_from_queue_to_table(serv->cot, serv->cq); - if(check_someone_can_toss_card(serv->turn_queue, - serv->connected_players_counter, - serv->cq, serv->cot)) - { - set_state_for_client(serv, tossing); - set_whose_turn(serv, tossing); - serv->state = tossing_phase_out; - } else { - set_state_for_client(serv, display_only_table); - serv->state = table; - } - } - } - } - set_record_status_for_all(serv); - update_card_quantity_arr(serv); - update_game_info(serv->gi, serv->connected_players_counter, - serv->shuffled_deck_size, serv->position_whose_turn); } serv->change_server_state = 0; } @@ -425,7 +442,7 @@ static int server_state_change_condition(struct server *serv) static int accept_new_player(struct server *serv) { - int accept_result, i; + int accept_result; accept_result = accept_client(serv); if(accept_result == -1) { syslog(LOG_ERR, "accept error"); @@ -438,12 +455,11 @@ static int accept_new_player(struct server *serv) return 1; } - static void set_up_player_tracking(struct server *serv, fd_set *readfds, fd_set *writefds) { int i; - for(i = 0; i < serv->sess_arr[i]; ++i) { + for(i = 0; i < serv->max_sess_arr_size; ++i) { if(!serv->sess_arr[i]) continue; @@ -478,29 +494,40 @@ static void set_up_player_tracking(struct server *serv, fd_set *readfds, serv->sess_arr[i]->tm == answer_wait) FD_SET(i, readfds); break; + case no_players: + {} } } } static int check_server_state_change_conditions(int is_tossing_limit, - enum server_states state) + struct server *serv) { - switch(state) { + switch(serv->state) { case start_game: case attack_phase_out: case attack_phase_in: case defense_phase_out: case defense_phase_in: case tossing_phase_out: + case table: return 1; case tossing_phase_in: - if(tossing_limit || check_all_answers_were_received(serv->turn_queue, - serv->connected_players_counter)) + if(is_tossing_limit || + check_all_answers_were_received((const struct session**) + serv->turn_queue, + serv->connected_players_counter)) return 1; + default: + return 0; } return 0; } +static void close_connection() +{ +} + static void make_data_transfer(struct server *serv, fd_set *readfds, fd_set *writefds) { @@ -528,9 +555,10 @@ static void make_data_transfer(struct server *serv, fd_set *readfds, serv->change_server_state = 1; } break; + case start_game: case attack_phase_out: case defense_phase_out: - case tossing_phase_out + case tossing_phase_out: case table: if(FD_ISSET(i, writefds) && serv->sess_arr[i]->record) result = print_game_part(serv->sess_arr[i], serv->gi); @@ -542,7 +570,8 @@ static void make_data_transfer(struct server *serv, fd_set *readfds, break; case defense_phase_in: if(FD_ISSET(i, readfds)) - result = get_card_from_defender(serv->sess_arr[i], serv->cot); + result = get_card_from_defender(serv->sess_arr[i], serv->cot, + serv->trump_suit); break; case tossing_phase_in: if(FD_ISSET(i, readfds)) { @@ -559,20 +588,25 @@ static void make_data_transfer(struct server *serv, fd_set *readfds, if(result == 2) tossing_limit = 1; else if(result == 3) - serv->sess_arr[i]-> = cancel; + serv->sess_arr[i]->tm = cancel; } break; + case no_players: + {} } } if(serv->state == start_game || serv->state == table) sleep(2); - if(check_server_state_change_conditions(tossing_limit, serv->state)) + if(check_server_state_change_conditions(tossing_limit, serv)) serv->change_server_state = 1; + /* connection is closed */ + if(!result) + close_connection(); } int main_loop(struct server *serv) { - int i, maxfd, accept_result; + int maxfd, accept_result; fd_set readfds, writefds; for(;;) { @@ -632,7 +666,6 @@ static int init_server(struct server *serv, int port) serv->state = no_players; serv->change_server_state = 0; serv->connected_players_counter = 0; - serv->confirmation_status = 0; serv->shuffled_deck = NULL; serv->shuffled_deck_size = max_shuffled_deck_size; serv->gi = NULL; @@ -1,7 +1,8 @@ #ifndef SERVER_H_SENTRY #define SERVER_H_SENTRY -#include "card_qeueu.h" +#include "card_queue.h" +#include "card_stack.h" enum { max_buffer_size = 4096, @@ -9,6 +10,11 @@ enum { init_sess_arr_size = 32 }; +enum { + max_shuffled_deck_size = 52, + max_card_arr_size = 18 +}; + enum server_states { no_players, first_player, @@ -42,7 +48,7 @@ enum tossing_mode { struct session { int fd; - enum client_game states state; + enum client_game_states state; /* read data from client */ char buffer[max_buffer_size]; int buffer_used; @@ -63,16 +69,18 @@ struct cards_on_table { struct server { int change_server_state; + enum server_states state; int listen_socket; struct session **sess_arr; int max_sess_arr_size; int connected_players_counter; - char **shuffled_deck; + const char **shuffled_deck; int shuffled_deck_size; + const char *trump_suit; struct game_info *gi; struct session **turn_queue; int *card_quantity_arr; - int number_whose_turn; + int position_whose_turn; struct card_queue *cq; struct cards_on_table *cot; }; diff --git a/server_data_processing.c b/server_data_processing.c index c313013..5c78f78 100644 --- a/server_data_processing.c +++ b/server_data_processing.c @@ -1,12 +1,13 @@ #include "server_data_processing.h" #include "server.h" +#include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <string.h> enum { - output_buffer_size = 1024; + output_buffer_size = 1024 }; static char output_buffer[output_buffer_size]; @@ -25,12 +26,12 @@ static int read_from_client(int fd, char *buffer, int max_buffer_size) /* buffer overflow */ if(read_result >= max_buffer_size) return 0; + return read_result; } int print_message_for_first_player(int fd) { - char *str_end; - str_end = stpcpy(output_buffer, "first\n"); + stpcpy(output_buffer, "first\n"); return write_to_client(fd, strlen("first\n")); } @@ -46,7 +47,7 @@ int print_connected_players(int fd, int number) * 0 - buffer overflow or player closed session * -1 - not ready */ -int check_readiness(const struct session *client) +int check_readiness(struct session *client) { int read_result; read_result = read_from_client(client->fd, client->buffer, max_buffer_size); @@ -68,21 +69,21 @@ static void copy_card_queue(int *offset, struct card_queue *cq) length = strlen(next_attack_card->str); for(i = 0; i < length; ++i, ++*offset) *(output_buffer + *offset) = (next_attack_card->str)[i]; - *(output_buffer + *offset) = '\'; + *(output_buffer + *offset) = '\\'; ++*offset; } *(output_buffer + *offset-1) = ':'; } -static void copy_cards_on_table(int *offset, struct cards_on_table *cot) +static void copy_cards_on_table(int *offset, struct cards_on_table cot) { int i, j, length; - for(i = 0; i <= cot->card_arr_idx; ++i) { - length = strlen(cot->card_arr[i]); + for(i = 0; i <= cot.card_arr_idx; ++i) { + length = strlen(cot.card_arr[i]); for(j = 0; j < length; ++j, ++*offset) - *(output_buffer + *offset) = cot->card_arr[i][j]; + *(output_buffer + *offset) = cot.card_arr[i][j]; #if 0 - *(output_buffer + *offset) = '\'; + *(output_buffer + *offset) = '\\'; #endif } *(output_buffer + *offset) = ':'; @@ -100,7 +101,7 @@ static void copy_own_deck(int *offset, player_cards deck) length = strlen(card); for(i = 0; i < length; ++i, ++*offset) *(output_buffer + *offset) = card[i]; - *(output_buffer + *offset) = '\'; + *(output_buffer + *offset) = '\\'; deck = deck->next; } *(output_buffer + *offset) = ':'; @@ -108,8 +109,11 @@ static void copy_own_deck(int *offset, player_cards deck) } static void copy_base_info(int *free_pos, struct game_info *gi, - player_cards deck, int player_position) + enum client_game_states state, player_cards deck, + int player_position) { + int i; + *free_pos = sprintf(output_buffer, "%u:%u:%u:%u:%s:", state, gi->players_number, gi->shuffled_cards_left, player_position, gi->trump_suit); @@ -120,56 +124,43 @@ static void copy_base_info(int *free_pos, struct game_info *gi, gi->card_quantity_arr[i]); } if(gi->cot->card_arr_idx != -1) - copy_cards_on_table(free_pos, gi->cot); + copy_cards_on_table(free_pos, *gi->cot); if(!is_empty_stack(deck)) copy_own_deck(free_pos, deck); } int print_game_part(const struct session *client, struct game_info *gi) { - int free_pos, i; /* free_pos == data length */ + int free_pos; /* free_pos == data length */ + + copy_base_info(&free_pos, gi, client->state, client->deck, + client->player_position); switch(client->state) { case display_only_table: - copy_base_info(&free_pos, gi, client->deck, client->player_position); - *(output_buffer + free_pos-1) = '\n'; - break; + /* let the client print card tips and wait for input */ case attack: - /* let the client print card tips and wait for input */ - copy_base_info(&free_pos, gi, client->deck, client->player_position); + case defense: + /* + * who haven't got tossing card (including defender) must wait + * when other players make moves + */ + case tossing_expectation: + case tossing: + /* instead of last ':' */ *(output_buffer + free_pos-1) = '\n'; break; + /* other clents will be waiting particular player */ case attack_expectation: - /* other clents will be waiting particular player */ - copy_base_info(&free_pos, gi, deck, player_position); free_pos += sprintf(output_buffer + free_pos, "%u:", gi->position_whose_turn); - /* instead of last ':' */ - *(output_buffer + free_pos-1) = '\n'; - break; - case defense: - copy_base_info(&free_pos, gi, client->deck, client->player_position); *(output_buffer + free_pos-1) = '\n'; break; case defense_expectation: - copy_base_info(&free_pos, gi, client->deck, client->player_position); free_pos += sprintf(output_buffer + free_pos, "%u:", gi->position_whose_turn); copy_card_queue(&free_pos, gi->cq); *(output_buffer + free_pos-1) = '\n'; - break; - /* - * who haven't got tossing card (including defender) must wait - * when other players make moves - */ - case tossing_expectation: - copy_base_info(&free_pos, gi, client->deck, client->player_position); - *(output_buffer + free_pos-1) = '\n'; - break; - case tossing: - copy_base_info(&free_pos, gi, client->deck, client->player_position); - *(output_buffer + free_pos-1) = '\n'; - break; } return write_to_client(client->fd, free_pos); } @@ -184,7 +175,7 @@ int get_cards_from_attacker(struct session *client, struct card_queue *cq) if(!read_result) return read_result; for(i = 0, j = 0; i < read_result && client->buffer[i] != '\n'; ++i) { - if(read_result[i] == '\') { + if(client->buffer[i] == '\\') { given_card[j] = '\0'; j = 0; stack_card = remove_card_from_stack(&client->deck, given_card); @@ -194,6 +185,7 @@ int get_cards_from_attacker(struct session *client, struct card_queue *cq) given_card[j] = client->buffer[i]; ++j; } + return read_result; } /* @@ -202,7 +194,8 @@ int get_cards_from_attacker(struct session *client, struct card_queue *cq) * defender didn't want to continue defense phase * */ -int get_card_from_defender(struct session *client, struct cards_on_table *cot) +int get_card_from_defender(struct session *client, struct cards_on_table *cot, + const char * trump_suit) { int read_result, i; char given_card[4]; @@ -216,7 +209,7 @@ int get_card_from_defender(struct session *client, struct cards_on_table *cot) if(given_card[0] == '\n') return 1; given_card[i] = '\0'; - if(is_card_bit(cot->card_arr[card_arr_idx-2], given_card)) { + if(is_card_bit(cot->card_arr[cot->card_arr_idx-2], given_card, trump_suit)){ stack_card = remove_card_from_stack(&client->deck, given_card); put_defender_card_on_table(cot, stack_card); return 1; @@ -260,7 +253,7 @@ int get_cards_from_tossing_player(struct session *client, total_defense_cards += find_out_card_quantity_in_deck(defense_deck); for(i = 0, j = 0; i < read_result; ++i) { - if(read_result[i] == '\') { + if(client->buffer[i] == '\\') { /* cancellation */ if(given_card[0] == '\n') return 3; @@ -287,7 +280,7 @@ int get_cards_from_tossing_player(struct session *client, } continue; } - given_card[j] = buffer[i]; + given_card[j] = client->buffer[i]; ++j; } /* 7 -- state for result of received cards */ diff --git a/server_data_processing.h b/server_data_processing.h index f047ada..9ebe5ad 100644 --- a/server_data_processing.h +++ b/server_data_processing.h @@ -5,10 +5,11 @@ int print_message_for_first_player(int fd); int print_connected_players(int fd, int number); -int check_readiness(const struct session *client); +int check_readiness(struct session *client); int print_game_part(const struct session *client, struct game_info *gi); int get_cards_from_attacker(struct session *client, struct card_queue *cq); -int get_card_from_defender(struct session *client, struct cards_on_table *cot); +int get_card_from_defender(struct session *client, struct cards_on_table *cot, + const char *trump_suit); int get_cards_from_tossing_player(struct session *client, const player_cards defense_deck, struct cards_on_table *cot, diff --git a/server_game_process.c b/server_game_process.c index 5f1aacb..99b50fe 100644 --- a/server_game_process.c +++ b/server_game_process.c @@ -4,6 +4,8 @@ #include <string.h> #include <stdio.h> +enum { deck_size = 52 }; + static const char *basic_deck[deck_size] = { "2^", "3^", "4^", "5^", "6^", "7^", "8^", "9^", "10^", "J^", "Q^", "K^", "A^", "2#", @@ -20,10 +22,10 @@ static int get_random_idx() return 0 + (int)((double)deck_size*rand()/(RAND_MAX + 1.0)); } -char** get_shuffled_deck() +const char** get_shuffled_deck() { int i, new_idx; - char **shuffled_deck = realloc(deck_size, sizeof(char*)); + const char **shuffled_deck = calloc(deck_size, sizeof(char*)); for(i = 0; i < deck_size; ++i) { new_idx = get_random_idx(); while(shuffled_deck[new_idx]) @@ -33,10 +35,11 @@ char** get_shuffled_deck() return shuffled_deck; } -void deal_first_cards(char **shuffled_deck, int *cards_left, player_cards *deck) +void deal_first_cards(const char **shuffled_deck, int *cards_left, + player_cards *deck) { int i, last_idx; - char *str; + const char *str; for(i = 0; i < start_deck_size; ++i) { last_idx = *cards_left-1; str = shuffled_deck[last_idx]; @@ -48,6 +51,32 @@ void deal_first_cards(char **shuffled_deck, int *cards_left, player_cards *deck) } } +void deal_cards(const char **shuffled_deck, int *shuffled_cards_left, + struct session **turn_queue, int players_number, + int *card_quantity_arr) +{ + int i, j, key, player_deck_size, card_shortage_quantity, last_idx; + const char *extracted_card = NULL; + + for(i = 0; i < players_number; ++i) { + key = turn_queue[i]->player_position - 1; + player_deck_size = card_quantity_arr[key]; + if(player_deck_size < start_deck_size) { + card_shortage_quantity = start_deck_size - player_deck_size; + 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) + return; + extracted_card = shuffled_deck[last_idx]; + push_stack(&turn_queue[i]->deck, extracted_card); + --*shuffled_cards_left; + shuffled_deck[last_idx] = NULL; + } + } + } +} + const char* find_trump_suit(const char **shuffled_deck, int *cards_left) { const char *trump_suit = NULL; @@ -61,38 +90,44 @@ const char* find_trump_suit(const char **shuffled_deck, int *cards_left) int convert_rank_to_int(const char *card) { - int length, rank = 0; - char str_rand[2]; + int length; + char str_rank[2]; length = strlen(card); /* 10 - the only one of its kind */ if(length == 3) return 10; - strncpy(str_rank, 1); + + str_rank[0] = card[0]; 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; + + 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; } -int find_lowest_trump(player_cards deck, char *trump_suit) +int find_lowest_trump(player_cards deck, const char *trump_suit) { - const char *card; - int lowest_rank = 0; + int length, lowest_rank = 0, current_rank; + const char *suit = NULL; 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; + length = strlen(deck->str); + suit = deck->str + length - 1; + if(*suit == *trump_suit) { + current_rank = convert_rank_to_int(deck->str); + if(!lowest_rank || lowest_rank > current_rank) + lowest_rank = current_rank; } deck = deck->next; } @@ -108,26 +143,35 @@ void shift_turn_queue_by_one(struct session **turn_queue, int size) turn_queue[i-1] = tmp; } +void move_turn_queue_two_players_ahead(struct session **turn_queue, int size) +{ + int i; + + for(i = 0; i < 2; ++i) + shift_turn_queue_by_one(turn_queue, size); +} + void update_card_quantity_arr(struct server *serv) { - int i, j; + int i, player_position_idx; - for(i = 0, j = 0; i < serv->max_sess_arr_size; ++i) + for(i = 0; i < serv->max_sess_arr_size; ++i) if(serv->sess_arr[i]) { - serv->card_quantity_arr[j] = + player_position_idx = serv->sess_arr[i]->player_position - 1; + serv->card_quantity_arr[player_position_idx] = 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 shuffled_cards_left, + const char *trump_suit, int position_whose_turn, struct card_queue *cq, struct cards_on_table *cot) { - struct game_info *gi = malloc(sizeof(game_info)); + struct game_info *gi = malloc(sizeof(struct game_info)); gi->players_number = players_number; gi->card_quantity_arr = card_quantity_arr; gi->shuffled_cards_left = shuffled_cards_left; @@ -166,8 +210,7 @@ int is_card_bit(const char *attack_card, const char *defend_card, /* defender has a trump suit */ } else if(!strcmp(defend_suit, trump_suit)) return 1; - else - return 0; + return 0; } /* * analyze that each attacker card can be beat @@ -176,7 +219,7 @@ 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 i, is_bited_card; + int is_bited_card; struct card_stack_item *next_defend_card; struct card_queue_item *next_attack_card; player_cards involved_cards; @@ -227,7 +270,7 @@ int check_someone_can_toss_card(struct session **turn_queue, { int i, j; struct card_queue_item *attack_card_in_queue; - struct card_stack item *not_defender_card; + struct card_stack_item *not_defender_card; for(i = 0; i < players_quantity; ++i) { /* skipping defender's cards */ @@ -250,7 +293,7 @@ int check_someone_can_toss_card(struct session **turn_queue, } /* checking cards on table */ for(j = cot->card_arr_idx; j >= 0; --j) { - if(cot->card_arr[j] == '-' || cot->card_arr[j] == '\') + if(cot->card_arr[j][0] == '-' || cot->card_arr[j][0] == '\\') continue; not_defender_card = NULL; while((not_defender_card = @@ -269,16 +312,15 @@ int check_someone_can_toss_card(struct session **turn_queue, int check_player_can_toss_card(player_cards deck, struct cards_on_table *cot) { int i; - struct card_stack item *not_defender_card; + 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] == '\') + if(cot->card_arr[i][0] == '-' || cot->card_arr[i][0] == '\\') continue; not_defender_card = NULL; while((not_defender_card = - get_next_card_from_stack(turn_queue[i]->deck, - not_defender_card)) && + get_next_card_from_stack(deck, not_defender_card)) && !check_matched_ranks(cot->card_arr[i], not_defender_card->str)) {} if(not_defender_card) @@ -292,7 +334,7 @@ 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] == '\') + if(cot->card_arr[i][0] == '-' || cot->card_arr[i][0] == '\\') continue; if(check_matched_ranks(cot->card_arr[i], card)) return 1; @@ -309,11 +351,11 @@ void put_all_cards_from_queue_to_table(struct cards_on_table *cot, while(!is_empty_queue(cq)) { card = pop_card_queue(cq); ++cot->card_arr_idx; - cot->card_arr[card_arr_idx] = card; + cot->card_arr[cot->card_arr_idx] = card; ++cot->card_arr_idx; - cot->card_arr[card_arr_idx] = "\\"; + cot->card_arr[cot->card_arr_idx] = "\\"; ++cot->card_arr_idx; - cot->card_arr[card_arr_idx] = "-"; + cot->card_arr[cot->card_arr_idx] = "-"; } } @@ -324,33 +366,34 @@ void put_one_card_from_queue_to_table(struct cards_on_table *cot, card = pop_card_queue(cq); ++cot->card_arr_idx; - cot->card_arr[card_arr_idx] = card; + cot->card_arr[cot->card_arr_idx] = card; ++cot->card_arr_idx; - cot->card_arr[card_arr_idx] = "\\"; + cot->card_arr[cot->card_arr_idx] = "\\"; ++cot->card_arr_idx; - cot->card_arr[card_arr_idx] = "-"; + cot->card_arr[cot->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; + cot->card_arr[cot->card_arr_idx] = card; } void move_all_cards_to_defender(struct cards_on_table *cot, player_cards *deck) { + int i; +#if 0 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 == '\') + if(cot->card_arr[i][0] == '-' || cot->card_arr[i][0] == '\\') continue; - push_stack(deck, card); + push_stack(deck, cot->card_arr[i]); } cot->card_arr_idx = i; } @@ -386,7 +429,7 @@ int calculate_attack_card_quantity_on_table(const struct cards_on_table *cot) return counter; } -int check_all_answers_were_received(const session **turn_queue, int size) +int check_all_answers_were_received(const struct session **turn_queue, int size) { int i; diff --git a/server_game_process.h b/server_game_process.h index 1518c8c..5cddc27 100644 --- a/server_game_process.h +++ b/server_game_process.h @@ -9,46 +9,47 @@ enum { start_deck_size = 6 }; -enum { - max_shuffled_deck_size = 52, - max_card_arr_size = 18 -}; - struct game_info { int players_number; int *card_quantity_arr; int shuffled_cards_left; const char* trump_suit; int position_whose_turn; - struct cards_on_table cot; + struct cards_on_table *cot; struct card_queue *cq; }; -char** get_shuffled_deck(); -void deal_first_cards(char **shuffled_deck, int *cards_left, +const char** get_shuffled_deck(); +void deal_first_cards(const char **shuffled_deck, int *cards_left, player_cards *deck); - -const char* find_trump_suit(char **shuffled_deck, int *cards_left); -int find_lowest_trump(player_cards deck, char *trump); -void shift_turn_queue_to_first(struct session **turn_queue, int size); +void deal_cards(const char **shuffled_deck, int *shuffled_cards_left, + struct session **turn_queue, int players_number, + int *card_quantity_arr); +const char* find_trump_suit(const char **shuffled_deck, int *cards_left); +int find_lowest_trump(player_cards deck, const char *trump); +void shift_turn_queue_by_one(struct session **turn_queue, int size); +void move_turn_queue_two_players_ahead(struct session **turn_queue, int size); void update_card_quantity_arr(struct server *serv); struct game_info* get_new_game_info(int players_number, int *card_quantity_arr, - int shuffled_cards_left, char *trump_suit, - int number_whose_turn); + int shuffled_cards_left, + const char *trump_suit, + int position_whose_turn, + struct card_queue *cq, + struct cards_on_table *cot); int is_card_bit(const char *attack_card, const char *defend_card, const char *trump_suit); -int check_defender_can_defend(struct cards_on_table *cot, - struct player_cards deck, const char *trump_suit); +int check_defender_can_defend(struct card_queue *cq, player_cards deck, + const char *trump_suit); void update_game_info(struct game_info *gi, int players_number, int shuffled_cards_left, int position_whose_turn); int check_someone_can_toss_card(struct session **turn_queue, - int players_quantity, - struct card_queue *cq); + int players_quantity, struct card_queue *cq, + struct cards_on_table *cot); int check_player_can_toss_card(player_cards deck, struct cards_on_table *cot); int is_correct_tossing_card(const char *card, struct cards_on_table *cot); @@ -59,14 +60,14 @@ void put_all_cards_from_queue_to_table(struct cards_on_table *cot, void put_one_card_from_queue_to_table(struct cards_on_table *cot, struct card_queue *cq); -void put_defender_card_on_table(struct cards_on_table *cot, const char *card) +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, - struct card_queue *cq, player_cards *deck); +void move_all_cards_to_defender(struct cards_on_table *cot, player_cards *deck); void remove_cards_from_table(struct cards_on_table *cot); int calculate_defense_card_quantity_on_table(const struct cards_on_table *cot); int calculate_attack_card_quantity_on_table(const struct cards_on_table *cot); -int check_all_answers_were_received(const session **turn_queue, int size); +int check_all_answers_were_received(const struct session **turn_queue, + int size); #endif |