#include "game.h" #include "card.h" #include "hand.h" #include #include #include #include #include #include #include #include #include "ui.h" #include "global.h" #include "net/comm.h" #include "net/client.h" #include "net/server.h" static void init_mainstack(card *stack, const uint32_t size) { assert(stack != NULL); // assign card values to main stack for(uint32_t i=0, val=MIN_CARD; itable_stacks, false, 0); ui_display_wnd_stack_points(&data->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(&data->hand, false, 0); state = STATE_CLIENT_SELECT_OPEN_CARD; break; case STATE_CLIENT_SELECT_OPEN_CARD: // Select open card open_card_idx = ui_choose_card(&data->hand); data->selected_card = data->hand.cards[open_card_idx]; // Send open card to server net_send(sock, msg_type_selected_card, NULL); state = STATE_CLIENT_WAIT_FOR_OPEN_CARDS; break; case STATE_CLIENT_WAIT_FOR_OPEN_CARDS: net_recv(sock, msg_type_selected_card_all); pnoc_sort(data->players.players, MAX_PLAYERS); // sort in ascending order ui_display_wnd_current_state(data->players.players, MAX_PLAYERS, 0, 0); // TODO fix parameters state = STATE_CLIENT_PLAY_CARDS; sleep(2); return; break; #if 0 case STATE_CLIENT_PLAY_CARDS: foreach(open_card) { play_lowest_open_card { determine_stack_for_open_card { if (stack_has_to_be_picked) { if (we_have_to_pick) { pick_stack(); send_stack_to_server(); } else // another client has to pick { receive_stack(); } clear_stack(stack_id); } } place_card() { if(count_stack_cards == 6) clear_stack(stack_id); } } } if (we_have_hand_cards) { state = STATE_CLIENT_SELECT_OPEN_CARD; } else { receive_next_server_action(); if (server_action == DEAL_CARDS) { round++; state = STATE_CLIENT_WAIT_CARDS; } else if (server_action == GAME_FINISHED) state = STATE_CLIENT_GAME_FINISHED; } break; #endif default: printf("main_loop_client: entered unknown state\n"); exit(EXIT_FAILURE); } } } static void main_loop_server(socket_list_t* client_socks) { bool running = true; uint8_t round = 1; int cards = MAX_CARD - MIN_CARD + 1; card mainstack[cards]; gamestate state = STATE_SERVER_DEAL_HAND_CARDS; data_store *data = datamodel(); srand(time(0)); init_mainstack(mainstack, cards); while(running) { switch(state) { case STATE_SERVER_DEAL_HAND_CARDS: if(round == 1) { // Draw cards for initial stacks and send them to clients data->table_stacks.stacks[0].cards[0] = mainstack_remove_card(mainstack, cards); data->table_stacks.stacks[1].cards[0] = mainstack_remove_card(mainstack, cards); data->table_stacks.stacks[2].cards[0] = mainstack_remove_card(mainstack, cards); data->table_stacks.stacks[3].cards[0] = mainstack_remove_card(mainstack, cards); for(int i = 0; i < data->players.count; i++) { net_send(client_socks->sockets[i], msg_type_initial_stacks, NULL); } } int num_dealcards = num_cards_in_stack(mainstack, cards) / data->players.count; if(num_dealcards > 10) num_dealcards = 10; // Deal hand cards to clients for(int i = 0; i < data->players.count; i++) { hand_t h; memset(h.cards, 0, MAX_HAND_CARDS); for(int j=0; jsockets[i], msg_type_deal_hand, &h); } state = STATE_SERVER_WAIT_FOR_OPEN_CARDS; break; case STATE_SERVER_WAIT_FOR_OPEN_CARDS: // Receive open cards from clients for(int i = 0; i < data->players.count; i++) { pnoc_t* pl = get_pnoc_from_playerid(&data->players, client_socks->player_ids[i]); assert(pl != NULL); net_recv(client_socks->sockets[i], msg_type_selected_card); pl->open_card = data->selected_card; } for(int i=0; iplayers.count; i++) net_send(client_socks->sockets[i], msg_type_selected_card_all, NULL); state = STATE_SERVER_PLAY_CARDS; return; break; #if 0 case STATE_SERVER_PLAY_CARDS: foreach(open_card) { play_lowest_open_card { determine_stack_for_open_card { if (stack_has_to_be_picked) { receive_stack_from_client(); send_received_stack_to_other_clients(); clear_stack(stack_id); } } place_card() { if(count_stack_cards == 6) clear_stack(stack_id); } } } if (clients_have_hand_cards) { state = STATE_SERVER_WAIT_FOR_OPEN_CARDS; } else { if (main_stack_has_enough_cards_for_clients) { send_action_to_client(DEAL_HAND_CARDS); round++; state = STATE_SERVER_DEAL_HAND_CARDS; } else { send_action_to_client(GAME_FINISHED); state = STATE_SERVER_GAME_FINISHED; } } break; #endif default: printf("main_loop_server: entered unknown state\n"); exit(EXIT_FAILURE); } } } void start_game(const bool servermode, const char* addr, const char* port) { assert(addr != NULL && port != NULL); bool server_process = false; if(servermode) { pid_t child = fork(); server_process = (child > 0); } if(server_process) // Start server and connect to localhost { int server_sock; socket_list_t client_socks; uint8_t num_players = 1; data_store* data = datamodel(); // The stack points window uses ts, too, so there is no separate data set // Example data set for current state window pnoc_t pnoc[10] = { {0, "$you", 10}, {1, "1234567890", 23}, {2, "baz", 38}, {3, "foo_bar", 14}, {4, "lolcat", 60}, {5, "blablub123", 15}, {6, "abcdefg", 103}, {7, "hello", 98}, {8, "hornoxe", 33}, {9, "1337nick", 74} }; pnoc_sort(pnoc, 10); const uint32_t score = 10; server_sock = server_start(port); server_get_players(server_sock, &client_socks, num_players); data->players.count = num_players; for(int i=0; iplayers.players[i].player_id = i+1; printf("Player connected: %s\n", data->players.players[i].player_name); } for(int i=0; inickname, "nickname", 10); net_send(sock, msg_type_hello, NULL); net_recv(sock, msg_type_start_game); ui_init(); // Display all windows ui_display_wnd_table_cards(&data->table_stacks, false, 0); ui_display_wnd_stack_points(&data->table_stacks, false, 0); ui_display_wnd_hand_cards(&data->hand, false, 0); main_loop_client(sock); ui_fini(); } }