back to scratko.xyz
aboutsummaryrefslogtreecommitdiff
path: root/server_game_process.c
diff options
context:
space:
mode:
authorscratko <m@scratko.xyz>2024-08-02 15:55:08 +0300
committerscratko <m@scratko.xyz>2024-08-02 15:55:08 +0300
commit0733ff24c89c8208b7e5d2789d0913d435b9e0fa (patch)
tree0ae94c1f3ce9d9c76d8bd07d89b9a1ee78a75834 /server_game_process.c
downloaddurak-0733ff24c89c8208b7e5d2789d0913d435b9e0fa.tar.gz
durak-0733ff24c89c8208b7e5d2789d0913d435b9e0fa.tar.bz2
durak-0733ff24c89c8208b7e5d2789d0913d435b9e0fa.zip
Initial commit
Diffstat (limited to 'server_game_process.c')
-rw-r--r--server_game_process.c397
1 files changed, 397 insertions, 0 deletions
diff --git a/server_game_process.c b/server_game_process.c
new file mode 100644
index 0000000..5f1aacb
--- /dev/null
+++ b/server_game_process.c
@@ -0,0 +1,397 @@
+#include "server_game_process.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+static const char *basic_deck[deck_size] = {
+ "2^", "3^", "4^", "5^", "6^", "7^", "8^",
+ "9^", "10^", "J^", "Q^", "K^", "A^", "2#",
+ "3#", "4#", "5#", "6#", "7#", "8#", "9#",
+ "10#", "J#", "Q#", "K#", "A#", "2%", "3%",
+ "4%", "5%", "6%", "7%", "8%", "9%", "10%",
+ "j%", "Q%", "K%", "A%", "2v", "3v", "4v",
+ "5v", "6v", "7v", "8v", "9v", "10v", "Jv",
+ "Qv", "Kv", "Av"
+};
+
+static int get_random_idx()
+{
+ return 0 + (int)((double)deck_size*rand()/(RAND_MAX + 1.0));
+}
+
+char** get_shuffled_deck()
+{
+ int i, new_idx;
+ char **shuffled_deck = realloc(deck_size, sizeof(char*));
+ for(i = 0; i < deck_size; ++i) {
+ new_idx = get_random_idx();
+ while(shuffled_deck[new_idx])
+ new_idx = get_random_idx();
+ shuffled_deck[new_idx] = basic_deck[i];
+ }
+ return shuffled_deck;
+}
+
+void deal_first_cards(char **shuffled_deck, int *cards_left, player_cards *deck)
+{
+ int i, last_idx;
+ char *str;
+ for(i = 0; i < start_deck_size; ++i) {
+ last_idx = *cards_left-1;
+ str = shuffled_deck[last_idx];
+ if(str) {
+ push_stack(deck, str);
+ --*cards_left;
+ shuffled_deck[last_idx] = NULL;
+ }
+ }
+}
+
+const char* find_trump_suit(const char **shuffled_deck, int *cards_left)
+{
+ const char *trump_suit = NULL;
+ trump_suit = shuffled_deck[0] ? shuffled_deck[0] : NULL;
+ if(trump_suit)
+ shuffled_deck[0] = NULL;
+ trump_suit += strlen(trump_suit) - 1;
+ --*cards_left;
+ return trump_suit;
+}
+
+int convert_rank_to_int(const char *card)
+{
+ int length, rank = 0;
+ char str_rand[2];
+
+ length = strlen(card);
+ /* 10 - the only one of its kind */
+ if(length == 3)
+ return 10;
+ strncpy(str_rank, 1);
+ str_rank[1] = '\0';
+ if(!strncmp(str_rank, "J", 1))
+ rank = 11;
+ else if(!strncmp(str_rank, "Q", 1))
+ rank = 12;
+ else if(!strncmp(str_rank, "K", 1))
+ rank = 13;
+ else if(!strncmp(str_rank, "A", 1))
+ rank = 14;
+ else
+ rank = strtol(str_rank, NULL, 10);
+ return rank;
+}
+
+int find_lowest_trump(player_cards deck, char *trump_suit)
+{
+ const char *card;
+ int lowest_rank = 0;
+
+ while(deck) {
+ if(!strncmp(card+length-1, trump_suit, 1)) {
+ lowest_rank = convert_rank_to_int(deck->str);
+ if(!lowest_rank || lowest_rank > rank)
+ lowest_rank = rank;
+ }
+ deck = deck->next;
+ }
+ return lowest_rank;
+}
+
+void shift_turn_queue_by_one(struct session **turn_queue, int size)
+{
+ int i;
+ struct session *tmp = turn_queue[0];
+ for(i = 1; i < size; ++i)
+ turn_queue[i-1] = turn_queue[i];
+ turn_queue[i-1] = tmp;
+}
+
+void update_card_quantity_arr(struct server *serv)
+{
+ int i, j;
+
+ for(i = 0, j = 0; i < serv->max_sess_arr_size; ++i)
+ if(serv->sess_arr[i]) {
+ serv->card_quantity_arr[j] =
+ find_out_card_quantity_in_deck(serv->sess_arr[i]->deck);
+ ++j;
+ }
+}
+
+struct game_info* get_new_game_info(int players_number, int *card_quantity_arr,
+ int shuffled_cards_left, char *trump_suit,
+ int position_whose_turn,
+ struct card_queue *cq,
+ struct cards_on_table *cot)
+
+{
+ struct game_info *gi = malloc(sizeof(game_info));
+ gi->players_number = players_number;
+ gi->card_quantity_arr = card_quantity_arr;
+ gi->shuffled_cards_left = shuffled_cards_left;
+ gi->trump_suit = trump_suit;
+ gi->position_whose_turn = position_whose_turn;
+ gi->cq = cq;
+ gi->cot = cot;
+ return gi;
+}
+
+void update_game_info(struct game_info *gi, int players_number,
+ int shuffled_cards_left, int position_whose_turn)
+{
+ gi->players_number = players_number;
+ gi->shuffled_cards_left = shuffled_cards_left;
+ gi->position_whose_turn = position_whose_turn;
+}
+
+int is_card_bit(const char *attack_card, const char *defend_card,
+ const char *trump_suit)
+{
+ int length, attack_rank, defend_rank;
+ const char *attack_suit, *defend_suit;
+
+ length = strlen(attack_card);
+ attack_suit= attack_card + length - 1;
+ length = strlen(defend_card);
+ defend_suit = defend_card + length - 1;
+
+ /* suits matched */
+ if(!strcmp(attack_suit, defend_suit)) {
+ attack_rank = convert_rank_to_int(attack_card);
+ defend_rank = convert_rank_to_int(defend_card);
+ if(defend_rank > attack_rank)
+ return 1;
+ /* defender has a trump suit */
+ } else if(!strcmp(defend_suit, trump_suit))
+ return 1;
+ else
+ return 0;
+}
+/*
+ * analyze that each attacker card can be beat
+ * TODO: free memory
+ */
+int check_defender_can_defend(struct card_queue *cq,
+ player_cards deck, const char *trump_suit)
+{
+ int i, is_bited_card;
+ struct card_stack_item *next_defend_card;
+ struct card_queue_item *next_attack_card;
+ player_cards involved_cards;
+
+ is_bited_card = 0;
+ init_stack(&involved_cards);
+
+ next_attack_card = NULL;
+ while((next_attack_card = get_next_card_from_queue(cq, next_attack_card))) {
+ /* get first defend card */
+ next_defend_card = NULL;
+ next_defend_card = get_next_card_from_stack(deck, next_defend_card);
+
+ /* stack traversal */
+ while(next_defend_card) {
+ if(is_card_bit(next_attack_card->str, next_defend_card->str,
+ trump_suit))
+ /* if card doesn't meet */
+ if(!find_card_in_stack(involved_cards, next_defend_card->str)) {
+ push_stack(&involved_cards, next_defend_card->str);
+ is_bited_card = 1;
+ break;
+ }
+ get_next_card_from_stack(deck, next_defend_card);
+ }
+ if(is_bited_card)
+ is_bited_card = 0;
+ else
+ return 0;
+ }
+ return 1;
+}
+
+static int check_matched_ranks(const char *attack_card,
+ const char *not_defender_card)
+{
+ int attack_rank, not_defender_rank;
+
+ attack_rank = convert_rank_to_int(attack_card);
+ not_defender_rank = convert_rank_to_int(not_defender_card);
+ return attack_rank == not_defender_rank;
+}
+
+int check_someone_can_toss_card(struct session **turn_queue,
+ int players_quantity,
+ struct card_queue *cq,
+ struct cards_on_table *cot)
+{
+ int i, j;
+ struct card_queue_item *attack_card_in_queue;
+ struct card_stack item *not_defender_card;
+
+ for(i = 0; i < players_quantity; ++i) {
+ /* skipping defender's cards */
+ if(i == 1)
+ continue;
+
+ /* checking card queue of attack cards */
+ attack_card_in_queue = NULL;
+ while((attack_card_in_queue =
+ get_next_card_from_queue(cq, attack_card_in_queue))) {
+ not_defender_card = NULL;
+ while((not_defender_card =
+ get_next_card_from_stack(turn_queue[i]->deck,
+ not_defender_card)) &&
+ !check_matched_ranks(attack_card_in_queue->str,
+ not_defender_card->str))
+ {}
+ if(not_defender_card)
+ return 1;
+ }
+ /* checking cards on table */
+ for(j = cot->card_arr_idx; j >= 0; --j) {
+ if(cot->card_arr[j] == '-' || cot->card_arr[j] == '\')
+ continue;
+ not_defender_card = NULL;
+ while((not_defender_card =
+ get_next_card_from_stack(turn_queue[i]->deck,
+ not_defender_card)) &&
+ !check_matched_ranks(cot->card_arr[j],
+ not_defender_card->str))
+ {}
+ if(not_defender_card)
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int check_player_can_toss_card(player_cards deck, struct cards_on_table *cot)
+{
+ int i;
+ struct card_stack item *not_defender_card;
+
+ /* checking cards on table */
+ for(i = cot->card_arr_idx; i >= 0; --i) {
+ if(cot->card_arr[i] == '-' || cot->card_arr[i] == '\')
+ continue;
+ not_defender_card = NULL;
+ while((not_defender_card =
+ get_next_card_from_stack(turn_queue[i]->deck,
+ not_defender_card)) &&
+ !check_matched_ranks(cot->card_arr[i], not_defender_card->str))
+ {}
+ if(not_defender_card)
+ return 1;
+ }
+ return 0;
+}
+
+int is_correct_tossing_card(const char *card, struct cards_on_table *cot)
+{
+ int i;
+
+ for(i = cot->card_arr_idx; i >= 0; --i) {
+ if(cot->card_arr[i] == '-' || cot->card_arr[i] == '\')
+ continue;
+ if(check_matched_ranks(cot->card_arr[i], card))
+ return 1;
+ }
+ return 0;
+}
+
+/* when defender cannot bit any card */
+void put_all_cards_from_queue_to_table(struct cards_on_table *cot,
+ struct card_queue *cq)
+{
+ const char *card;
+
+ while(!is_empty_queue(cq)) {
+ card = pop_card_queue(cq);
+ ++cot->card_arr_idx;
+ cot->card_arr[card_arr_idx] = card;
+ ++cot->card_arr_idx;
+ cot->card_arr[card_arr_idx] = "\\";
+ ++cot->card_arr_idx;
+ cot->card_arr[card_arr_idx] = "-";
+ }
+}
+
+void put_one_card_from_queue_to_table(struct cards_on_table *cot,
+ struct card_queue *cq)
+{
+ const char *card;
+
+ card = pop_card_queue(cq);
+ ++cot->card_arr_idx;
+ cot->card_arr[card_arr_idx] = card;
+ ++cot->card_arr_idx;
+ cot->card_arr[card_arr_idx] = "\\";
+ ++cot->card_arr_idx;
+ cot->card_arr[card_arr_idx] = "-";
+}
+
+/* it used by defender to bit attack card */
+void put_defender_card_on_table(struct cards_on_table *cot, const char *card)
+{
+ cot->card_arr[card_arr_idx] = card;
+}
+
+void move_all_cards_to_defender(struct cards_on_table *cot, player_cards *deck)
+{
+ const char *card;
+
+#if 0
+ while(!is_empty_queue(cq)) {
+ card = pop_card_queue(cq);
+ push_stack(deck, card);
+ }
+#endif
+ for(i = cot->card_arr_idx; i >= 0; --i) {
+ if(cot->card_arr == '-' || cot->card_arr == '\')
+ continue;
+ push_stack(deck, card);
+ }
+ cot->card_arr_idx = i;
+}
+
+void remove_cards_from_table(struct cards_on_table *cot)
+{
+ cot->card_arr_idx = -1;
+}
+
+int calculate_defense_card_quantity_on_table(const struct cards_on_table *cot)
+{
+ int i, counter = 0;
+
+ for(i = 0; i <= cot->card_arr_idx; ++i) {
+ /* every 3 position meets a defender card */
+ if(!((i+1) % 3)) {
+ if(!strcmp(cot->card_arr[i], "-"))
+ continue;
+ else
+ ++counter;
+ }
+ }
+ return counter;
+}
+
+int calculate_attack_card_quantity_on_table(const struct cards_on_table *cot)
+{
+ int i, counter = 0;
+
+ for(i = 0; i <= cot->card_arr_idx; ++i)
+ if(i == 0 || !(i % 3))
+ ++counter;
+ return counter;
+}
+
+int check_all_answers_were_received(const session **turn_queue, int size)
+{
+ int i;
+
+ for(i = 0; i < size; ++i)
+ if(turn_queue[i]->tm == answer_wait)
+ return 0;
+ return 1;
+}