summaryrefslogtreecommitdiff
path: root/board.c
diff options
context:
space:
mode:
authorDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2022-04-15 01:18:36 -0700
committerDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2022-04-15 01:18:36 -0700
commiteda5d1668dbc8529453b7128c4ec2d51aeb1e783 (patch)
tree2ee5072865a761c540be454abcb6871358be65ea /board.c
parent3ffb56f167a1855731b50eebfc484b7cc5f21036 (diff)
downloaddartboat-eda5d1668dbc8529453b7128c4ec2d51aeb1e783.tar.gz
dartboat-eda5d1668dbc8529453b7128c4ec2d51aeb1e783.tar.xz
split code into multiple files
Diffstat (limited to 'board.c')
-rw-r--r--board.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/board.c b/board.c
new file mode 100644
index 0000000..1a543ee
--- /dev/null
+++ b/board.c
@@ -0,0 +1,140 @@
+#include "board.h"
+
+#include <math.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define NUM_SECTORS (sizeof(SECTORS) / sizeof(*SECTORS))
+#define SECTOR_WIDTH (360.0 / NUM_SECTORS)
+int SECTORS[] = { 20, 1, 18, 4, 13, 6, 10, 15, 2, 17, 3, 19, 7,
+ 16, 8, 11, 14, 9, 12, 5 };
+int SECTOR_INDS[NUM_SECTORS];
+double SECTOR_ANGLES[NUM_SECTORS];
+
+char *RING_NAMES[] = {
+ FOREACH_RING(GEN_RING_STRING)
+ "OUT"
+};
+double OUTER_DISTS[] = {
+ FOREACH_RING(GEN_RING_OUTER_DIST)
+};
+double CENTRE_DISTS[sizeof(OUTER_DISTS) / sizeof(*OUTER_DISTS)];
+
+static void init_sectors()
+{
+ for (size_t i = 0; i < NUM_SECTORS; ++i) {
+ SECTOR_INDS[SECTORS[i]-1] = i;
+
+ double angle = 90 - (i * SECTOR_WIDTH);
+ if (angle < 0) angle += 360;
+ SECTOR_ANGLES[i] = angle;
+ }
+}
+
+static void init_centre_dists()
+{
+ CENTRE_DISTS[0] = 0;
+ for (int i = R_25; i < R_OUT; ++i)
+ CENTRE_DISTS[i] = (OUTER_DISTS[i] -
+ ((OUTER_DISTS[i] - OUTER_DISTS[i-1]) / 2));
+}
+
+void init_board()
+{
+ init_sectors();
+ init_centre_dists();
+}
+
+int get_sector(double angle)
+{
+ double shifted = angle - 90 - (SECTOR_WIDTH/2);
+ return SECTORS[NUM_SECTORS - 1 -
+ (int)((shifted - (360 * floor(shifted/360))) / SECTOR_WIDTH)];
+}
+
+enum ring get_ring(double radius)
+{
+ for (int i = R_BULL; i < R_OUT; ++i)
+ if (radius < OUTER_DISTS[i])
+ return i;
+
+ return R_OUT;
+}
+
+struct segment get_segment(struct pcoords c)
+{
+ return (struct segment){ .sector = get_sector(c.a),
+ .ring = get_ring(c.r) };
+}
+
+char *segment_name(struct segment seg)
+{
+ 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, SEGMENT_MAX_LEN,
+ (seg.ring == R_TREBLE ? "T%d" :
+ (seg.ring == R_DOUBLE ? "D%d" : "%d")),
+ seg.sector);
+#pragma GCC diagnostic pop
+
+ return str;
+}
+
+int segment_points(struct segment seg)
+{
+ if (seg.ring == R_BULL)
+ return 50;
+ else if (seg.ring == R_25)
+ return 25;
+ else if (seg.ring == R_TREBLE)
+ return 3 * seg.sector;
+ else if (seg.ring == R_DOUBLE)
+ return 2 * seg.sector;
+ else if (seg.ring == R_SMALL || seg.ring == R_BIG)
+ return seg.sector;
+ return 0;
+}
+
+bool segment_is_double(struct segment seg)
+{
+ if (seg.ring == R_DOUBLE || seg.ring == R_BULL)
+ return true;
+ return false;
+}
+
+struct pcoords segment_centre(struct segment seg)
+{
+ return (struct pcoords){ .a = SECTOR_ANGLES[SECTOR_INDS[seg.sector-1]],
+ .r = CENTRE_DISTS[seg.ring] };
+}
+
+struct segment segment_from_name(char *name)
+{
+ int s = 20;
+ enum ring r;
+
+ if (!strcmp(name, "BULL")) {
+ r = R_BULL;
+ } else if (!strcmp(name, "25")) {
+ r = R_25;
+ } else if (name[0] == 'T') {
+ r = R_TREBLE;
+ s = atoi(name+1);
+ } else if (name[0] == 'D') {
+ r = R_DOUBLE;
+ s = atoi(name+1);
+ } else {
+ r = R_BIG;
+ s = atoi(name);
+ }
+
+ return (struct segment){ .sector = s, .ring = r };
+}