diff options
Diffstat (limited to 'dartbot.c')
| -rw-r--r-- | dartbot.c | 97 | 
1 files changed, 61 insertions, 36 deletions
| @@ -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);  	} | 
