#include "web_match.h" #include "match.h" #include #include #include struct match_state *state; struct match_opts *match_opts; static int curr_id = 0; void match_new() { if (state) free_state(); state = calloc(1, sizeof(*state)); state->id = ++curr_id; state->mode = match_opts->mode; state->size_players = 2; state->legs = malloc(state->size_players * sizeof(*(state->legs))); state->player_types = malloc(state->size_players * sizeof(*(state->player_types))); state->comp_undone = malloc(state->size_players * sizeof(*(state->comp_undone))); } void match_add_player(int start_pts, enum player_type type, char *name) { if (state->num_players == state->size_players) { state->size_players += state->size_players ? state->size_players : 1; state->legs = realloc(state->legs, state->size_players * sizeof(*(state->legs))); state->player_types = realloc(state->player_types, state->size_players * sizeof(*(state->player_types))); state->comp_undone = realloc(state->comp_undone, state->size_players * sizeof(*(state->comp_undone))); } state->legs[state->num_players] = leg_init(start_pts, name); state->player_types[state->num_players] = type; state->comp_undone[state->num_players++] = 0; } void free_state() { for (int i = 0; i < state->num_players; ++i) { // undone visits readded before free to avoid memory leak state->legs[i]->n_visits += state->comp_undone[i]; leg_free(state->legs[i]); } free(state->legs); free(state); state = NULL; } void match_opts_free() { free(match_opts); match_opts = NULL; } struct leg *state_active_leg() { return state->legs[state->active_player - 1]; } int match_num_players() { if (state->mode == M_P) return 1; return state->num_players; } int match_winning_player() { for (int i = 0; i < match_num_players(); ++i) { if (state->legs[i]->rem == 0) return i + 1; } return 0; } bool match_is_over() { return match_winning_player() != 0; } int match_prev_player() { if (state->active_player == 1) return match_num_players(); else return state->active_player - 1; } int match_next_player() { if (state->active_player == match_num_players()) return 1; else return state->active_player + 1; } int match_prev_throw_player() { if (match_is_over()) return state->active_player; return match_prev_player(); } bool match_player_is_comp(int pn) { return state->player_types[pn - 1] == PT_COMP; } bool match_first_user_has_thrown() { for (int i = 0, np = match_num_players(); i < np; ++i) { int pn = match_opts->throws_first + i; if (pn > np) pn -= np; if (!match_player_is_comp(pn)) return !!state->legs[pn - 1]->n_visits; } return false; }