summaryrefslogtreecommitdiff
path: root/web
diff options
context:
space:
mode:
Diffstat (limited to 'web')
-rw-r--r--web/static/sw.js2
-rw-r--r--web/web_control.c35
-rw-r--r--web/web_match.c46
-rw-r--r--web/web_match.h20
-rw-r--r--web/web_prompt.c1
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();
}