summaryrefslogtreecommitdiff
path: root/web
diff options
context:
space:
mode:
authorDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2022-05-23 15:23:48 -0700
committerDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2022-05-23 15:25:07 -0700
commit15ff00e056a98ab4210dde3d4461a88849d6c1d4 (patch)
tree280b8d248baee5d2ae0dcc2117e3f2b309d128ec /web
parentc93897ed2013f20d6ece33815971d206fd0d056e (diff)
downloaddartboat-15ff00e056a98ab4210dde3d4461a88849d6c1d4.tar.gz
dartboat-15ff00e056a98ab4210dde3d4461a88849d6c1d4.tar.xz
move a bunch of general match logic from web to lib
Diffstat (limited to 'web')
-rw-r--r--web/static/sw.js2
-rw-r--r--web/web_control.c79
-rw-r--r--web/web_match.c85
-rw-r--r--web/web_match.h18
-rw-r--r--web/web_prompt.c5
-rw-r--r--web/web_scoreboard.c63
6 files changed, 80 insertions, 172 deletions
diff --git a/web/static/sw.js b/web/static/sw.js
index 3b2d49b..56f5626 100644
--- a/web/static/sw.js
+++ b/web/static/sw.js
@@ -1,5 +1,5 @@
const CACHE_PREFIX = 'dartboat-'
-const CACHE_VERSION = '21';
+const CACHE_VERSION = '22';
const CACHE_NAME = `${CACHE_PREFIX}${CACHE_VERSION}`;
const CACHE_FILES = [
diff --git a/web/web_control.c b/web/web_control.c
index c561250..d06e17e 100644
--- a/web/web_control.c
+++ b/web/web_control.c
@@ -17,7 +17,7 @@
void set_active_player(int pn)
{
- state->active_player = pn;
+ state->m->active_player = pn;
scoreboard_set_player_active(pn);
if (match_player_is_comp(pn))
@@ -28,8 +28,9 @@ void set_active_player(int pn)
void update_user_rem_from_pts(int pts)
{
- update_player_rem(state->active_player, state_active_leg()->rem - pts);
- scoreboard_flush_player_info(state->active_player);
+ update_player_rem(state->m->active_player,
+ state_active_leg()->rem - pts);
+ scoreboard_flush_player_info(state->m->active_player);
}
EMSCRIPTEN_KEEPALIVE
@@ -39,8 +40,8 @@ void end_boat_visit(int rem, double avg, int match_id)
return;
svg_clear_points();
- update_player_rem(state->active_player, rem);
- scoreboard_set_player_avg(state->active_player, avg);
+ update_player_rem(state->m->active_player, rem);
+ scoreboard_set_player_avg(state->m->active_player, avg);
prompt_set_input(NULL);
prompt_set_msgr(NULL);
@@ -61,13 +62,13 @@ void draw_boat_throwing(int pts, char *str, double x, double y, int match_id)
int rem = l->n_visits > 1 ? l->visits[l->n_visits-2].rem : l->start;
svg_draw_point(x, y);
- update_player_rem(state->active_player, rem - pts);
+ update_player_rem(state->m->active_player, rem - pts);
prompt_set_input(pts_str);
prompt_set_msgr(str);
free(str);
prompt_flush();
- scoreboard_flush_player_info(state->active_player);
+ scoreboard_flush_player_info(state->m->active_player);
}
static void schedule_boat_visit_draws(struct leg *l, struct visit *v,
@@ -103,12 +104,10 @@ static void schedule_boat_visit_draws(struct leg *l, struct visit *v,
void boat_visit()
{
struct leg *l = state_active_leg();
- if (state->comp_undone[state->active_player - 1]) {
- --state->comp_undone[state->active_player - 1];
- l->rem = l->visits[l->n_visits++].rem;
- } else {
+ if (l->undone_visits)
+ leg_redo_visit(l);
+ else
comp_visit(l);
- }
struct visit *v = l->visits + l->n_visits - 1;
double avg = v->rem > 0 ?
@@ -123,21 +122,22 @@ void boat_visit()
void handle_next()
{
+ int wp;
+
if (!state) {
prompt_main_menu();
- } else if (match_is_over()) {
- if (state->num_darts ||
- match_player_is_comp(match_winning_player()))
+ } else if ((wp = match_winning_player(state->m))) {
+ if (state->num_darts || match_player_is_comp(wp))
prompt_end_match();
else
prompt_num_darts();
} else {
- if (state->active_player)
- set_active_player(match_next_player());
+ if (state->m->active_player)
+ set_active_player(match_next_player(state->m));
else
set_active_player(match_opts->throws_first);
- if (match_player_is_comp(state->active_player))
+ if (match_player_is_comp(state->m->active_player))
boat_visit();
}
@@ -159,10 +159,10 @@ void user_visit(int points)
v->points = points;
l->rem -= points;
v->rem = l->rem;
- update_player_rem(state->active_player, l->rem);
+ update_player_rem(state->m->active_player, l->rem);
if (v->rem > 0)
- update_player_avg(state->active_player, 0);
+ update_player_avg(state->m->active_player, 0);
draw_visits();
handle_next();
@@ -176,20 +176,12 @@ void user_visit_to_rem(int rem)
static void undo_active()
{
struct leg *l = state_active_leg();
+ leg_undo_visit(l);
- if (match_player_is_comp(state->active_player)) {
- l->rem += l->visits[--l->n_visits].points;
- ++state->comp_undone[state->active_player - 1];
- } else {
- struct visit *v = l->visits + --l->n_visits;
- l->rem += v->points;
- memset(v, 0, sizeof(*v));
- }
-
- update_player_avg(state->active_player, 0);
- update_player_rem(state->active_player, l->rem);
+ update_player_avg(state->m->active_player, 0);
+ update_player_rem(state->m->active_player, l->rem);
- state->active_player = match_prev_throw_player();
+ state->m->active_player = match_last_player_to_throw(state->m);
}
void user_undo()
@@ -202,16 +194,16 @@ void user_undo()
if (state->num_darts) {
state->num_darts = 0;
struct leg *l = state_active_leg();
- scoreboard_set_player_avg(state->active_player,
+ scoreboard_set_player_avg(state->m->active_player,
((double)(l->start - l->visits[l->n_visits-2].rem) /
(l->n_visits - 1)));
- scoreboard_set_player_active(state->active_player);
+ scoreboard_set_player_active(state->m->active_player);
handle_next();
return;
}
- state->active_player = match_prev_throw_player();
- while (match_player_is_comp(state->active_player))
+ state->m->active_player = match_last_player_to_throw(state->m);
+ while (match_player_is_comp(state->m->active_player))
undo_active();
undo_active();
@@ -227,7 +219,7 @@ void user_num_darts(int n)
}
state->num_darts = n;
- update_player_avg(state->active_player, n);
+ update_player_avg(state->m->active_player, n);
handle_next();
}
@@ -237,14 +229,15 @@ void start_match()
match_new();
for (int i = 0; i < match_opts->num_players; ++i)
- match_add_player(match_opts->start_pts,
+ match_add_player(state->m,
match_opts->players[i].type,
- match_opts->players[i].name);
+ match_opts->players[i].name,
+ match_opts->start_pts);
- scoreboard_show_info(match_num_players());
- for (int i = 1; i <= match_num_players(); ++i) {
- update_player_name(i, state->legs[i - 1]->name);
- update_player_rem(i, state->legs[i - 1]->rem);
+ scoreboard_show_info(state->m->n_players);
+ for (int i = 1; i <= state->m->n_players; ++i) {
+ update_player_name(i, state->m->players[i - 1].name);
+ update_player_rem(i, state->m->legs[i - 1]->rem);
update_player_avg(i, 0);
}
diff --git a/web/web_match.c b/web/web_match.c
index 58b0aca..d4dac50 100644
--- a/web/web_match.c
+++ b/web/web_match.c
@@ -17,41 +17,12 @@ void match_new()
state = calloc(1, sizeof(*state));
state->id = ++curr_id;
-
- 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;
+ state->m = match_init();
}
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->m);
free(state);
state = NULL;
}
@@ -114,67 +85,23 @@ void match_opts_free()
struct leg *state_active_leg()
{
- return state->legs[state->active_player - 1];
-}
-
-int match_num_players()
-{
- 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();
+ return state->m->legs[state->m->active_player - 1];
}
bool match_player_is_comp(int pn)
{
- return state->player_types[pn - 1] == PT_COMP;
+ return state->m->players[pn - 1].type == PT_COMP;
}
bool match_first_user_has_thrown()
{
- for (int i = 0, np = match_num_players(); i < np; ++i) {
+ 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->legs[pn - 1]->n_visits;
+ return !!state->m->legs[pn - 1]->n_visits;
}
return false;
diff --git a/web/web_match.h b/web/web_match.h
index 8fb2056..04664f4 100644
--- a/web/web_match.h
+++ b/web/web_match.h
@@ -3,20 +3,11 @@
#include "match.h"
-enum player_type {
- PT_USER,
- PT_COMP
-};
-
struct match_state {
int id;
- struct leg **legs;
- enum player_type *player_types;
- int *comp_undone;
- int num_players, size_players;
+ struct match *m;
- int active_player;
int num_darts;
};
@@ -36,7 +27,6 @@ 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_new();
void match_opts_add_player(enum player_type type, char *name);
@@ -45,12 +35,6 @@ void match_opts_free();
struct leg *state_active_leg();
-int match_num_players();
-int match_winning_player();
-bool match_is_over();
-int match_prev_player();
-int match_next_player();
-int match_prev_throw_player();
bool match_player_is_comp(int pn);
bool match_first_user_has_thrown();
diff --git a/web/web_prompt.c b/web/web_prompt.c
index 86cc97f..37745e8 100644
--- a/web/web_prompt.c
+++ b/web/web_prompt.c
@@ -399,7 +399,8 @@ void prompt_comp_visit()
set_prompt_mode(PM_DARTBOARD);
char buf[64];
- sprintf(buf, "%s is throwing…", state_active_leg()->name);
+ sprintf(buf, "%s is throwing…",
+ state->m->players[state->m->active_player - 1].name);
prompt_set_msgl(buf);
prompt_set_msgr(NULL);
}
@@ -421,7 +422,7 @@ void prompt_end_match()
char buf[64];
sprintf(buf, "%s wins.",
- state->legs[match_winning_player() - 1]->name);
+ state->m->players[match_winning_player(state->m) - 1].name);
prompt_set_msgl(buf);
prompt_set_msgr(NULL);
diff --git a/web/web_scoreboard.c b/web/web_scoreboard.c
index 2916ae8..907b1e5 100644
--- a/web/web_scoreboard.c
+++ b/web/web_scoreboard.c
@@ -75,7 +75,7 @@ void scoreboard_prev_slot()
for (int i = NUM_SLOTS; i > 1; --i)
set_slot_player(i, slots[i - 2]);
int prev = slots[0];
- set_slot_player(1, prev == 1 ? match_num_players() : prev - 1);
+ set_slot_player(1, prev == 1 ? state->m->n_players : prev - 1);
set_slot_active(player_slot(active_pn));
}
@@ -85,7 +85,7 @@ void scoreboard_next_slot()
for (int i = 1; i < NUM_SLOTS; ++i)
set_slot_player(i, slots[i]);
int prev = slots[NUM_SLOTS - 1];
- set_slot_player(NUM_SLOTS, prev == match_num_players() ? 1 : prev + 1);
+ set_slot_player(NUM_SLOTS, prev == state->m->n_players ? 1 : prev + 1);
set_slot_active(player_slot(active_pn));
}
@@ -98,7 +98,7 @@ void scoreboard_set_player_active(int pn)
return;
}
- int np = match_num_players();
+ int np = state->m->n_players;
if (np > NUM_SLOTS) {
for (int i = 0; i < NUM_SLOTS; ++i)
set_slot_player(i + 1, ((pn + i - 1) % np) + 1);
@@ -202,7 +202,7 @@ static double calc_avg(struct leg *l, int n_darts) {
void update_player_avg(int pn, int n_darts)
{
- struct leg *l = state->legs[pn-1];
+ struct leg *l = state->m->legs[pn-1];
scoreboard_set_player_avg(pn, calc_avg(l, n_darts));
}
@@ -284,13 +284,13 @@ void draw_visits_dense()
dom_set_content("#visits", NULL);
dom_add_class("#visits", "dense");
- int np = match_num_players();
+ int np = state->m->n_players;
dom_set_style_property_int("--num-players", np);
int n_visits = 0;
for (int i = 0; i < np; ++i) {
- if (state->legs[i]->n_visits > n_visits)
- n_visits = state->legs[i]->n_visits;
+ if (state->m->legs[i]->n_visits > n_visits)
+ n_visits = state->m->legs[i]->n_visits;
}
struct dom_elem **elemv = malloc(
@@ -301,7 +301,7 @@ void draw_visits_dense()
elemv[elemc++] = create_div("", "");
for (int i = 0; i < np; ++i) {
sprintf(buf, "visit-name visit-name-%d", i + 1);
- elemv[elemc++] = create_div(state->legs[i]->name, buf);
+ elemv[elemc++] = create_div(state->m->players[i].name, buf);
}
elemv[elemc++] = create_div("0", "visit-n");
@@ -310,7 +310,7 @@ void draw_visits_dense()
elemv[elemc++] = create_div("", "throws-first");
else
elemv[elemc++] = create_div("", "");
- snprintf(buf, sizeof(buf), "%d", state->legs[i]->start);
+ snprintf(buf, sizeof(buf), "%d", state->m->legs[i]->start);
elemv[elemc++] = create_div(buf, "");
}
@@ -319,13 +319,13 @@ void draw_visits_dense()
elemv[elemc++] = create_div(buf, "visit-n");
for (int j = 0; j < np; ++j) {
- if (i >= state->legs[j]->n_visits) {
+ if (i >= state->m->legs[j]->n_visits) {
elemv[elemc++] = create_div("", "");
elemv[elemc++] = create_div("", "");
continue;
}
- struct visit *v = state->legs[j]->visits + i;
+ struct visit *v = state->m->legs[j]->visits + i;
snprintf(buf, sizeof(buf), "%d", v->points);
snprintf(buf2, sizeof(buf2), "%s",
@@ -338,21 +338,21 @@ void draw_visits_dense()
bool n_darts = false;
for (int j = 0; j < np; ++j) {
- if (i < state->legs[j]->n_visits &&
- state->legs[j]->visits[i].n_darts)
+ if (i < state->m->legs[j]->n_visits &&
+ state->m->legs[j]->visits[i].n_darts)
n_darts = true;
}
if (!n_darts) continue;
elemv[elemc++] = create_div("", "");
for (int j = 0; j < np; ++j) {
- if (i >= state->legs[j]->n_visits) {
+ if (i >= state->m->legs[j]->n_visits) {
elemv[elemc++] = create_div("",
"visit-dense-darts");
continue;
}
- struct visit *v = state->legs[j]->visits + i;
+ struct visit *v = state->m->legs[j]->visits + i;
if (v->n_darts) {
buf_darts(buf, sizeof(buf), v);
@@ -371,14 +371,15 @@ void draw_visits_dense()
free(elemv);
dom_scroll_to_bottom("#visits");
- int pn = match_is_over() ? state->active_player : match_next_player();
+ int pn = match_winning_player(state->m);
+ if (!pn) pn = match_next_player(state->m);
sprintf(buf, ".visit-name-%d", pn);
dom_scroll_to_center_child("#visits", buf);
}
void draw_visits()
{
- if (match_num_players() > 2) {
+ if (state->m->n_players > 2) {
draw_visits_dense();
return;
}
@@ -386,29 +387,30 @@ void draw_visits()
dom_set_content("#visits", NULL);
dom_remove_class("#visits", "dense");
- int n_visits = state->legs[0]->n_visits;
- if (match_num_players() != 1 && state->legs[1]->n_visits > n_visits)
- n_visits = state->legs[1]->n_visits;
+ int n_visits = state->m->legs[0]->n_visits;
+ if (state->m->n_players != 1 && state->m->legs[1]->n_visits > n_visits)
+ n_visits = state->m->legs[1]->n_visits;
struct dom_elem **elemv = malloc(7 * (n_visits + 1) * sizeof(*elemv));
int elemc = 0;
elemv[elemc++] = create_div("", "visit-p1-spacer");
- elemv[elemc++] = create_div(state->legs[0]->name, "visit-p1-name");
- if (match_num_players() != 1)
- elemv[elemc++] = create_div(state->legs[1]->name,
+ elemv[elemc++] = create_div(state->m->players[0].name,
+ "visit-p1-name");
+ if (state->m->n_players != 1)
+ elemv[elemc++] = create_div(state->m->players[1].name,
"visit-p2-name");
elemv[elemc++] = create_div("", "visit-p2-spacer");
char buf[32], buf2[32];
- snprintf(buf, sizeof(buf), "%d", state->legs[0]->start);
+ snprintf(buf, sizeof(buf), "%d", state->m->legs[0]->start);
if (match_opts->throws_first == 1)
elemv[elemc++] = create_div("", // content added via CSS
"visit-p1-pts throws-first");
elemv[elemc++] = create_div(buf, "visit-p1-rem");
elemv[elemc++] = create_div("0", "visit-n");
- if (match_num_players() != 1) {
- snprintf(buf, sizeof(buf), "%d", state->legs[1]->start);
+ if (state->m->n_players != 1) {
+ snprintf(buf, sizeof(buf), "%d", state->m->legs[1]->start);
elemv[elemc++] = create_div(buf, "visit-p2-rem");
if (match_opts->throws_first == 2)
elemv[elemc++] = create_div("",
@@ -418,9 +420,9 @@ void draw_visits()
for (int i = 0; i < n_visits; ++i) {
struct visit *v;
- if (i >= state->legs[0]->n_visits)
+ if (i >= state->m->legs[0]->n_visits)
goto p2;
- v = state->legs[0]->visits + i;
+ v = state->m->legs[0]->visits + i;
if (v->n_darts) {
buf_darts(buf, sizeof(buf), v);
@@ -439,9 +441,10 @@ p2:
snprintf(buf, sizeof(buf), "%d", i + 1);
elemv[elemc++] = create_div(buf, "visit-n");
- if (match_num_players() == 1 || i >= state->legs[1]->n_visits)
+ if (state->m->n_players == 1 ||
+ i >= state->m->legs[1]->n_visits)
continue;
- v = state->legs[1]->visits + i;
+ v = state->m->legs[1]->visits + i;
snprintf(buf, sizeof(buf), "%d", v->rem);
elemv[elemc++] = create_div(buf, "visit-p2-rem");