summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--web/dartboat_wasm.c214
-rw-r--r--web/static/dartboat.js4
-rw-r--r--web/static/index.html2
-rw-r--r--web/static/style.css2
4 files changed, 117 insertions, 105 deletions
diff --git a/web/dartboat_wasm.c b/web/dartboat_wasm.c
index 6580716..b44a9b8 100644
--- a/web/dartboat_wasm.c
+++ b/web/dartboat_wasm.c
@@ -11,30 +11,31 @@
int delay_ms = 500;
enum match_mode {
- M_PVC = 1,
+ M_FIRST = 1,
+ M_PVC = M_FIRST,
M_P,
- M_PVP
+ M_PVP,
+ M_LAST = M_PVP
};
-// TODO refactor *everything*
-
struct match_state {
enum match_mode mode;
- struct leg *l1, *l2, *active_l;
- int active_p;
- int undone_count;
+ struct leg *legs[2];
+ struct leg *active_leg;
+ int active_player;
+ int boat_undone;
bool num_darts;
};
struct match_state *state;
-void set_active_player(int player)
+void set_active_player(int pn)
{
- state->active_p = player;
- state->active_l = player == 1 ? state->l1 : state->l2;
- EM_ASM({setPlayerActive($0)}, player);
+ state->active_player = pn;
+ state->active_leg = state->legs[pn-1];
+ EM_ASM({setPlayerActive($0)}, pn);
- if (state->mode == M_PVC && player == 2) {
+ if (state->mode == M_PVC && pn == 2) {
EM_ASM({promptMsgL($0)}, "Bot is throwing…");
EM_ASM({setPromptHandler($0)}, "");
} else {
@@ -46,10 +47,10 @@ void set_active_player(int player)
void toggle_active_player()
{
- set_active_player(3 - state->active_p);
+ set_active_player(3 - state->active_player);
}
-void update_player_sugg(int player, int rem)
+void update_player_sugg(int pn, int rem)
{
char str[15] = {0}, *p = str;
@@ -62,19 +63,12 @@ void update_player_sugg(int player, int rem)
}
}
- EM_ASM({updatePlayerSugg($0, $1)}, player, str);
+ EM_ASM({updatePlayerSugg($0, $1)}, pn, str);
}
bool is_match_over()
{
- return state->l1->rem <= 0 || state->l2->rem <= 0;
-}
-
-void prompt_end_match()
-{
- EM_ASM(setPlayerActive()); // sets all inactive
- EM_ASM({setPromptHandler($0)}, "end_match");
- EM_ASM({promptMsgR($0)}, "Press OK to end match.");
+ return state->legs[0]->rem <= 0 || state->legs[1]->rem <= 0;
}
void draw_visits()
@@ -84,25 +78,25 @@ void draw_visits()
char visit_no[10], p1_pts[10], p1_rem[10],
p2_pts[10], p2_rem[10], p2_darts[100];
- sprintf(p1_rem, "%d", state->l1->start);
- sprintf(p2_rem, "%d", state->l2->start);
+ sprintf(p1_rem, "%d", state->legs[0]->start);
+ sprintf(p2_rem, "%d", state->legs[1]->start);
EM_ASM({drawVisit($0, $1, $2, $3, $4, $5)},
"0", "", p1_rem, "", state->mode == M_P ? "" : p2_rem, "");
- int n_visits = state->l1->n_visits > state->l2->n_visits ?
- state->l1->n_visits : state->l2->n_visits;
+ int n_visits = state->legs[0]->n_visits > state->legs[1]->n_visits ?
+ state->legs[0]->n_visits : state->legs[1]->n_visits;
for (int i = 0; i < n_visits; ++i) {
visit_no[0] = p1_pts[0] = p1_rem[0] =
p2_pts[0] = p2_rem[0] = p2_darts[0] = 0;
sprintf(visit_no, "%d", i + 1);
- struct visit *v = state->l1->visits + i;
+ struct visit *v = state->legs[0]->visits + i;
sprintf(p1_pts, "%d", v->points);
sprintf(p1_rem, "%d", v->rem);
- if (i < state->l2->n_visits) {
- v = state->l2->visits + i;
+ if (i < state->legs[1]->n_visits) {
+ v = state->legs[1]->visits + i;
sprintf(p2_pts, "%d", v->points);
sprintf(p2_rem, "%d", v->rem);
@@ -119,7 +113,7 @@ void draw_visits()
}
}
-void update_player_rem(int player, int rem)
+void update_player_rem(int pn, int rem)
{
char str[5];
if (rem < 0 || rem == 1)
@@ -127,14 +121,14 @@ void update_player_rem(int player, int rem)
else
sprintf(str, "%d", rem);
- EM_ASM({updatePlayerRem($0, $1)}, player, str);
- if (player == 1 || state->mode != M_PVC)
- update_player_sugg(player, rem);
+ EM_ASM({updatePlayerRem($0, $1)}, pn, str);
+ if (pn == 1 || state->mode != M_PVC)
+ update_player_sugg(pn, rem);
}
EMSCRIPTEN_KEEPALIVE void update_user_rem_from_pts(int pts)
{
- update_player_rem(state->active_p, state->active_l->rem - pts);
+ update_player_rem(state->active_player, state->active_leg->rem - pts);
}
EMSCRIPTEN_KEEPALIVE void draw_boat_throwing(int pts, char *str)
@@ -142,8 +136,9 @@ EMSCRIPTEN_KEEPALIVE void draw_boat_throwing(int pts, char *str)
char pts_str[10];
sprintf(pts_str, "%d", pts);
- int rem = state->l2->n_visits > 1 ?
- state->l2->visits[state->l2->n_visits-2].rem : state->l2->start;
+ int rem = state->legs[1]->n_visits > 1 ?
+ state->legs[1]->visits[state->legs[1]->n_visits-2].rem :
+ state->legs[1]->start;
update_player_rem(2, rem - pts);
EM_ASM({setPromptInput($0)}, pts_str);
@@ -151,7 +146,7 @@ EMSCRIPTEN_KEEPALIVE void draw_boat_throwing(int pts, char *str)
}
void handle_next();
-EMSCRIPTEN_KEEPALIVE void end_boat_throwing(int rem, double avg)
+EMSCRIPTEN_KEEPALIVE void end_boat_visit(int rem, double avg)
{
update_player_rem(2, rem);
EM_ASM({updatePlayerAvg($0, $1)}, 2, avg);
@@ -164,9 +159,9 @@ EMSCRIPTEN_KEEPALIVE void end_boat_throwing(int rem, double avg)
EMSCRIPTEN_KEEPALIVE void boat_visit()
{
- struct leg *l = state->l2;
- if (state->undone_count) {
- --state->undone_count;
+ struct leg *l = state->legs[1];
+ if (state->boat_undone) {
+ --state->boat_undone;
l->rem = l->visits[l->n_visits++].rem;
} else {
comp_visit(l);
@@ -178,7 +173,7 @@ EMSCRIPTEN_KEEPALIVE void boat_visit()
(double)l->start / (((l->n_visits - 1) * 3) + v->n_darts) * 3;
if (!delay_ms) {
- end_boat_throwing(l->rem, avg);
+ end_boat_visit(l->rem, avg);
return;
}
@@ -197,7 +192,7 @@ EMSCRIPTEN_KEEPALIVE void boat_visit()
}
EM_ASM({scheduleCCall($0, $1, $2, $3, $4, $5)},
- "end_boat_throwing", delay_ms * (v->n_darts + 1),
+ "end_boat_visit", delay_ms * (v->n_darts + 1),
"number", l->rem, "number", avg);
}
@@ -209,7 +204,24 @@ void clear_player_info(int pn)
EM_ASM({updatePlayerAvg($0, $1)}, pn, 0);
}
-EMSCRIPTEN_KEEPALIVE void prompt_match_mode()
+void prompt_num_darts()
+{
+ EM_ASM({setPromptHandler($0)}, "num_darts");
+ EM_ASM({promptMsgL($0)}, "Darts needed?");
+ EM_ASM({promptMsgR($0)}, "");
+}
+
+void prompt_end_match()
+{
+ EM_ASM(setPlayerActive()); // sets all inactive
+ EM_ASM({setPromptHandler($0)}, "end_match");
+ EM_ASM({promptMsgL($0)},
+ state->mode == M_PVC && state->legs[1]->rem <= 0 ? "Bot wins. :(" :
+ "You win! :)");
+ EM_ASM({promptMsgR($0)}, "Press OK to end match.");
+}
+
+EMSCRIPTEN_KEEPALIVE void prompt_select_mode()
{
for (int pn = 1; pn < 3; ++pn) {
EM_ASM({hidePlayerInfo($0)}, pn);
@@ -217,62 +229,69 @@ EMSCRIPTEN_KEEPALIVE void prompt_match_mode()
}
EM_ASM(clearVisits());
- EM_ASM({setPromptHandler($0)}, "match_mode");
- EM_ASM({promptMsgR($0)}, "");
+ EM_ASM({setPromptHandler($0)}, "select_mode");
EM_ASM({promptMsgL($0)}, "Select match mode:");
+ EM_ASM({promptMsgR($0)}, "");
}
void handle_next()
{
if (!state) {
- prompt_match_mode();
+ prompt_select_mode();
} else if (is_match_over()) {
- if (state->mode == M_PVC && state->l2->rem <= 0) {
- EM_ASM({promptMsgL($0)}, "Bot wins. :(");
+ if (state->num_darts ||
+ (state->mode == M_PVC && state->legs[1]->rem <= 0))
prompt_end_match();
- } else if (!state->num_darts) {
- EM_ASM({setPromptHandler($0)}, "num_darts");
- EM_ASM({promptMsgL($0)}, "Darts needed?");
- } else {
- EM_ASM({promptMsgL($0)}, "You win! :)");
- prompt_end_match();
- }
+ else
+ prompt_num_darts();
} else {
if (state->mode == M_P) {
set_active_player(1);
} else {
- toggle_active_player();
+ if (state->active_player)
+ toggle_active_player();
+ else
+ set_active_player(1);
- if (state->mode == M_PVC && state->active_p == 2)
+ if (state->mode == M_PVC && state->active_player == 2)
boat_visit();
}
}
}
+void update_player_avg(int pn, int n_darts)
+{
+ struct leg *l = state->legs[pn-1];
+ EM_ASM({updatePlayerAvg($0, $1)}, pn,
+ l->n_visits ?
+ (l->rem > 0 ? ((double)(l->start - l->rem) / l->n_visits) :
+ ((double)l->start / (((l->n_visits - 1) * 3) + n_darts) * 3)) :
+ 0);
+}
+
EMSCRIPTEN_KEEPALIVE void user_visit(int points)
{
- if (points < 0 || state->l1->rem <= 0 || state->l2->rem <= 0 ||
- points > state->active_l->rem || state->active_l->rem - points == 1 ||
+ if (points < 0 || points > state->active_leg->rem ||
+ state->active_leg->rem - points == 1 ||
points > 180 || points == 179 || points == 178 || points == 176 ||
points == 175 || points == 173 || points == 172 || points == 169 ||
points == 166 || points == 163 ||
- (state->active_l->rem - points == 0 &&
- (points == 168 || points == 165 || points == 162 || points == 159))) {
-
+ (state->active_leg->rem - points == 0 &&
+ (points == 168 || points == 165 || points == 162 ||
+ points == 159))) {
EM_ASM(oi());
return;
}
- struct leg *l = state->active_l;
+ struct leg *l = state->active_leg;
struct visit *v = l->visits + l->n_visits++;
v->points = points;
l->rem -= points;
v->rem = l->rem;
- update_player_rem(state->active_p, l->rem);
+ update_player_rem(state->active_player, l->rem);
if (v->rem > 0)
- EM_ASM({updatePlayerAvg($0, $1)}, state->active_p,
- (double)(l->start-l->rem)/l->n_visits);
+ update_player_avg(state->active_player, 0);
draw_visits();
handle_next();
@@ -280,12 +299,12 @@ EMSCRIPTEN_KEEPALIVE void user_visit(int points)
EMSCRIPTEN_KEEPALIVE void user_visit_to_rem(int rem)
{
- user_visit(state->l1->rem - rem);
+ user_visit(state->legs[0]->rem - rem);
}
EMSCRIPTEN_KEEPALIVE void user_undo()
{
- if (!state->l1->n_visits) {
+ if (!state->legs[0]->n_visits) {
EM_ASM(oi());
return;
}
@@ -294,33 +313,29 @@ EMSCRIPTEN_KEEPALIVE void user_undo()
set_active_player(1);
} else if (state->mode == M_PVP) {
if (is_match_over())
- set_active_player(state->active_p);
+ set_active_player(state->active_player);
else
toggle_active_player();
}
- struct leg *l = state->active_l;
+ struct leg *l = state->active_leg;
struct visit *v = l->visits + --l->n_visits;
l->rem += v->points;
memcpy(v, 0, sizeof(*v));
state->num_darts = 0;
- if (state->mode == M_PVC && state->l2->n_visits > l->n_visits) {
- state->l2->rem += state->l2->visits[--state->l2->n_visits].points;
- ++state->undone_count;
+ if (state->mode == M_PVC && state->legs[1]->n_visits > l->n_visits) {
+ state->legs[1]->rem +=
+ state->legs[1]->visits[--state->legs[1]->n_visits].points;
+ ++state->boat_undone;
}
- EM_ASM({updatePlayerAvg($0, $1)}, 1,
- state->l1->n_visits ?
- (double)(state->l1->start - state->l1->rem) / state->l1->n_visits :
- 0);
- EM_ASM({updatePlayerAvg($0, $1)}, 2,
- state->l2->n_visits ?
- (double)(state->l2->start - state->l2->rem) / state->l2->n_visits :
- 0);
- update_player_rem(state->active_p, l->rem);
- if (state->mode == M_PVC)
- update_player_rem(2, state->l2->rem);
+ update_player_avg(state->active_player, 0);
+ update_player_rem(state->active_player, l->rem);
+ if (state->mode == M_PVC) {
+ update_player_avg(2, 0);
+ update_player_rem(2, state->legs[1]->rem);
+ }
draw_visits();
@@ -337,50 +352,47 @@ EMSCRIPTEN_KEEPALIVE void user_num_darts(int n)
}
state->num_darts = n;
-
- struct leg *l = state->active_l;
- EM_ASM({updatePlayerAvg($0, $1)}, state->active_p,
- ((double)l->start / (((l->n_visits - 1) * 3) + n)) * 3);
+ update_player_avg(state->active_player, n);
handle_next();
}
void free_state()
{
- state->l2->n_visits += state->undone_count; // avoid memory leak
- leg_free(state->l1);
- leg_free(state->l2);
+ state->legs[1]->n_visits += state->boat_undone; // avoid memory leak
+ leg_free(state->legs[0]);
+ leg_free(state->legs[1]);
free(state);
state = NULL;
}
EMSCRIPTEN_KEEPALIVE void start_match(int mode)
{
- if (mode != M_PVP && mode != M_PVC && mode != M_P) {
+ if (mode < M_FIRST || mode > M_LAST) {
EM_ASM(oi());
return;
}
- if (state) free_state(); // FIXME
+ if (state) free_state(); // this should never happen
state = calloc(1, sizeof(*state));
state->mode = mode;
- state->l1 = leg_init(501, mode == M_PVP ? "Player 1" : "User");
- state->l2 = leg_init(501, mode == M_PVC ? "Bot" : "Player 2");
- set_active_player(1);
+ state->legs[0] = leg_init(501, mode == M_PVP ? "Player 1" : "User");
+ state->legs[1] = leg_init(501, mode == M_PVC ? "Bot" : "Player 2");
EM_ASM({showPlayerInfo($0)}, 1);
- EM_ASM({updatePlayerName($0, $1)}, 1, state->l1->name);
- update_player_rem(1, state->l1->rem);
+ EM_ASM({updatePlayerName($0, $1)}, 1, state->legs[0]->name);
+ update_player_rem(1, state->legs[0]->rem);
EM_ASM({updatePlayerAvg($0, $1)}, 1, 0);
if (mode != M_P) {
EM_ASM({showPlayerInfo($0)}, 2);
- EM_ASM({updatePlayerName($0, $1)}, 2, state->l2->name);
- update_player_rem(2, state->l2->rem);
+ EM_ASM({updatePlayerName($0, $1)}, 2, state->legs[1]->name);
+ update_player_rem(2, state->legs[1]->rem);
EM_ASM({updatePlayerAvg($0, $1)}, 2, 0);
}
draw_visits();
+ handle_next();
}
EMSCRIPTEN_KEEPALIVE void end_match()
diff --git a/web/static/dartboat.js b/web/static/dartboat.js
index cb8e9dd..9cedc4a 100644
--- a/web/static/dartboat.js
+++ b/web/static/dartboat.js
@@ -123,9 +123,9 @@ prompt_handlers.end_match = {
}
};
-prompt_handlers.match_mode = {
+prompt_handlers.select_mode = {
__proto__: prompt_handlers.default,
- _keypad: 'match_mode',
+ _keypad: 'select_mode',
submit() {
let v = this._get_and_clear();
diff --git a/web/static/index.html b/web/static/index.html
index e1384bb..1177e40 100644
--- a/web/static/index.html
+++ b/web/static/index.html
@@ -47,7 +47,7 @@
<div onclick="promptHandle('undo')" class="key" id="key_undo">UNDO</div>
<div onclick="promptHandle('submit_rem')" class="key">REMAINING</div>
</div>
- <div id="keypad-match_mode" class="keypad">
+ <div id="keypad-select_mode" class="keypad">
<div onclick="promptHandle('append', 1); promptHandle('submit')" class="key"><span class="keyboard-val">[1]</span> Play against bot</div>
<div onclick="promptHandle('append', 2); promptHandle('submit')" class="key"><span class="keyboard-val">[2]</span> One-player scoreboard</div>
<div onclick="promptHandle('append', 3); promptHandle('submit')" class="key"><span class="keyboard-val">[3]</span> Two-player scoreboard</div>
diff --git a/web/static/style.css b/web/static/style.css
index 519a437..e43a0c1 100644
--- a/web/static/style.css
+++ b/web/static/style.css
@@ -42,7 +42,7 @@ div#controls .keypad {
display: contents;
}
-div#controls #keypad-match_mode .key {
+div#controls #keypad-select_mode .key {
grid-column: 1 / -1;
padding-left: 0.4rem;