diff options
Diffstat (limited to 'web/dartboat_wasm.c')
-rw-r--r-- | web/dartboat_wasm.c | 214 |
1 files changed, 113 insertions, 101 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() |