diff options
-rw-r--r-- | web/static/sw.js | 2 | ||||
-rw-r--r-- | web/web_control.c | 35 | ||||
-rw-r--r-- | web/web_match.c | 46 | ||||
-rw-r--r-- | web/web_match.h | 20 | ||||
-rw-r--r-- | web/web_prompt.c | 1 |
5 files changed, 79 insertions, 25 deletions
diff --git a/web/static/sw.js b/web/static/sw.js index b41daa8..b9a92e6 100644 --- a/web/static/sw.js +++ b/web/static/sw.js @@ -1,5 +1,5 @@ const CACHE_PREFIX = 'dartboat-' -const CACHE_VERSION = '17'; +const CACHE_VERSION = '18'; const CACHE_NAME = `${CACHE_PREFIX}${CACHE_VERSION}`; const CACHE_FILES = [ diff --git a/web/web_control.c b/web/web_control.c index 0c08b40..e89cc8f 100644 --- a/web/web_control.c +++ b/web/web_control.c @@ -15,8 +15,6 @@ #include <emscripten/emscripten.h> -static int curr_match_id = 0; - void set_active_player(int pn) { state->active_player = pn; @@ -37,7 +35,7 @@ void update_user_rem_from_pts(int pts) EMSCRIPTEN_KEEPALIVE void end_boat_visit(int rem, double avg, int match_id) { - if (!state || match_id != curr_match_id) + if (!state || match_id != state->id) return; svg_clear_points(); @@ -53,7 +51,7 @@ void end_boat_visit(int rem, double avg, int match_id) EMSCRIPTEN_KEEPALIVE void draw_boat_throwing(int pts, char *str, double x, double y, int match_id) { - if (!state || match_id != curr_match_id) + if (!state || match_id != state->id) return; char pts_str[10]; @@ -95,18 +93,18 @@ static void schedule_boat_visit_draws(struct leg *l, struct visit *v, memcpy(tmp, str, len_str + 1); EM_ASM({scheduleCCall($0, $1, $2, $3, $4, $5, $6)}, "draw_boat_throwing", delay, - pts, tmp, c.x, c.y, curr_match_id); + pts, tmp, c.x, c.y, state->id); } EM_ASM({scheduleCCall($0, $1, $2, $3, $4)}, "end_boat_visit", - delay_ms * (v->n_darts + 1), l->rem, avg, curr_match_id); + delay_ms * (v->n_darts + 1), l->rem, avg, state->id); } void boat_visit() { struct leg *l = state_active_leg(); - if (state->boat_undone) { - --state->boat_undone; + if (state->comp_undone[state->active_player - 1]) { + --state->comp_undone[state->active_player - 1]; l->rem = l->visits[l->n_visits++].rem; } else { comp_visit(l); @@ -120,7 +118,7 @@ void boat_visit() if (delay_ms) schedule_boat_visit_draws(l, v, avg); else - end_boat_visit(l->rem, avg, curr_match_id); + end_boat_visit(l->rem, avg, state->id); } void handle_next() @@ -181,7 +179,7 @@ static void undo_active() if (match_player_is_comp(state->active_player)) { l->rem += l->visits[--l->n_visits].points; - ++state->boat_undone; + ++state->comp_undone[state->active_player - 1]; } else { struct visit *v = l->visits + --l->n_visits; l->rem += v->points; @@ -250,12 +248,18 @@ void match_mode_selected(int mode) if (mode == M_PVC) { match_opts->p1_name = "User"; match_opts->p2_name = "Computer"; + match_opts->p2_type = PT_COMP; } else if (mode == M_P) { match_opts->p1_name = "Player 1"; match_opts->p2_name = NULL; } else if (mode == M_PVP) { match_opts->p1_name = "Player 1"; match_opts->p2_name = "Player 2"; + } else if (mode == M_CVC) { + match_opts->p1_name = "Computer 1"; + match_opts->p1_type = PT_COMP; + match_opts->p2_name = "Computer 2"; + match_opts->p2_type = PT_COMP; } prompt_match_opts(); @@ -264,13 +268,10 @@ void match_mode_selected(int mode) void start_match() { - if (state) free_state(); // rematch gets us here - ++curr_match_id; - - state = calloc(1, sizeof(*state)); - state->mode = match_opts->mode; - state->legs[0] = leg_init(match_opts->start_pts, match_opts->p1_name); - state->legs[1] = leg_init(match_opts->start_pts, + match_new(); + match_add_player(match_opts->start_pts, match_opts->p1_type, + match_opts->p1_name); + match_add_player(match_opts->start_pts, match_opts->p2_type, match_opts->p2_name ? match_opts->p2_name : "oi"); show_player_info(1); diff --git a/web/web_match.c b/web/web_match.c index aabea4d..bdd049d 100644 --- a/web/web_match.c +++ b/web/web_match.c @@ -8,12 +8,50 @@ 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() { - state->legs[1]->n_visits += state->boat_undone; // avoid memory leak - leg_free(state->legs[0]); - leg_free(state->legs[1]); + 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; } @@ -78,7 +116,7 @@ int match_prev_throw_player() bool match_player_is_comp(int pn) { - return state->mode == M_PVC && pn == 2; + return state->player_types[pn - 1] == PT_COMP; } bool match_first_user_has_thrown() diff --git a/web/web_match.h b/web/web_match.h index ae5eff0..715be76 100644 --- a/web/web_match.h +++ b/web/web_match.h @@ -8,19 +8,31 @@ enum match_mode { M_PVC = M_FIRST, M_P, M_PVP, - M_LAST = M_PVP + M_CVC, + M_LAST = M_CVC +}; + +enum player_type { + PT_USER, + PT_COMP }; struct match_state { + int id; enum match_mode mode; - struct leg *legs[2]; + + struct leg **legs; + enum player_type *player_types; + int *comp_undone; + int num_players, size_players; + int active_player; - int boat_undone; int num_darts; }; struct match_opts { enum match_mode mode; + enum player_type p1_type, p2_type; char *p1_name, *p2_name; int start_pts; int throws_first; @@ -29,6 +41,8 @@ struct match_opts { extern struct match_state *state; extern struct match_opts *match_opts; +void match_new(); +void match_add_player(int start_pts, enum player_type type, char *name); void free_state(); void match_opts_free(); diff --git a/web/web_prompt.c b/web/web_prompt.c index 8e2bd74..9213ca0 100644 --- a/web/web_prompt.c +++ b/web/web_prompt.c @@ -195,6 +195,7 @@ void prompt_select_mode() add_list_opt("Play against computer"); add_list_opt("One-player scoreboard"); add_list_opt("Two-player scoreboard"); + add_list_opt("Computer vs computer"); flush_list_opts(); } |