diff options
Diffstat (limited to 'web/dartboat_wasm.c')
-rw-r--r-- | web/dartboat_wasm.c | 321 |
1 files changed, 164 insertions, 157 deletions
diff --git a/web/dartboat_wasm.c b/web/dartboat_wasm.c index 989e0c2..1815d53 100644 --- a/web/dartboat_wasm.c +++ b/web/dartboat_wasm.c @@ -27,28 +27,27 @@ struct match_state { struct match_state *state; -void switch_active_user() { - state->active_p = 3 - state->active_p; - if (state->active_p == 1) - state->active_l = state->l1; - else - state->active_l = state->l2; - EM_ASM({setPlayerActive($0)}, state->active_p); +void set_active_player(int player) +{ + state->active_p = player; + state->active_l = player == 1 ? state->l1 : state->l2; + EM_ASM({setPlayerActive($0)}, player); } -void set_user_active() { - state->active_p = 1; - state->active_l = state->l1; +void toggle_active_player() +{ + set_active_player(3 - state->active_p); +} - EM_ASM({setPlayerActive($0)}, 1); +void set_user_active() +{ + set_active_player(1); EM_ASM({setPromptHandler($0)}, "visit"); } -void set_boat_active() { - state->active_p = 2; - state->active_l = state->l2; - - EM_ASM({setPlayerActive($0)}, 2); +void set_boat_active() +{ + set_active_player(2); EM_ASM({setPromptHandler()}, ""); } @@ -68,43 +67,44 @@ void update_player_sugg(int player, int rem) EM_ASM({updatePlayerSugg($0, $1)}, player, str); } -bool is_match_over() { +bool is_match_over() +{ return state->l1->rem <= 0 || state->l2->rem <= 0; } -void prompt_match_over() { +void prompt_match_over() +{ + EM_ASM(setPlayerActive()); // sets all inactive EM_ASM({setPromptHandler($0)}, "match_over"); EM_ASM({promptMsgR($0)}, "Press OK to end match."); - EM_ASM(setPlayerActive()); } -EMSCRIPTEN_KEEPALIVE void draw_visits() { +void draw_visits() +{ EM_ASM({clearVisits()}); - struct leg *l1 = state->l1; - struct leg *l2 = state->l2; - char visit_no[10], p1_pts[10], p1_rem[10], p2_pts[10], p2_rem[10], p2_darts[100]; - sprintf(p1_rem, "%d", l1->start); - sprintf(p2_rem, "%d", l2->start); + sprintf(p1_rem, "%d", state->l1->start); + sprintf(p2_rem, "%d", state->l2->start); EM_ASM({drawVisit($0, $1, $2, $3, $4, $5)}, "0", "", p1_rem, "", state->mode == M_P ? "" : p2_rem, ""); - int n_visits = l1->n_visits > l2->n_visits ? l1->n_visits : l2->n_visits; + int n_visits = state->l1->n_visits > state->l2->n_visits ? + state->l1->n_visits : state->l2->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 = l1->visits + i; + struct visit *v = state->l1->visits + i; sprintf(p1_pts, "%d", v->points); sprintf(p1_rem, "%d", v->rem); - if (i < l2->n_visits) { - v = l2->visits + i; + if (i < state->l2->n_visits) { + v = state->l2->visits + i; sprintf(p2_pts, "%d", v->points); sprintf(p2_rem, "%d", v->rem); @@ -121,45 +121,51 @@ EMSCRIPTEN_KEEPALIVE void draw_visits() { } } -EMSCRIPTEN_KEEPALIVE void draw_match() { - draw_visits(); - - if (state->l1->rem <= 0) { - EM_ASM({promptMsgL($0)}, "Darts needed?"); - EM_ASM({setPromptHandler($0)}, "num_darts"); - } else if (state->l2->rem <= 0) { - if (state->mode == M_PVC) { - EM_ASM({promptMsgL($0)}, "Bot wins. :("); - prompt_match_over(); - } else { - EM_ASM({promptMsgL($0)}, "Darts needed?"); - EM_ASM({setPromptHandler($0)}, "num_darts"); - } - } else { - EM_ASM({promptMsgL($0)}, "Enter points:"); - } -} - -EMSCRIPTEN_KEEPALIVE void update_player_rem(int player, int rem) { - char str[10]; +void update_player_rem(int player, int rem) +{ + char str[5]; if (rem < 0 || rem == 1) strcpy(str, "BUST"); else sprintf(str, "%d", rem); EM_ASM({updatePlayerRem($0, $1)}, player, str); - if (player == 1 || state->mode != M_PVC) update_player_sugg(player, rem); } -EMSCRIPTEN_KEEPALIVE void update_user_rem_from_pts(int pts) { +EMSCRIPTEN_KEEPALIVE void update_user_rem_from_pts(int pts) +{ update_player_rem(state->active_p, state->active_l->rem - pts); } -void end_boat_throwing(int, double); // FIXME +EMSCRIPTEN_KEEPALIVE void draw_boat_throwing(int pts, char *str) +{ + char pts_str[10]; + sprintf(pts_str, "%d", pts); -EMSCRIPTEN_KEEPALIVE void boat_visit() { + int rem = state->l2->n_visits > 1 ? + state->l2->visits[state->l2->n_visits-2].rem : state->l2->start; + + update_player_rem(2, rem - pts); + EM_ASM({setPromptInput($0)}, pts_str); + EM_ASM({promptMsgR($0)}, str); +} + +void post_visit_checks(); +EMSCRIPTEN_KEEPALIVE void end_boat_throwing(int rem, double avg) +{ + update_player_rem(2, rem); + EM_ASM({updatePlayerAvg($0, $1)}, 2, avg); + EM_ASM({setPromptInput($0)}, ""); + EM_ASM({promptMsgR($0)}, ""); + + draw_visits(); + post_visit_checks(); +} + +EMSCRIPTEN_KEEPALIVE void boat_visit() +{ if (state->l1->rem <= 0 || state->l2->rem <= 0) return; @@ -205,7 +211,36 @@ EMSCRIPTEN_KEEPALIVE void boat_visit() { "number", l->rem, "number", avg); } -EMSCRIPTEN_KEEPALIVE bool user_visit(int points) { +void post_visit_checks() +{ + if (is_match_over()) { + if (state->mode == M_PVC && state->l2->rem <= 0) { + EM_ASM({promptMsgL($0)}, "Bot wins. :("); + prompt_match_over(); + } else { + EM_ASM({setPromptHandler($0)}, "num_darts"); + EM_ASM({promptMsgL($0)}, "Darts needed?"); + } + } else { + if (state->mode == M_PVC) { + if (state->active_p == 1) { + set_boat_active(); + boat_visit(); + } else { + set_user_active(); + EM_ASM({promptMsgL($0)}, "Enter points:"); + } + } else if (state->mode == M_PVP) { + toggle_active_player(); + EM_ASM({promptMsgL($0)}, "Enter points:"); + } else { + EM_ASM({promptMsgL($0)}, "Enter points:"); + } + } +} + +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 || points > 180 || points == 179 || points == 178 || points == 176 || @@ -215,7 +250,7 @@ EMSCRIPTEN_KEEPALIVE bool user_visit(int points) { (points == 168 || points == 165 || points == 162 || points == 159))) { EM_ASM(oi()); - return false; + return; } struct leg *l = state->active_l; @@ -229,39 +264,31 @@ EMSCRIPTEN_KEEPALIVE bool user_visit(int points) { EM_ASM({updatePlayerAvg($0, $1)}, state->active_p, (double)(l->start-l->rem)/l->n_visits); - draw_match(); - - if (!is_match_over()) { - if (state->mode == M_PVC) { - set_boat_active(); - boat_visit(); - } else if (state->mode == M_PVP) { - switch_active_user(); - } - } - - return true; + draw_visits(); + post_visit_checks(); } -EMSCRIPTEN_KEEPALIVE void user_visit_to_rem(int rem) { +EMSCRIPTEN_KEEPALIVE void user_visit_to_rem(int rem) +{ user_visit(state->l1->rem - rem); } -EMSCRIPTEN_KEEPALIVE bool user_undo() { +EMSCRIPTEN_KEEPALIVE void user_undo() +{ if (!state->l1->n_visits) { EM_ASM(oi()); - return false; + return; } if (state->mode == M_PVP) { if (is_match_over()) EM_ASM({setPlayerActive($0)}, state->active_p); else - switch_active_user(); + toggle_active_player(); } if (state->mode == M_PVC) - EM_ASM({setPlayerActive($0)}, state->active_p); + set_user_active(); struct leg *l = state->active_l; struct visit *v = l->visits + --l->n_visits; @@ -284,131 +311,111 @@ EMSCRIPTEN_KEEPALIVE bool user_undo() { EM_ASM({promptMsgR($0)}, ""); EM_ASM({setPromptHandler($0)}, "visit"); - draw_match(); - - return true; -} - -EMSCRIPTEN_KEEPALIVE void draw_boat_throwing(int pts, char *str) { - char buf[10]; - sprintf(buf, "%d", pts); - - int rem = state->l2->n_visits > 1 ? - state->l2->visits[state->l2->n_visits-2].rem : state->l2->start; - - update_player_rem(2, rem - pts); - EM_ASM({setPromptInput($0)}, buf); - EM_ASM({promptMsgR($0)}, str); -} - -EMSCRIPTEN_KEEPALIVE void end_boat_throwing(int rem, double avg) { - update_player_rem(2, rem); - EM_ASM({updatePlayerAvg($0, $1)}, 2, avg); - EM_ASM({setPromptInput($0)}, ""); - EM_ASM({promptMsgR($0)}, ""); - draw_match(); - - if (!is_match_over()) - set_user_active(); + EM_ASM({promptMsgL($0)}, "Enter points:"); + draw_visits(); } -EMSCRIPTEN_KEEPALIVE void resp_numdarts(int n_darts) { - if (n_darts < 1 || n_darts > 3) { +EMSCRIPTEN_KEEPALIVE void user_num_darts(int n) +{ + if (n < 1 || n > 3) { EM_ASM(oi()); return; } - struct leg *l = state->l1; + struct leg *l = state->active_l; EM_ASM({updatePlayerAvg($0, $1)}, state->active_p, - ((double)l->start / (((l->n_visits - 1) * 3) + n_darts)) * 3); + ((double)l->start / (((l->n_visits - 1) * 3) + n)) * 3); EM_ASM({promptMsgL($0)}, "You win! :)"); prompt_match_over(); } -void init_boat() { - static int ran; - - if (ran) return; - ran = 1; - - srand(time(NULL)); - init_board(); - - EM_ASM({updateStdev($0)}, horizontal_stdev); - EM_ASM({updateDelay($0)}, delay_ms); -} - -EMSCRIPTEN_KEEPALIVE void free_match() { +void free_state() +{ + state->l2->n_visits += state->undone_count; // avoid memory leak leg_free(state->l1); - state->l2->n_visits += state->undone_count; // FIXME messy way to avoid memory leak leg_free(state->l2); free(state); state = NULL; } -EMSCRIPTEN_KEEPALIVE void prompt_match_mode() { - for (int i = 1; i < 3; ++i) { - EM_ASM({hidePlayerInfo($0)}, i); - EM_ASM({updatePlayerName($0, $1)}, i, ""); - EM_ASM({updatePlayerRem($0, $1)}, i, ""); - EM_ASM({updatePlayerSugg($0, $1)}, i, ""); - EM_ASM({updatePlayerAvg($0, $1)}, i, 0); - } - EM_ASM(clearVisits()); - - EM_ASM({setPromptHandler($0)}, "init"); - EM_ASM({promptMsgR($0)}, ""); - EM_ASM({promptMsgL($0)}, "Select match mode:"); -} - -EMSCRIPTEN_KEEPALIVE void start_match(int mode) { +EMSCRIPTEN_KEEPALIVE void start_match(int mode) +{ if (mode != M_PVP && mode != M_PVC && mode != M_P) { EM_ASM(oi()); return; } - if (state) free_match(); - - init_boat(); + if (state) free_state(); state = calloc(1, sizeof(*state)); state->mode = mode; - if (mode == M_PVC) { - state->l1 = leg_init(501, "User"); - state->l2 = leg_init(501, "Bot"); - } else { - state->l1 = leg_init(501, mode == M_PVP ? "Player 1" : "User"); - state->l2 = leg_init(501, "Player 2"); - } - EM_ASM({showPlayerInfo($0)}, 1); - if (mode != M_P) - EM_ASM({showPlayerInfo($0)}, 2); + state->l1 = leg_init(501, mode == M_PVP ? "Player 1" : "User"); + state->l2 = leg_init(501, mode == M_PVC ? "Bot" : "Player 2"); state->active_p = 1; state->active_l = state->l1; + set_user_active(); + EM_ASM({showPlayerInfo($0)}, 1); EM_ASM({updatePlayerName($0, $1)}, 1, state->l1->name); - EM_ASM({updatePlayerName($0, $1)}, 2, state->l2->name); update_player_rem(1, state->l1->rem); - update_player_rem(2, state->l2->rem); EM_ASM({updatePlayerAvg($0, $1)}, 1, 0); - EM_ASM({updatePlayerAvg($0, $1)}, 2, 0); - set_user_active(); + 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({updatePlayerAvg($0, $1)}, 2, 0); + } + + EM_ASM({promptMsgR($0)}, ""); + EM_ASM({promptMsgL($0)}, ""); + draw_visits(); +} + +void clear_player_info(int pn) +{ + EM_ASM({updatePlayerName($0, $1)}, pn, ""); + EM_ASM({updatePlayerRem($0, $1)}, pn, ""); + EM_ASM({updatePlayerSugg($0, $1)}, pn, ""); + EM_ASM({updatePlayerAvg($0, $1)}, pn, 0); +} + +EMSCRIPTEN_KEEPALIVE void prompt_match_mode() +{ + for (int pn = 1; pn < 3; ++pn) { + EM_ASM({hidePlayerInfo($0)}, pn); + clear_player_info(pn); + } + EM_ASM(clearVisits()); + + EM_ASM({setPromptHandler($0)}, "init"); EM_ASM({promptMsgR($0)}, ""); - draw_match(); + EM_ASM({promptMsgL($0)}, "Select match mode:"); +} + +EMSCRIPTEN_KEEPALIVE void set_delay(int delay) +{ + delay_ms = delay; } -EMSCRIPTEN_KEEPALIVE void set_stdev(float hstdev, float vstdev) { +EMSCRIPTEN_KEEPALIVE void set_stdev(float hstdev, float vstdev) +{ horizontal_stdev = hstdev; vertical_stdev = vstdev; } -EMSCRIPTEN_KEEPALIVE void set_delay(int delay) { - delay_ms = delay; +void init_boat() +{ + srand(time(NULL)); + init_board(); + + EM_ASM(readOpts()); + EM_ASM({updateDelay($0)}, delay_ms); + EM_ASM({updateStdev($0)}, horizontal_stdev); } -int main() { - EM_ASM(read_opts()); +int main() +{ init_boat(); prompt_match_mode(); } |