summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dartbot.c97
1 files changed, 61 insertions, 36 deletions
diff --git a/dartbot.c b/dartbot.c
index 263bbc1..7367648 100644
--- a/dartbot.c
+++ b/dartbot.c
@@ -1,5 +1,6 @@
#include <math.h>
#include <ncurses.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
@@ -7,6 +8,7 @@
#define HORIZONTAL_STDEV 50
#define VERTICAL_STDEV 50
+// board spec from WDF rules
#define WIRE_WIDTH 1.56
#define INNER_DIAMETER_BULL 12.7
#define INNER_DIAMETER_25 31.8
@@ -15,14 +17,19 @@
#define DOUBLE_INSIDE_WIDTH 8.0
#define TREBLE_INSIDE_WIDTH 8.0
+#define SEGMENT_MAX_LEN 5
+// distance from centre to apex of outer wire
+// must be ordered outwards from centre
#define FOREACH_RING(M) \
- M(R_BULL, INNER_DIAMETER_BULL/2 + WIRE_WIDTH/2) \
- M(R_25, INNER_DIAMETER_25/2 + WIRE_WIDTH/2) \
- M(R_SMALL, TREBLE_OUTER_EDGE - WIRE_WIDTH - TREBLE_INSIDE_WIDTH - WIRE_WIDTH/2) \
- M(R_TREBLE, TREBLE_OUTER_EDGE - WIRE_WIDTH/2) \
- M(R_BIG, DOUBLE_OUTER_EDGE - WIRE_WIDTH - DOUBLE_INSIDE_WIDTH - WIRE_WIDTH/2) \
- M(R_DOUBLE, DOUBLE_OUTER_EDGE - WIRE_WIDTH/2)
-#define GEN_RING_ENUM(X, D) X,
+ M(BULL, INNER_DIAMETER_BULL/2 + WIRE_WIDTH/2) \
+ M(25, INNER_DIAMETER_25/2 + WIRE_WIDTH/2) \
+ M(SMALL, TREBLE_OUTER_EDGE - WIRE_WIDTH - TREBLE_INSIDE_WIDTH - \
+ WIRE_WIDTH/2) \
+ M(TREBLE, TREBLE_OUTER_EDGE - WIRE_WIDTH/2) \
+ M(BIG, DOUBLE_OUTER_EDGE - WIRE_WIDTH - DOUBLE_INSIDE_WIDTH - \
+ WIRE_WIDTH/2) \
+ M(DOUBLE, DOUBLE_OUTER_EDGE - WIRE_WIDTH/2)
+#define GEN_RING_ENUM(X, D) R_ ## X,
#define GEN_RING_STRING(X, D) #X,
#define GEN_RING_OUTER_DIST(X, D) D,
@@ -44,7 +51,8 @@ double OUTER_DISTS[] = {
};
double CENTRE_DISTS[sizeof(OUTER_DISTS)/sizeof(*OUTER_DISTS)];
-void init_centre_dists() {
+void init_centre_dists()
+{
CENTRE_DISTS[0] = 0;
for (int i = R_25; i < R_OUT; ++i)
CENTRE_DISTS[i] = (OUTER_DISTS[i] -
@@ -80,25 +88,43 @@ enum ring get_ring(double radius)
return R_OUT;
}
-struct ccoords gauss()
+double drand()
{
- double theta = 2 * M_PI * ((double)rand() / RAND_MAX);
- double r = sqrt(-2 * log(1 - (double)rand() / RAND_MAX));
- return (struct ccoords){ .x = r * cos(theta), .y = r * sin(theta) };
+ return (double)rand() / RAND_MAX;
+}
+
+double gauss(double mean, double stdev)
+{
+ static bool have_next;
+ static double next;
+
+ double curr;
+
+ if (have_next) {
+ curr = next;
+ } else {
+ double theta = 2 * M_PI * drand();
+ double r = sqrt(-2 * log(1 - drand()));
+
+ curr = r * cos(theta);
+ next = r * sin(theta);
+ }
+
+ have_next = !have_next;
+ return mean + (curr * stdev);
}
struct ccoords get_offset()
{
- struct ccoords g = gauss();
- return (struct ccoords){ .x = g.x * HORIZONTAL_STDEV,
- .y = g.y * VERTICAL_STDEV };
+ return (struct ccoords){ .x = gauss(0, HORIZONTAL_STDEV),
+ .y = gauss(0, VERTICAL_STDEV) };
}
-struct ccoords pol_to_cart(struct pcoords a)
+struct ccoords pol_to_cart(struct pcoords c)
{
- double t = a.a * (M_PI / 180);
- double x = a.r * cos(t);
- double y = a.r * sin(t);
+ double t = c.a * (M_PI / 180);
+ double x = c.r * cos(t);
+ double y = c.r * sin(t);
return (struct ccoords){ .x = x, .y = y };
}
@@ -120,28 +146,26 @@ struct pcoords throw_dart(struct pcoords target)
.y = cc.y + offset.y });
}
-struct segment get_segment(struct pcoords pos)
+struct segment get_segment(struct pcoords c)
{
- return (struct segment){ .sector = get_sector(pos.a),
- .ring = get_ring(pos.r) };
+ return (struct segment){ .sector = get_sector(c.a),
+ .ring = get_ring(c.r) };
}
char *segment_name(struct segment seg)
{
- char *str = malloc(5);
-
- if (seg.ring == R_BULL)
- strncpy(str, "BULL", 5);
- else if (seg.ring == R_25)
- strncpy(str, "25", 5);
- else if (seg.ring == R_OUT)
- strncpy(str, "OUT", 5);
- else if (seg.ring == R_TREBLE)
- snprintf(str, 5, "T%d", seg.sector);
- else if (seg.ring == R_DOUBLE)
- snprintf(str, 5, "D%d", seg.sector);
+ char *str = malloc(SEGMENT_MAX_LEN);
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstringop-truncation"
+ if (seg.ring == R_BULL || seg.ring == R_25 || seg.ring == R_OUT)
+ strncpy(str, RING_NAMES[seg.ring], SEGMENT_MAX_LEN);
else
- snprintf(str, 5, "%d", seg.sector);
+ snprintf(str, SEGMENT_MAX_LEN,
+ (seg.ring == R_TREBLE ? "T%d" :
+ (seg.ring == R_DOUBLE ? "D%d" : "%d")),
+ seg.sector);
+#pragma GCC diagnostic pop
return str;
}
@@ -167,7 +191,8 @@ int main()
res = throw_dart(t);
seg = get_segment(res);
char *name = segment_name(seg);
- printf("%d %f %f %d %s %s\n", seg.sector, res.a, res.r, seg.ring, RING_NAMES[seg.ring], name);
+ printf("%d %f %f %d %s %s\n", seg.sector, res.a, res.r, seg.ring,
+ RING_NAMES[seg.ring], name);
free(name);
}