summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client_game_states.c19
-rw-r--r--src/data_store.h2
-rw-r--r--src/game.c22
-rw-r--r--src/game_states.h8
-rw-r--r--src/hand.c11
-rw-r--r--src/hand.h1
-rw-r--r--src/net/client.c11
-rw-r--r--src/net/client.h1
-rw-r--r--src/net/comm.c6
-rw-r--r--src/net/comm.h1
-rw-r--r--src/net/server.c25
-rw-r--r--src/net/server.h2
-rw-r--r--src/server_game_states.c78
13 files changed, 146 insertions, 41 deletions
diff --git a/src/client_game_states.c b/src/client_game_states.c
index 2b11d51..686acb6 100644
--- a/src/client_game_states.c
+++ b/src/client_game_states.c
@@ -60,7 +60,7 @@ game_state_t state_client_wait_for_open_cards(const int sock)
return STATE_CLIENT_SELECT_OPEN_CARD;; // just for testing
}
-game_state_t state_client_play_cards(const int sock, const uint8_t round)
+game_state_t state_client_play_cards(const int sock)
{
data_store_t *ds = data_store();
@@ -94,23 +94,20 @@ game_state_t state_client_play_cards(const int sock, const uint8_t round)
card_stack_push(cs, c);
}
}
-#if 0
- if (we_have_hand_cards)
+
+ if(hand_count_cards(&ds->hand) > 0) // still cards in hand?
{
return STATE_CLIENT_SELECT_OPEN_CARD;
}
else
{
- receive_next_server_action();
- if (server_action == DEAL_CARDS)
- {
- round++;
- return STATE_CLIENT_WAIT_FOR_CARDS;
- }
- else if (server_action == GAME_FINISHED)
+ 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;
}
-#endif
+ assert(false);
return 1337;
}
diff --git a/src/data_store.h b/src/data_store.h
index 71fedae..b2d75b4 100644
--- a/src/data_store.h
+++ b/src/data_store.h
@@ -1,6 +1,7 @@
#ifndef OXEN_DATA_STORE_H
#define OXEN_DATA_STORE_H
+#include <stdbool.h>
#include "player.h"
#include "table_stacks.h"
#include "hand.h"
@@ -14,6 +15,7 @@ typedef struct
hand_t hand;
uint8_t stack_index;
card selected_card;
+ bool game_finished;
} data_store_t;
data_store_t *data_store(void);
diff --git a/src/game.c b/src/game.c
index e2d8f88..c6341a8 100644
--- a/src/game.c
+++ b/src/game.c
@@ -21,13 +21,14 @@ static void main_loop_client(int sock)
{
bool running = true;
game_state_t state = STATE_CLIENT_WAIT_FOR_HAND_CARDS;
- uint8_t round = 1;
+ uint8_t round = 0;
while(running)
{
switch(state)
{
case STATE_CLIENT_WAIT_FOR_HAND_CARDS:
+ round++;
state = state_client_wait_for_hand_cards(sock, round);
break;
@@ -38,11 +39,14 @@ static void main_loop_client(int sock)
case STATE_CLIENT_WAIT_FOR_OPEN_CARDS:
state = state_client_wait_for_open_cards(sock);
break;
-#if 0
+
case STATE_CLIENT_PLAY_CARDS:
state = state_client_play_cards(sock);
break;
-#endif
+
+ case STATE_CLIENT_GAME_FINISHED:
+ running = false;
+ break;
default:
printf("main_loop_client: entered unknown state\n");
exit(EXIT_FAILURE);
@@ -53,7 +57,7 @@ static void main_loop_client(int sock)
static void main_loop_server(socket_list_t* client_socks)
{
bool running = true;
- uint8_t round = 1;
+ uint8_t round = 0;
game_state_t state = STATE_SERVER_DEAL_HAND_CARDS;
main_stack_t m;
@@ -64,17 +68,21 @@ static void main_loop_server(socket_list_t* client_socks)
switch(state)
{
case STATE_SERVER_DEAL_HAND_CARDS:
+ round++;
state = state_server_deal_hand_cards(client_socks, round, &m);
break;
case STATE_SERVER_WAIT_FOR_OPEN_CARDS:
state = state_server_wait_for_open_cards(client_socks);
break;
-#if 0
+
case STATE_SERVER_PLAY_CARDS:
- state = state_server_play_cards(client_socks, round);
+ state = state_server_play_cards(client_socks, &m);
+ break;
+
+ case STATE_SERVER_GAME_FINISHED:
+ running = false;
break;
-#endif
default:
printf("main_loop_server: entered unknown state\n");
exit(EXIT_FAILURE);
diff --git a/src/game_states.h b/src/game_states.h
index 83950af..980f5ff 100644
--- a/src/game_states.h
+++ b/src/game_states.h
@@ -11,20 +11,22 @@ typedef enum {
STATE_CLIENT_SELECT_OPEN_CARD,
STATE_CLIENT_WAIT_FOR_OPEN_CARDS,
STATE_CLIENT_PLAY_CARDS,
+ STATE_CLIENT_GAME_FINISHED,
// Server states
STATE_SERVER_DEAL_HAND_CARDS,
STATE_SERVER_WAIT_FOR_OPEN_CARDS,
- STATE_SERVER_PLAY_CARDS
+ STATE_SERVER_PLAY_CARDS,
+ STATE_SERVER_GAME_FINISHED
} game_state_t;
game_state_t state_client_wait_for_hand_cards(const int sock, const uint8_t round);
game_state_t state_client_select_open_card(const int sock);
game_state_t state_client_wait_for_open_cards(const int sock);
-game_state_t state_client_play_cards(const int sock, const uint8_t round);
+game_state_t state_client_play_cards(const int sock);
game_state_t state_server_deal_hand_cards(const socket_list_t *client_socks, const uint8_t round, main_stack_t *m);
game_state_t state_server_wait_for_open_cards(const socket_list_t *client_socks);
-game_state_t state_server_play_cards(const socket_list_t *client_socks, const uint8_t round);
+game_state_t state_server_play_cards(const socket_list_t *client_socks, const main_stack_t *m);
#endif // OXEN_GAME_STATES_H
diff --git a/src/hand.c b/src/hand.c
index 3853697..359ed08 100644
--- a/src/hand.c
+++ b/src/hand.c
@@ -24,3 +24,14 @@ void hand_remove_card(hand_t *h, const uint8_t card_index)
h->cards[card_index] = 0;
}
+
+const uint8_t hand_count_cards(const hand_t* h)
+{
+ uint8_t count = 0;
+ for(int i=0; i<MAX_HAND_CARDS; i++)
+ if(h->cards[i] != 0)
+ count++;
+
+ return count;
+}
+
diff --git a/src/hand.h b/src/hand.h
index 8202511..f922ccf 100644
--- a/src/hand.h
+++ b/src/hand.h
@@ -12,5 +12,6 @@ typedef struct
void hand_sort(hand_t *h);
void hand_remove_card(hand_t *h, const uint8_t card_index);
+const uint8_t hand_count_cards(const hand_t* h);
#endif // OXEN_HAND_H
diff --git a/src/net/client.c b/src/net/client.c
index 1768926..0d1686c 100644
--- a/src/net/client.c
+++ b/src/net/client.c
@@ -140,6 +140,17 @@ bool client_parse_selected_card_all(const msg_t *m)
return true;
}
+bool client_parse_next_action(const msg_t *m)
+{
+ assert(m != NULL);
+ assert(m->hdr.payload_length == 1);
+
+ data_store_t *ds = data_store();
+ ds->game_finished = m->payload[0];
+
+ return true;
+}
+
bool client_parse_hello(const msg_t *m)
{
assert(m != NULL);
diff --git a/src/net/client.h b/src/net/client.h
index b15e329..f0ec810 100644
--- a/src/net/client.h
+++ b/src/net/client.h
@@ -17,5 +17,6 @@ bool client_parse_deal_hand(const msg_t *m);
bool client_parse_selected_stack(const msg_t *m);
bool client_parse_initial_stacks(const msg_t *m);
bool client_parse_selected_card_all(const msg_t *m);
+bool client_parse_next_action(const msg_t *m);
#endif // OXEN_CLIENT_H
diff --git a/src/net/comm.c b/src/net/comm.c
index 000c96f..0c7d8e9 100644
--- a/src/net/comm.c
+++ b/src/net/comm.c
@@ -56,6 +56,9 @@ bool net_recv(const int sock, const msg_type_t type)
case msg_type_selected_stack_s:
result = client_parse_selected_stack(&m);
break;
+ case msg_type_next_action:
+ result = client_parse_next_action(&m);
+ break;
default:
printf("net_recv: Unknown message type %d received!\n", type);
exit(EXIT_FAILURE);
@@ -103,6 +106,9 @@ bool net_send(const int sock, const msg_type_t type, const void *data)
case msg_type_selected_card_all:
server_prep_selected_card_all(&m);
break;
+ case msg_type_next_action:
+ server_prep_next_action(&m);
+ break;
default:
printf("net_send: Unknown message type %d given\n", type);
exit(EXIT_FAILURE);
diff --git a/src/net/comm.h b/src/net/comm.h
index a014c6d..b9fff41 100644
--- a/src/net/comm.h
+++ b/src/net/comm.h
@@ -24,6 +24,7 @@ typedef enum
msg_type_selected_card_all = 0x6,
msg_type_selected_stack_c = 0x7,
msg_type_selected_stack_s = 0x8,
+ msg_type_next_action = 0x9,
} msg_type_t;
// Header format
diff --git a/src/net/server.c b/src/net/server.c
index 54601ed..c45c796 100644
--- a/src/net/server.c
+++ b/src/net/server.c
@@ -9,6 +9,21 @@
#include "server.h"
#include "../data_store.h"
+
+/**
+ * Return socket with connection to player with specified player id
+ */
+int socket_for_player_id(const socket_list_t *client_socks, const player_id_t pid)
+{
+ for(int i=0; i<client_socks->count; i++)
+ {
+ if(client_socks->player_ids[i] == pid)
+ return client_socks->sockets[i];
+ }
+ assert(false);
+ return 0;
+}
+
/**
* Starts the server. The server will listen on a specified port.
* @param[in] port Port on which server should listen
@@ -245,3 +260,13 @@ void server_prep_selected_card_all(msg_t *m)
m->hdr.payload_length = pos;
}
+
+void server_prep_next_action(msg_t *m)
+{
+ data_store_t *ds = data_store();
+
+ m->hdr.type = msg_type_next_action;
+ m->payload[0] = ds->game_finished;
+ m->hdr.payload_length = 1;
+}
+
diff --git a/src/net/server.h b/src/net/server.h
index 625f24f..fb1d30b 100644
--- a/src/net/server.h
+++ b/src/net/server.h
@@ -15,6 +15,7 @@ typedef struct
uint8_t player_ids[MAX_PLAYERS];
} socket_list_t;
+int socket_for_player_id(const socket_list_t *client_socks, const player_id_t pid);
int server_start(const char* port);
void server_get_players(int serversock, socket_list_t* client_socks, const uint8_t count);
@@ -24,6 +25,7 @@ void server_prep_deal_hand(msg_t *m, const hand_t *h);
void server_prep_selected_stack(msg_t *m);
void server_prep_initial_stacks(msg_t *m);
void server_prep_selected_card_all(msg_t *m);
+void server_prep_next_action(msg_t *m);
bool server_parse_hello(const msg_t *m);
bool server_parse_selected_card(const msg_t *m);
diff --git a/src/server_game_states.c b/src/server_game_states.c
index 746b4be..c3314ae 100644
--- a/src/server_game_states.c
+++ b/src/server_game_states.c
@@ -39,6 +39,11 @@ game_state_t state_server_deal_hand_cards(const socket_list_t *client_socks, con
net_send(client_socks->sockets[i], msg_type_deal_hand, &h);
}
+ // set own pseudo hand to keep track of number of available hand cards
+ memset(&d->hand.cards, 0, MAX_HAND_CARDS);
+ for(int i=0; i<num_dealcards; i++)
+ d->hand.cards[i] = 1;
+
return STATE_SERVER_WAIT_FOR_OPEN_CARDS;
}
@@ -58,53 +63,86 @@ game_state_t state_server_wait_for_open_cards(const socket_list_t *client_socks)
for(int i = 0; i < d->player_list.count; i++)
net_send(client_socks->sockets[i], msg_type_selected_card_all, NULL);
+ // update local hand for tracking number of cards
+ for(int i=0; i<MAX_HAND_CARDS; i++)
+ {
+ if(d->hand.cards[i] == 1)
+ {
+ d->hand.cards[i] = 0;
+ break;
+ }
+ }
+
+ player_list_sort_by_open_card(&d->player_list, d->player_list.count); // sort in ascending order
+
//return STATE_SERVER_PLAY_CARDS;
return STATE_SERVER_WAIT_FOR_OPEN_CARDS; // just for testing
}
-game_state_t state_server_play_cards(const socket_list_t *client_socks, const uint8_t round)
+game_state_t state_server_play_cards(const socket_list_t *client_socks, const main_stack_t *m)
{
-#if 0
data_store_t *d = data_store();
- foreach(open_card)
+ for(int i=0; i<d->player_list.count; i++)
{
- play_lowest_open_card
+ card c = d->player_list.players[i].open_card;
+ uint8_t stack_idx = get_stack_idx_for_card(&d->table_stacks, c);
+
+ if(stack_idx >= NUM_TABLE_STACKS) // card does not fit on any stack
{
- determine_stack_for_open_card
+ int cur_sock = socket_for_player_id(client_socks, d->player_list.players[i].player_id);
+ net_recv(cur_sock, msg_type_selected_stack_c);
+ for(int j=0; j<client_socks->count; j++) // send received stack to all clients (including the one who sent it)
+ net_send(client_socks->sockets[i], msg_type_selected_stack_s, NULL);
+
+ d->player_list.players[i].score += card_stack_get_points(&d->table_stacks.stacks[d->stack_index]);
+ card_stack_clear(&d->table_stacks.stacks[d->stack_index], c);
+ }
+ else // card fits on a stack -> place it
+ {
+ card_stack_t* cs = &d->table_stacks.stacks[stack_idx];
+ if(cs->cards[MAX_CARD_STACK_SIZE-1] != 0) // stack is full
{
- if (stack_has_to_be_picked) {
- receive_stack_from_client();
- send_received_stack_to_other_clients();
- clear_stack(stack_id);
- }
+ d->player_list.players[i].score += card_stack_get_points(cs);
+ card_stack_clear(cs, c);
}
- place_card()
+ else
{
- if(count_stack_cards == 6)
- clear_stack(stack_id);
+ // put open card on top of stack
+ for(int j=0; j<MAX_CARD_STACK_SIZE; j++)
+ {
+ if(cs->cards[j] != 0)
+ continue;
+ cs->cards[j] = c;
+ break;
+ }
}
}
}
- if (clients_have_hand_cards)
+ if(hand_count_cards(&d->hand) > 0) // still cards in hand?
{
return STATE_SERVER_WAIT_FOR_OPEN_CARDS;
}
else
{
- if (main_stack_has_enough_cards_for_clients)
+ if(main_stack_size(m) > d->player_list.count) // no more cards -> deal new cards
{
- send_action_to_client(DEAL_HAND_CARDS);
- round++;
+ d->game_finished = false;
+ for(int i=0; i<client_socks->count; i++)
+ net_send(client_socks->sockets[i], msg_type_next_action, NULL);
+
return STATE_SERVER_DEAL_HAND_CARDS;
}
- else
+ else // empty main stack -> end game
{
- send_action_to_client(GAME_FINISHED);
+ d->game_finished = false;
+ for(int i=0; i<client_socks->count; i++)
+ net_send(client_socks->sockets[i], msg_type_next_action, NULL);
return STATE_SERVER_GAME_FINISHED;
}
}
-#endif
+
+ assert(false);
return 1337;
}