#include "board.h" #include #include #include #include #include #include #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]; static const char *SECTOR_NAMES[] = { FOREACH_SECTOR(GEN_SECTOR_STR) FOREACH_SECTOR(GEN_SECTOR_STR_D) FOREACH_SECTOR(GEN_SECTOR_STR_T) }; static const char *RING_NAMES[] = { FOREACH_RING(GEN_RING_STR) "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) }; } const char *segment_name(struct segment seg) { if (seg.ring == R_BULL || seg.ring == R_25 || seg.ring == R_OUT) return RING_NAMES[seg.ring]; int ind = seg.sector - 1; if (seg.ring == R_DOUBLE) ind += 20; else if (seg.ring == R_TREBLE) ind += 40; return SECTOR_NAMES[ind]; } 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 }; }