back to scratko.xyz
aboutsummaryrefslogtreecommitdiff
path: root/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'server.c')
-rw-r--r--server.c307
1 files changed, 170 insertions, 137 deletions
diff --git a/server.c b/server.c
index 74b2a92..5153107 100644
--- a/server.c
+++ b/server.c
@@ -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;