summaryrefslogtreecommitdiff
path: root/web/dartboat_wasm.c
diff options
context:
space:
mode:
authorDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2022-04-20 11:00:24 -0700
committerDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2022-04-20 11:00:24 -0700
commit05dd0652a768ac05740d1465d30e1792b874414f (patch)
tree4a631c8abd87fd06e969188fbc91519a3a154630 /web/dartboat_wasm.c
parent36b74c04154cdecba1f999f5b358874502755cd0 (diff)
downloaddartboat-05dd0652a768ac05740d1465d30e1792b874414f.tar.gz
dartboat-05dd0652a768ac05740d1465d30e1792b874414f.tar.xz
add web interface using Wasm
Diffstat (limited to 'web/dartboat_wasm.c')
-rw-r--r--web/dartboat_wasm.c186
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());
+}