summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--match.c50
-rw-r--r--match.h5
-rw-r--r--web/web_control.c57
-rw-r--r--web/web_match.c19
-rw-r--r--web/web_match.h3
5 files changed, 76 insertions, 58 deletions
diff --git a/match.c b/match.c
index 0b9a425..ee35798 100644
--- a/match.c
+++ b/match.c
@@ -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 &&
diff --git a/match.h b/match.h
index b22ed63..32523b6 100644
--- a/match.h
+++ b/match.h
@@ -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