summaryrefslogtreecommitdiff
path: root/dartbot.c
diff options
context:
space:
mode:
authorDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2022-04-05 23:22:31 -0700
committerDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2022-04-05 23:22:31 -0700
commit2dfa6a526739932bba86a3b66d031e8106bd1bb3 (patch)
tree12aaf480e8b537f2f87baafa4ea2d1ba21835483 /dartbot.c
parent1fdd0f7b92b7d5f1b0e3c5cda96d1e46f6b3b790 (diff)
downloaddartboat-2dfa6a526739932bba86a3b66d031e8106bd1bb3.tar.gz
dartboat-2dfa6a526739932bba86a3b66d031e8106bd1bb3.tar.xz
add ability to play a solo test match
Diffstat (limited to 'dartbot.c')
-rw-r--r--dartbot.c159
1 files changed, 134 insertions, 25 deletions
diff --git a/dartbot.c b/dartbot.c
index 7367648..c79706f 100644
--- a/dartbot.c
+++ b/dartbot.c
@@ -5,8 +5,8 @@
#include <string.h>
#include <time.h>
-#define HORIZONTAL_STDEV 50
-#define VERTICAL_STDEV 50
+#define HORIZONTAL_STDEV 24
+#define VERTICAL_STDEV 24
// board spec from WDF rules
#define WIRE_WIDTH 1.56
@@ -33,8 +33,22 @@
#define GEN_RING_STRING(X, D) #X,
#define GEN_RING_OUTER_DIST(X, D) D,
-int sectors[] = { 20, 1, 18, 4, 13, 6, 10, 15, 2, 17, 3, 19, 7,
+int SECTORS[] = { 20, 1, 18, 4, 13, 6, 10, 15, 2, 17, 3, 19, 7,
16, 8, 11, 14, 9, 12, 5 };
+#define LEN_SECTORS (sizeof(SECTORS) / sizeof(*SECTORS))
+#define SECTOR_WIDTH (360.0 / LEN_SECTORS)
+int SECTOR_INDS[LEN_SECTORS];
+double SECTOR_ANGLES[LEN_SECTORS];
+void init_sectors()
+{
+ for (size_t i = 0; i < LEN_SECTORS; ++i) {
+ SECTOR_INDS[SECTORS[i]-1] = i;
+
+ double angle = 90 - (i * SECTOR_WIDTH);
+ if (angle < 0) angle += 360;
+ SECTOR_ANGLES[i] = angle;
+ }
+}
enum ring {
FOREACH_RING(GEN_RING_ENUM)
@@ -74,9 +88,9 @@ struct segment {
int get_sector(double angle)
{
- //return sectors[(int)(fmod(angle + 279, 360) / 18)];
- double shifted = angle + 279;
- return sectors[(int)((shifted - (360 * floor(shifted / 360))) / 18)];
+ double shifted = angle - 90 - (SECTOR_WIDTH/2);
+ return SECTORS[LEN_SECTORS - 1 -
+ (int)((shifted - (360 * floor(shifted/360))) / SECTOR_WIDTH)];
}
enum ring get_ring(double radius)
@@ -170,6 +184,118 @@ char *segment_name(struct segment seg)
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 };
+}
+
+struct visit {
+ int points;
+ int darts_thrown;
+ struct segment *darts;
+};
+
+struct visit test_visit(int rem)
+{
+ struct visit v = { .points = 0, .darts_thrown = 0,
+ .darts = calloc(3, sizeof(struct segment)) };
+
+ for (int i = 0; i < 3; ++i) {
+ struct segment ts;
+ if (rem - v.points <= 40 && (rem - v.points) % 2 == 0)
+ ts = (struct segment){ .ring = R_DOUBLE,
+ .sector = (rem - v.points) / 2 };
+ else if (rem - v.points <= 40 && (rem - v.points) % 2 == 1)
+ ts = segment_from_name("1");
+ else
+ ts = segment_from_name("T20");
+ struct pcoords tc = segment_centre(ts);
+ struct pcoords dc = throw_dart(tc);
+ struct segment ds = get_segment(dc);
+
+ v.darts[i] = ds;
+ ++v.darts_thrown;
+ v.points += segment_points(ds);
+
+ if (rem - v.points == 0 && segment_is_double(ds))
+ break;
+
+ if (rem - v.points <= 1) {
+ v.points = 0;
+ break;
+ }
+ }
+
+ return v;
+}
+
+void test_match(int start_points)
+{
+ printf("(%2d) %3d\n", 0, start_points);
+ int visits = 0;
+
+ int rem = start_points;
+ while(rem > 0) {
+ ++visits;
+ struct visit v = test_visit(rem);
+ rem -= v.points;
+
+ printf("(%2d) %3d", visits, rem);
+ for (int i = 0; i < v.darts_thrown; ++i) {
+ char *n = segment_name(v.darts[i]);
+ printf(i == 0 ? " %4s" :" %4s", n);
+ free(n);
+ }
+ printf("\n");
+ }
+}
+
int main()
{
/*
@@ -181,27 +307,10 @@ int main()
endwin();
*/
srand(time(NULL));
+ init_sectors();
init_centre_dists();
- struct pcoords t = { .a = 90, .r = 100 };
- struct pcoords res = throw_dart(t);
- struct segment seg = get_segment(res);
-
- for (int i = 0; i < 20; ++i) {
- 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);
- free(name);
- }
-
- /*
- printf("\n");
- for (int i = 0; i < 6; i++) {
- printf("%.2f\n%.2f\n\n", CENTRE_DISTS[i], OUTER_DISTS[i]);
- }
- */
+ test_match(501);
return 0;
}