diff options
| author | Reiner Herrmann <reiner@reiner-h.de> | 2011-01-25 16:12:34 +0100 |
|---|---|---|
| committer | Reiner Herrmann <reiner@reiner-h.de> | 2011-01-25 16:12:34 +0100 |
| commit | c7181ee943069bde7f5d468d11ee63c3a535980d (patch) | |
| tree | 56d8dd1128faa734fd0c63f78e1963d9640128d2 | |
| parent | 72504b3fa304c1bf0731fec80d3b85c5481ee0a2 (diff) | |
finished implementing play_cards function for client/server; added new message type next_action which indicates whether the game is finished or the server will deal new cards
| -rw-r--r-- | src/client_game_states.c | 19 | ||||
| -rw-r--r-- | src/data_store.h | 2 | ||||
| -rw-r--r-- | src/game.c | 22 | ||||
| -rw-r--r-- | src/game_states.h | 8 | ||||
| -rw-r--r-- | src/hand.c | 11 | ||||
| -rw-r--r-- | src/hand.h | 1 | ||||
| -rw-r--r-- | src/net/client.c | 11 | ||||
| -rw-r--r-- | src/net/client.h | 1 | ||||
| -rw-r--r-- | src/net/comm.c | 6 | ||||
| -rw-r--r-- | src/net/comm.h | 1 | ||||
| -rw-r--r-- | src/net/server.c | 25 | ||||
| -rw-r--r-- | src/net/server.h | 2 | ||||
| -rw-r--r-- | src/server_game_states.c | 78 |
13 files changed, 146 insertions, 41 deletions
diff --git a/src/client_game_states.c b/src/client_game_states.c index 142693e..4fa4266 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(); @@ -103,23 +103,20 @@ game_state_t state_client_play_cards(const int sock, const uint8_t round) } } } -#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); @@ -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 @@ -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; +} + @@ -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 7e9a111..335cea6 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; +} + /** * Server side function; start server on specified port * @param[in] port Port on which server should listen @@ -231,3 +246,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; } |
