diff options
-rw-r--r-- | match.c | 50 | ||||
-rw-r--r-- | match.h | 5 | ||||
-rw-r--r-- | web/web_control.c | 57 | ||||
-rw-r--r-- | web/web_match.c | 19 | ||||
-rw-r--r-- | web/web_match.h | 3 |
5 files changed, 76 insertions, 58 deletions
@@ -1,14 +1,15 @@ +#include "comp.h" #include "match.h" #include <stdbool.h> #include <stdlib.h> #include <string.h> -struct leg *leg_init(int points) +struct leg *leg_init(int pts) { struct leg *l = calloc(1, sizeof(*l)); - l->start = l->rem = points; + l->start = l->rem = pts; l->size_visits = 16; l->visits = calloc(l->size_visits, sizeof(*(l->visits))); @@ -36,6 +37,33 @@ void leg_grow_visits(struct leg *l) memset((char *)l->visits + bytes, 0, bytes); } +struct visit *leg_comp_visit(struct leg *l, bool redo_undone) +{ + // FIXME redo_undone=false should free next undone + if (redo_undone && l->undone_visits) + leg_redo_visit(l); + else + comp_visit(l); + + struct visit *v = l->visits + l->n_visits - 1; + return v; +} + +struct visit *leg_pts_visit(struct leg *l, int pts) +{ + if (!is_points_valid(pts, l->rem)) + return NULL; + + if (l->n_visits == l->size_visits) + leg_grow_visits(l); + struct visit *v = l->visits + l->n_visits++; + v->points = pts; + l->rem -= pts; + v->rem = l->rem; + + return v; +} + void leg_undo_visit(struct leg *l) { l->rem += l->visits[--l->n_visits].points; @@ -115,8 +143,8 @@ int match_prev_player(struct match *m) int match_prev_throw_player(struct match *m) { - int p = match_winning_player(m); - return p ? p : match_prev_player(m); + int pn = match_winning_player(m); + return pn ? pn : match_prev_player(m); } int match_winning_player(struct match *m) @@ -129,6 +157,20 @@ int match_winning_player(struct match *m) return 0; } +bool match_first_user_has_thrown(struct match *m) +{ + for (int i = 0; i < m->n_players; ++i) { + int pn = m->starting_player + i; + if (pn > m->n_players) + pn -= m->n_players; + + if (m->players[pn - 1].type == PT_USER) + return !!m->legs[pn - 1]->n_visits; + } + + return false; +} + bool is_points_valid(int pts, int rem) { return pts <= rem && @@ -37,10 +37,12 @@ struct match { struct leg **legs; }; -struct leg *leg_init(int points); +struct leg *leg_init(int pts); void leg_free(struct leg *l); void leg_grow_visits(struct leg *l); +struct visit *leg_comp_visit(struct leg *l, bool redo_undone); +struct visit *leg_pts_visit(struct leg *l, int pts); void leg_undo_visit(struct leg *l); void leg_redo_visit(struct leg *l); @@ -53,6 +55,7 @@ int match_next_player(struct match *m); int match_prev_player(struct match *m); int match_prev_throw_player(struct match *m); int match_winning_player(struct match *m); +bool match_first_user_has_thrown(struct match *m); bool is_points_valid(int pts, int rem); diff --git a/web/web_control.c b/web/web_control.c index 96c455e..a7a53cf 100644 --- a/web/web_control.c +++ b/web/web_control.c @@ -28,9 +28,9 @@ void set_active_player(int pn) void update_user_rem_from_pts(int pts) { - update_player_rem(state->m->active_player, - state_active_leg()->rem - pts); - scoreboard_flush_player_info(state->m->active_player); + int pn = state->m->active_player; + update_player_rem(pn, state->m->legs[pn - 1]->rem - pts); + scoreboard_flush_player_info(pn); } EMSCRIPTEN_KEEPALIVE @@ -58,17 +58,18 @@ void draw_boat_throwing(int pts, char *str, double x, double y, int match_id) char pts_str[10]; sprintf(pts_str, "%d", pts); - struct leg *l = state_active_leg(); + int pn = state->m->active_player; + struct leg *l = state->m->legs[pn - 1]; int rem = l->n_visits > 1 ? l->visits[l->n_visits-2].rem : l->start; svg_draw_point(x, y); - update_player_rem(state->m->active_player, rem - pts); + update_player_rem(pn, rem - pts); prompt_set_input(pts_str); prompt_set_msgr(str); free(str); prompt_flush(); - scoreboard_flush_player_info(state->m->active_player); + scoreboard_flush_player_info(pn); } static void schedule_boat_visit_draws(struct leg *l, struct visit *v, @@ -103,13 +104,9 @@ static void schedule_boat_visit_draws(struct leg *l, struct visit *v, void boat_visit() { - struct leg *l = state_active_leg(); - if (l->undone_visits) - leg_redo_visit(l); - else - comp_visit(l); + struct leg *l = state->m->legs[state->m->active_player - 1]; + struct visit *v = leg_comp_visit(l, true); - struct visit *v = l->visits + l->n_visits - 1; double avg = v->rem > 0 ? (double)(l->start - l->rem) / l->n_visits : (double)l->start / (((l->n_visits - 1) * 3) + v->n_darts) * 3; @@ -147,22 +144,18 @@ void handle_next() void user_visit(int points) { - if (!is_points_valid(points, state_active_leg()->rem)) { + int pn = state->m->active_player; + struct leg *l = state->m->legs[pn - 1]; + struct visit *v = leg_pts_visit(l, points); + + if (!v) { oi(); return; } - struct leg *l = state_active_leg(); - if (l->n_visits == l->size_visits) - leg_grow_visits(l); - struct visit *v = l->visits + l->n_visits++; - v->points = points; - l->rem -= points; - v->rem = l->rem; - update_player_rem(state->m->active_player, l->rem); - + update_player_rem(pn, v->rem); if (v->rem > 0) - update_player_avg(state->m->active_player, 0); + update_player_avg(pn, 0); draw_visits(); handle_next(); @@ -170,34 +163,36 @@ void user_visit(int points) void user_visit_to_rem(int rem) { - user_visit(state_active_leg()->rem - rem); + user_visit(state->m->legs[state->m->active_player - 1]->rem - rem); } static void undo_active() { - struct leg *l = state_active_leg(); + int pn = state->m->active_player; + struct leg *l = state->m->legs[pn - 1]; leg_undo_visit(l); - update_player_avg(state->m->active_player, 0); - update_player_rem(state->m->active_player, l->rem); + update_player_avg(pn, 0); + update_player_rem(pn, l->rem); state->m->active_player = match_prev_throw_player(state->m); } void user_undo() { - if (!match_first_user_has_thrown()) { + if (!match_first_user_has_thrown(state->m)) { oi(); return; } if (state->num_darts) { state->num_darts = 0; - struct leg *l = state_active_leg(); - scoreboard_set_player_avg(state->m->active_player, + int pn = state->m->active_player; + struct leg *l = state->m->legs[pn - 1]; + scoreboard_set_player_avg(pn, ((double)(l->start - l->visits[l->n_visits-2].rem) / (l->n_visits - 1))); - scoreboard_set_player_active(state->m->active_player); + scoreboard_set_player_active(pn); handle_next(); return; } diff --git a/web/web_match.c b/web/web_match.c index d4dac50..93ebf76 100644 --- a/web/web_match.c +++ b/web/web_match.c @@ -83,26 +83,7 @@ void match_opts_free() match_opts = NULL; } -struct leg *state_active_leg() -{ - return state->m->legs[state->m->active_player - 1]; -} - bool match_player_is_comp(int pn) { return state->m->players[pn - 1].type == PT_COMP; } - -bool match_first_user_has_thrown() -{ - for (int i = 0, np = state->m->n_players; i < np; ++i) { - int pn = match_opts->throws_first + i; - if (pn > np) - pn -= np; - - if (!match_player_is_comp(pn)) - return !!state->m->legs[pn - 1]->n_visits; - } - - return false; -} diff --git a/web/web_match.h b/web/web_match.h index 04664f4..c2a4d5a 100644 --- a/web/web_match.h +++ b/web/web_match.h @@ -33,9 +33,6 @@ void match_opts_add_player(enum player_type type, char *name); void match_opts_remove_player(int pn); void match_opts_free(); -struct leg *state_active_leg(); - bool match_player_is_comp(int pn); -bool match_first_user_has_thrown(); #endif |