back to scratko.xyz
aboutsummaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorscratko <m@scratko.xyz>2024-08-18 01:33:08 +0300
committerscratko <m@scratko.xyz>2024-08-18 01:33:08 +0300
commit9970a2275a56d7835ba0c12a8586dc25cf7ec1cf (patch)
tree914b9353b2df1ba9dec5481fa3e7e6a8462dea5d /client
parent4b2fdc91d42a438193d15840e10851c3847fbe80 (diff)
downloaddurak-9970a2275a56d7835ba0c12a8586dc25cf7ec1cf.tar.gz
durak-9970a2275a56d7835ba0c12a8586dc25cf7ec1cf.tar.bz2
durak-9970a2275a56d7835ba0c12a8586dc25cf7ec1cf.zip
Global fixes v4.0
Removed unnecessary comments. Added resource cleanup for client and server. Changed queue display. Added player indicator. It's possible to quit the game while typing or waiting for a connection. Fixed a bug with determining the limit of card tossing.
Diffstat (limited to 'client')
-rw-r--r--client/card_stack.c65
-rw-r--r--client/client.c42
-rw-r--r--client/printing_game_frames.c45
-rw-r--r--client/verification_client_input.c10
4 files changed, 73 insertions, 89 deletions
diff --git a/client/card_stack.c b/client/card_stack.c
index 6f0a673..fc4057c 100644
--- a/client/card_stack.c
+++ b/client/card_stack.c
@@ -38,36 +38,6 @@ int is_empty_stack(player_cards deck)
return deck == NULL;
}
-#if 0
-static int convert_rank_to_int(const char *card)
-{
- int length;
- char str_rank[2];
-
- length = strlen(card);
- /* 10 - the only one of its kind */
- if(length == 3)
- return 10;
-
- str_rank[0] = card[0];
- str_rank[1] = '\0';
-
- switch(card[0]) {
- case 'J':
- return 11;
- case 'Q':
- return 12;
- case 'K':
- return 13;
- case 'A':
- return 14;
- default:
- return strtol(str_rank, NULL, 10);
- }
- return 0;
-}
-#endif
-
void add_hint_letters_stack(player_cards deck)
{
unsigned char letter = 'a';
@@ -145,30 +115,6 @@ void mark_card_for_attackers_stack(player_cards deck)
if(check_no_attackers_cards_marked(tmp_begin_deck))
mark_all_card_stack(tmp_begin_deck);
}
-#if 0
-static int is_card_beaten(const char *attack_card, const char *defend_card,
- const char *trump_suit)
-{
- int length, attack_rank, defend_rank;
- const char *attack_suit, *defend_suit;
-
- length = strlen(attack_card);
- attack_suit= attack_card + length - 1;
- length = strlen(defend_card);
- defend_suit = defend_card + length - 1;
-
- /* suits matched */
- if(!strcmp(attack_suit, defend_suit)) {
- attack_rank = convert_rank_to_int(attack_card);
- defend_rank = convert_rank_to_int(defend_card);
- if(defend_rank > attack_rank)
- return 1;
- /* defender has a trump suit */
- } else if(!strcmp(defend_suit, trump_suit))
- return 1;
- return 0;
-}
-#endif
void mark_card_for_defenders_stack(player_cards deck,
struct cards_on_table *cot, char *trump_suit)
@@ -186,17 +132,6 @@ void mark_card_for_defenders_stack(player_cards deck,
deck = deck->next;
}
}
-#if 0
-static int check_matched_ranks(const char *attack_card,
- const char *not_defender_card)
-{
- int attack_rank, not_defender_rank;
-
- attack_rank = convert_rank_to_int(attack_card);
- not_defender_rank = convert_rank_to_int(not_defender_card);
- return attack_rank == not_defender_rank;
-}
-#endif
void mark_card_for_tossing_stack(player_cards deck, struct cards_on_table *cot)
{
diff --git a/client/client.c b/client/client.c
index 5d49e1a..66bfb01 100644
--- a/client/client.c
+++ b/client/client.c
@@ -4,7 +4,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
-#include <stdio.h> /* test */
+#include <stdio.h> /* for debug */
#include "client.h"
#include "data_decryption.h"
@@ -12,7 +12,13 @@
#include "verification_client_input.h"
static const char *ip = "127.0.0.1";
-static const int port = 8082;
+static const int port = 1025;
+
+static void clean_up_resources(struct client *cl)
+{
+ free(cl->cc.number_arr);
+ clear_stack(&cl->deck);
+}
static void get_data_from_server(struct client *cl, fd_set *readfds)
{
@@ -24,9 +30,12 @@ static void get_data_from_server(struct client *cl, fd_set *readfds)
if(FD_ISSET(cl->fd, readfds)) {
if(!cl->data_left_in_buffer) {
cl->data_left_in_buffer = read(cl->fd, cl->buffer, max_buffer_size);
- /* end of file -- closed connection */
- if(!cl->data_left_in_buffer)
+ /* end of file -- closed connection (from server) */
+ if(!cl->data_left_in_buffer) {
+ clean_up_resources(cl);
+ pgf_disconnect();
exit(0);
+ }
#ifdef DEBUG
printf("%d\n", cl->data_left_in_buffer);
for(i = 0; i < cl->data_left_in_buffer; ++i)
@@ -47,13 +56,13 @@ static void get_data_from_server(struct client *cl, fd_set *readfds)
cl->total_players = decrypt_get_number(end_p+1, &end_p);
break;
case display_only_table:
- case attack:
- case defense:
case tossing_expectation:
case tossing:
/* last arg will contain pointer to '\n' */
decrypt_set_base_info(cl, end_p+1, &end_p);
break;
+ case attack:
+ case defense:
case attack_expectation:
decrypt_set_base_info(cl, end_p+1, &end_p);
decrypt_set_position_whose_turn(cl, end_p+1, &end_p);
@@ -163,14 +172,26 @@ static void change_client_frame(struct client *cl)
}
}
+static int check_users_exti(enum client_states state, const char *buffer,
+ int size)
+{
+ if((state == first_player || state == confirmation_waiting) &&
+ size == 2 && (buffer[0] == 'q' && buffer[1] == '\n'))
+ return 1;
+
+ return size == 3 && !strncmp(buffer, "qq", 2) && buffer[2] == '\n';
+}
+
static void send_data_to_server(struct client *cl, fd_set *readfds)
{
- int input_result = 0;
+ int input_result = 0, data_size;
if(FD_ISSET(0, readfds)) { /* 0 - stdin */
- read(0, cl->buffer, max_buffer_size);
- if(cl->buffer[0] == 'q' && cl->buffer[1] == 'q') {
+ data_size = read(0, cl->buffer, max_buffer_size);
+ if(check_users_exti(cl->state, cl->buffer, data_size)) {
close(cl->fd);
+ clean_up_resources(cl);
+ pgf_disconnect();
exit(0);
}
@@ -202,6 +223,7 @@ static int check_tracking_client_input(enum client_states state,
return 0;
switch(state) {
+ case first_player:
case confirmation_waiting:
case attack:
case defense:
@@ -246,9 +268,7 @@ static void init_client(struct client *cl)
cl->total_cards_left = 0;
cl->player_position = 0;
cl->cc.number_arr = NULL;
-#if 0
cl->cc.number_arr_idx = -1;
-#endif
cl->cot.card_arr_idx = -1;
cl->deck = NULL;
cl->pending_server_response = 0;
diff --git a/client/printing_game_frames.c b/client/printing_game_frames.c
index bda1208..6b2131a 100644
--- a/client/printing_game_frames.c
+++ b/client/printing_game_frames.c
@@ -2,6 +2,7 @@
#include "card_stack.h"
#include <stdio.h>
+#include <unistd.h>
void pgf_new_frame()
{
@@ -34,29 +35,39 @@ void pgf_first_player()
printf("=======================================\n"
" You're the first player\n"
"Waiting for other players to connect...\n"
+ " Press q <Enter> to exit\n"
"=======================================\n");
}
void pgf_confirmation_waiting(int total_players)
{
printf("=======================================\n"
- " To start game press <Enter> key \n"
- " Connected players: %u/8 \n"
+ " To start game press <Enter> key\n"
+ " Connected players: %u/8\n"
+ " Press q <Enter> to exit\n"
"=======================================\n", total_players);
}
+static int move_indication_condition(const struct client *cl,
+ int current_player)
+{
+ return
+ current_player == cl->position_whose_turn &&
+ (cl->state == attack_expectation || cl->state == defense_expectation ||
+ cl->state == attack || cl->state == defense ||
+ (cl->state == spectator && (cl->sp_mode == spectator_attack ||
+ cl->sp_mode == spectator_defense)));
+}
+
void pgf_table(struct client *cl)
{
struct card_stack_item *deck = NULL;
int i;
for(i = 0; i <= cl->cc.number_arr_idx; ++i)
- /* printing who will move */
- if(cl->state == attack_expectation || cl->state == defense_expectation)
- printf("<%c%u > ", cl->position_whose_turn-1 == i ? '*' : ' ',
- cl->cc.number_arr[i]);
- else
- printf("< %u > ", cl->cc.number_arr[i]);
+ printf("<%s %u %c> ", cl->player_position == i+1 ? "YOU" : " ",
+ cl->cc.number_arr[i], move_indication_condition(cl, i+1) ?
+ '*' : ' ');
printf(" %s [ %u ]", cl->trump_card, cl->total_cards_left);
printf("\n\n\n");
/* ================= cards on table ================ */
@@ -64,7 +75,7 @@ void pgf_table(struct client *cl)
printf(" %s %s %s\n", cl->cot.card_arr[i], cl->cot.card_arr[i+1],
cl->cot.card_arr[i+2]);
/* for the defender, the cards in the queue are hidden */
- if(cl->state == defense_expectation)
+ if(cl->state == defense_expectation || cl->state == spectator)
for(i = 0; i <= cl->cq.card_arr_idx; ++i)
printf(" %s \\ -\n", cl->cq.card_arr[i]);
if(cl->cot.card_arr_idx != -1)
@@ -88,6 +99,7 @@ void pgf_suggestions(struct client *cl)
{
struct card_stack_item *deck = NULL;
+ printf("qq - exit the game\n");
if(cl->state == attack || cl->state == tossing)
printf("you can specify more than one card\n");
deck = cl->deck;
@@ -152,7 +164,20 @@ void pgf_game_result(int durak_position)
"=======================================\n", durak_position);
}
+static void clear_input()
+{
+ int key;
+
+ while((key = getchar()) != '\n')
+ {}
+}
+
void pgf_disconnect()
{
- printf("Server connection disconnected\n");
+ char key;
+
+ printf("Server connection disconnected\n"
+ "Press <Enter> to close program\n");
+ while((key = getchar()) != '\n')
+ clear_input();
}
diff --git a/client/verification_client_input.c b/client/verification_client_input.c
index 171cd64..fa88b54 100644
--- a/client/verification_client_input.c
+++ b/client/verification_client_input.c
@@ -39,6 +39,7 @@ int vci_attack_or_tossing(int fd, char *buffer, player_cards deck,
if(state == tossing && buffer[0] == '\n') { /* cancel card tossing */
write(fd, buffer, 1);
+ printf("skipping the card toss\n");
return 1;
}
@@ -72,9 +73,9 @@ int vci_attack_or_tossing(int fd, char *buffer, player_cards deck,
++free_pos;
}
if(state == attack && buffer[0] == '\n') {
- printf("incorrect input\n> ");
- fflush(stdout);
- return 0;
+ printf("incorrect input\n> ");
+ fflush(stdout);
+ return 0;
}
output_buffer[free_pos] = '\n';
write(fd, output_buffer, free_pos+1);
@@ -92,6 +93,7 @@ int vci_defense(int fd, char *buffer, player_cards deck)
if(buffer[0] == '\n') { /* the player does not want to keep the defense */
write(fd, buffer, 1);
+ printf("accepting cards\n");
return 1;
}
if(buffer[1] != '\n') {
@@ -107,5 +109,7 @@ int vci_defense(int fd, char *buffer, player_cards deck)
return 1;
}
/* card is not found in the deck or cannot be used */
+ printf("incorrect input\n> ");
+ fflush(stdout);
return 0;
}