back to scratko.xyz
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile17
-rw-r--r--card_queue.c13
-rw-r--r--card_queue.h2
-rw-r--r--card_stack.c6
-rw-r--r--card_stack.h8
-rw-r--r--server.c307
-rw-r--r--server.h16
-rw-r--r--server_data_processing.c83
-rw-r--r--server_data_processing.h5
-rw-r--r--server_game_process.c147
-rw-r--r--server_game_process.h45
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
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;
diff --git a/server.h b/server.h
index 787d767..a97109f 100644
--- a/server.h
+++ b/server.h
@@ -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