diff options
author | David Vazgenovich Shakaryan <dvshakaryan@gmail.com> | 2022-04-05 23:22:31 -0700 |
---|---|---|
committer | David Vazgenovich Shakaryan <dvshakaryan@gmail.com> | 2022-04-05 23:22:31 -0700 |
commit | 2dfa6a526739932bba86a3b66d031e8106bd1bb3 (patch) | |
tree | 12aaf480e8b537f2f87baafa4ea2d1ba21835483 | |
parent | 1fdd0f7b92b7d5f1b0e3c5cda96d1e46f6b3b790 (diff) | |
download | dartboat-2dfa6a526739932bba86a3b66d031e8106bd1bb3.tar.gz dartboat-2dfa6a526739932bba86a3b66d031e8106bd1bb3.tar.xz |
add ability to play a solo test match
-rw-r--r-- | dartbot.c | 159 |
1 files changed, 134 insertions, 25 deletions
@@ -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; } |