#include "match.h" #include #include #include struct leg *leg_init(int points) { struct leg *l = calloc(1, sizeof(*l)); l->start = l->rem = points; l->size_visits = 16; l->visits = calloc(l->size_visits, sizeof(*(l->visits))); return l; } void leg_free(struct leg *l) { // readd undone visits before free to avoid memory leak l->n_visits += l->undone_visits; for (int i = 0; i < l->n_visits; ++i) { free(l->visits[i].darts); free(l->visits[i].ccoords); } free(l->visits); free(l); } void leg_grow_visits(struct leg *l) { size_t bytes = l->size_visits * sizeof(*(l->visits)); l->size_visits *= 2; l->visits = realloc(l->visits, 2 * bytes); memset((char *)l->visits + bytes, 0, bytes); } void leg_undo_visit(struct leg *l) { l->rem += l->visits[--l->n_visits].points; ++l->undone_visits; } void leg_redo_visit(struct leg *l) { l->rem = l->visits[l->n_visits++].rem; --l->undone_visits; } struct match *match_init() { struct match *m = calloc(1, sizeof(*m)); m->size_players = 2; m->players = malloc(m->size_players * sizeof(*m->players)); m->legs = malloc(m->size_players * sizeof(*m->legs)); return m; } void match_free(struct match *m) { for (int i = 0; i < m->n_players; ++i) { free(m->players[i].name); leg_free(m->legs[i]); } free(m->players); free(m->legs); free(m); } static void match_grow_players(struct match *m) { m->size_players *= 2; m->players = realloc(m->players, m->size_players * sizeof(*m->players)); m->legs = realloc(m->legs, m->size_players * sizeof(*m->legs)); } void match_add_player(struct match *m, enum player_type type, char *name, int start_pts) { if (m->n_players == m->size_players) match_grow_players(m); int i = m->n_players++; if (!m->starting_player) m->starting_player = i; struct player *p = m->players + i; p->type = type; p->name = strdup(name); m->legs[i] = leg_init(start_pts); } int match_next_player(struct match *m) { if (m->active_player == m->n_players) return 1; else return m->active_player + 1; } int match_prev_player(struct match *m) { if (m->active_player == 1) return m->n_players; else return m->active_player - 1; } int match_prev_throw_player(struct match *m) { int p = match_winning_player(m); return p ? p : match_prev_player(m); } int match_winning_player(struct match *m) { for (int i = 0; i < m->n_players; ++i) { if (m->legs[i]->rem == 0) return i + 1; } return 0; } bool is_points_valid(int pts, int rem) { return pts <= rem && rem - pts != 1 && pts >= 0 && pts <= 180 && pts != 179 && pts != 178 && pts != 176 && pts != 175 && pts != 173 && pts != 172 && pts != 169 && pts != 166 && pts != 163 && (rem - pts != 0 || (pts <= 170 && pts != 168 && pts != 165 && pts != 162 && pts != 159)); }