summaryrefslogtreecommitdiff
path: root/src/client_game_states.c
blob: 49870ed581cfcb2171c3e621c3233d5e44886a38 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "game_states.h"
#include "net/comm.h"
#include "ui.h"
#include "data_store.h"

game_state_t state_client_wait_for_hand_cards(const int sock, const uint8_t round)
{
	data_store_t *d = data_store();

	ui_display_wnd_messages("Waiting for hand cards from server");

	if(round == 1)
	{
		// Receive and display table stacks
		net_recv(sock, msg_type_initial_stacks);
		ui_display_wnd_table_cards(&d->table_stacks, false, 0);
		ui_display_wnd_stack_points(&d->table_stacks, false, 0);
	}

	// Wait for hand cards from server and display them
	net_recv(sock, msg_type_deal_hand);
	ui_display_wnd_hand_cards(&d->hand, false, 0);

	return STATE_CLIENT_SELECT_OPEN_CARD;
}

game_state_t state_client_select_open_card(const int sock)
{
	data_store_t *d = data_store();
	uint8_t open_card_idx;

	ui_display_wnd_messages("Please choose the card you want to play");

	// Select open card
	open_card_idx = ui_choose_card(&d->hand);
	d->selected_card = d->hand.cards[open_card_idx];

	// Send open card to server
	net_send(sock, msg_type_selected_card, NULL);

	// Remove picked open card from hand
	hand_remove_card(&d->hand, open_card_idx);
	ui_display_wnd_hand_cards(&d->hand, false, 0);

	return STATE_CLIENT_WAIT_FOR_OPEN_CARDS;
}

game_state_t state_client_wait_for_open_cards(const int sock)
{
	data_store_t *d = data_store();

	ui_display_wnd_messages("Waiting for the other players to pick  their cards"); // The two spaces between 'pick' and 'their' are intentionally and used for poor man's word wrap

	net_recv(sock, msg_type_selected_card_all);
	player_list_sort_by_open_card(&d->player_list, d->player_list.count); // sort in ascending order

	player_list_entry_t *ple = get_player_list_entry_by_player_id(&d->player_list, d->own_player_id);
	assert(ple != NULL);
	ui_display_wnd_current_state(&d->player_list, d->player_list.count, false, 0, ple->score);

	return STATE_CLIENT_PLAY_CARDS;
}

game_state_t state_client_play_cards(const int sock)
{
	data_store_t *ds = data_store();
	player_list_entry_t *ple = get_player_list_entry_by_player_id(&ds->player_list, ds->own_player_id);
	assert(ple != NULL);

	for(int i=0; i<ds->player_list.count; i++)
	{
		card c = ds->player_list.players[i].open_card;
		uint8_t stack_idx = get_stack_idx_for_card(&ds->table_stacks, c);
		bool our_turn = (ds->player_list.players[i].player_id == ds->own_player_id);

		ui_display_wnd_current_state(&ds->player_list, ds->player_list.count, true, i, ple->score);

		if(stack_idx >= NUM_TABLE_STACKS) // card does not fit on any stack
		{
			if(our_turn) // our turn to select stack
			{
				ui_display_wnd_messages("Please choose a stack");
				ds->stack_index = ui_choose_stack(&ds->table_stacks);
				net_send(sock, msg_type_selected_stack_c, NULL);
			}

			ui_display_wnd_messages("Waiting for chosen stack");
			net_recv(sock, msg_type_selected_stack_s);
			ds->player_list.players[i].score += card_stack_get_points(&ds->table_stacks.stacks[ds->stack_index]);
			card_stack_replace(&ds->table_stacks.stacks[ds->stack_index], c);

			ui_display_wnd_table_cards(&ds->table_stacks, false, 0);
			ui_display_wnd_stack_points(&ds->table_stacks, false, 0);

			// If it was our turn, display the score
			if(our_turn)
			{
				ui_display_wnd_current_state(&ds->player_list, ds->player_list.count, true, i, ple->score);
			}
		}
		else // card fits on a stack -> place it
		{
			card_stack_t* cs = &ds->table_stacks.stacks[stack_idx];
			if(cs->cards[MAX_CARD_STACK_SIZE-1] != 0) // stack is full
			{
				ds->player_list.players[i].score += card_stack_get_points(cs);
				card_stack_replace(cs, c);

				// If it was our turn, display the score
				if(our_turn)
				{
					ui_display_wnd_current_state(&ds->player_list, ds->player_list.count, true, i, ple->score);
				}
			}
			else
				card_stack_push(cs, c);

			ui_display_wnd_table_cards(&ds->table_stacks, false, 0);
			ui_display_wnd_stack_points(&ds->table_stacks, false, 0);
		}

		// Wait between player turns, but not after the last one
		if (i != ds->player_list.count - 1)
		sleep(3);
	}

	if(hand_count_cards(&ds->hand) > 0) // still cards in hand?
	{
		return STATE_CLIENT_SELECT_OPEN_CARD;
	}
	else
	{
		net_recv(sock, msg_type_next_action);
		if(!ds->game_finished) // no more cards -> server will deal
			return STATE_CLIENT_WAIT_FOR_HAND_CARDS;
		else
			return STATE_CLIENT_GAME_FINISHED;
	}

	assert(false);
	return 1337;
}