diff options
Diffstat (limited to 'web/dartboat_wasm.c')
-rw-r--r-- | web/dartboat_wasm.c | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/web/dartboat_wasm.c b/web/dartboat_wasm.c new file mode 100644 index 0000000..f43afb0 --- /dev/null +++ b/web/dartboat_wasm.c @@ -0,0 +1,186 @@ +#include "checkouts.h" +#include "comp.h" + +#include <stdlib.h> +#include <stdio.h> +#include <time.h> + +#include <emscripten/emscripten.h> + +// TODO refactor *everything* + +struct match_state { + struct leg *l1, *l2; + int complete; +}; + +void suggested(int rem, char *buf) { + buf[0] = 0; + + if (rem <= 170) { + char *target = CHECKOUTS[2][rem-1]; + if (target) { + int trem = rem - segment_points(segment_from_name(target)); + int len = sprintf(buf, "%s", target); + if (trem) { + target = CHECKOUTS[1][trem-1]; + len += sprintf(buf + len, "-%s", target); + trem = trem - segment_points(segment_from_name(target)); + + if (trem) { + target = CHECKOUTS[0][trem-1]; + len += sprintf(buf + len, "-%s", target); + } + } + } + } +} + +EMSCRIPTEN_KEEPALIVE bool user_visit(struct match_state *state, int points) { + if (state->l1->rem <= 0 || state->l2->rem <= 0) + return false; + + if (points > state->l1->rem || points > 180 || points == 179 || + points == 178 || points == 176 || points == 175 || points == 173 || + points == 172 || points == 169 || points == 166 || points == 163) + return false; + + struct leg *l = state->l1; + struct visit *v = l->visits + l->n_visits++; + v->points = points; + l->rem -= points; + v->rem = l->rem; + EM_ASM({updateUserRem($0)}, l->rem); + + char sug[100]; + suggested(v->rem, sug); + EM_ASM({promptSugg($0)}, sug); + + return true; +} + +EMSCRIPTEN_KEEPALIVE int is_match_over(struct match_state *state) { + if (state->l1->rem <= 0 || state->l2->rem <= 0) + return 1; + return 0; +} + +EMSCRIPTEN_KEEPALIVE void boat_visit(struct match_state *state) { + if (state->l1->rem <= 0 || state->l2->rem <= 0) + return; + + struct leg *l = state->l2; + comp_visit(l); + + struct visit *v = l->visits + l->n_visits - 1; + + char *s1 = segment_name(v->darts[0]), + *s2 = v->n_darts > 1 ? segment_name(v->darts[1]) : NULL, + *s3 = v->n_darts > 2 ? segment_name(v->darts[2]) : NULL; + + EM_ASM({boatVisitRes($0, $1, $2, $3, $4, $5, $6, $7)}, + l->rem, v->n_darts, segment_points(v->darts[0]), + v->n_darts > 1 ? segment_points(v->darts[1]) : 0, + v->n_darts > 2 ? segment_points(v->darts[2]) : 0, + s1, s2, s3); + + free(s1); + free(s2); + free(s3); +} + +EMSCRIPTEN_KEEPALIVE void draw_match(struct match_state *state) { + struct leg *l1 = state->l1; + struct leg *l2 = state->l2; + + char visit_no[10], u_pts[10], u_rem[10], b_pts[10], b_rem[10], b_darts[100]; + visit_no[0] = u_pts[0] = u_rem[0] = b_pts[0] = b_rem[0] = b_darts[0] = 0; + + EM_ASM({drawVisitNames($0, $1)}, + l1->name, l2->name); + EM_ASM({drawVisit($0, $1, $2, $3, $4, $5)}, + "0", "", "501", "", "501", ""); + + int n_visits = l1->n_visits > l2->n_visits ? l1->n_visits : l2->n_visits; + for (int i = 0; i < n_visits; ++i) { + sprintf(visit_no, "%d", i + 1); + + struct visit *v = l1->visits + i; + sprintf(u_pts, "%d", v->points); + sprintf(u_rem, "%d", v->rem); + + if (i < l2->n_visits) { + v = l2->visits + i; + sprintf(b_pts, "%d", v->points); + sprintf(b_rem, "%d", v->rem); + + for (int j = 0; j < v->n_darts; ++j) { + char *n = segment_name(v->darts[j]); + sprintf(b_darts + (j ? (j * 5 - 1) : 0), j == 0 ? "%4s" : " %4s", n); + free(n); + } + } + + EM_ASM({drawVisit($0, $1, $2, $3, $4, $5)}, + visit_no, u_pts, u_rem, b_pts, b_rem, b_darts); + + visit_no[0] = 0; + u_pts[0] = 0; + u_rem[0] = 0; + b_pts[0] = 0; + b_rem[0] = 0; + b_darts[0] = 0; + } + + if (l1->rem <= 0) { + EM_ASM({promptMsg($0)}, "You win! :)"); + EM_ASM(matchOver()); + } else if (l2->rem <= 0) { + EM_ASM({promptSugg($0)}, ""); + EM_ASM({promptMsg($0)}, "Bot wins. :("); + EM_ASM(matchOver()); + } else { + EM_ASM({promptMsg($0)}, "Enter points:"); + } + +} + +void init_boat() { + static int ran; + + if (ran) return; + ran = 1; + + srand(time(NULL)); + init_board(); + + EM_ASM({updateStdev($0)}, horizontal_stdev); +} + +EMSCRIPTEN_KEEPALIVE struct match_state *start_match() { + init_boat(); + struct match_state *state = calloc(1, sizeof(struct match_state)); + state->l1 = leg_init(501, "User"); + state->l2 = leg_init(501, "Bot"); + + EM_ASM({updateUserRem($0)}, state->l1->rem); + EM_ASM({updateBoatRem($0)}, state->l2->rem); + + return state; +} + +EMSCRIPTEN_KEEPALIVE void free_match(struct match_state *state) { + leg_free(state->l1); + leg_free(state->l2); + free(state); +} + +EMSCRIPTEN_KEEPALIVE void change_stdev(float hstdev, float vstdev) { + printf("%f %f\n", hstdev, vstdev); + horizontal_stdev = hstdev; + vertical_stdev = vstdev; +} + +int main() { + EM_ASM(initMatch()); +} |