From eda5d1668dbc8529453b7128c4ec2d51aeb1e783 Mon Sep 17 00:00:00 2001 From: David Vazgenovich Shakaryan Date: Fri, 15 Apr 2022 01:18:36 -0700 Subject: split code into multiple files --- Makefile | 6 +- board.c | 140 ++++++++++++++++ board.h | 57 +++++++ checkouts.c | 525 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ checkouts.h | 519 +---------------------------------------------------------- comp.c | 106 ++++++++++++ comp.h | 8 + curses.c | 144 +++++++++++++++++ curses.h | 40 +++++ dartbot.c | 465 +---------------------------------------------------- match.c | 22 +++ match.h | 24 +++ 12 files changed, 1080 insertions(+), 976 deletions(-) create mode 100644 board.c create mode 100644 board.h create mode 100644 checkouts.c create mode 100644 comp.c create mode 100644 comp.h create mode 100644 curses.c create mode 100644 curses.h create mode 100644 match.c create mode 100644 match.h diff --git a/Makefile b/Makefile index b4dcc2c..83ec0a8 100644 --- a/Makefile +++ b/Makefile @@ -1,16 +1,20 @@ CFLAGS += -O2 -Wall -Wextra -Wpedantic +CPPFLAGS += -MMD -MP LDFLAGS += -lm -lncurses TARGET := dartbot SRC := $(wildcard *.c) OBJ := $(SRC:.c=.o) +DEP := $(OBJ:.o=.d) all: $(TARGET) $(TARGET): $(OBJ) clean: - rm -f $(TARGET) $(OBJ) + rm -f $(TARGET) $(OBJ) $(DEP) + +-include $(DEP) .PHONY: all clean 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 +#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]; + +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 }; +} diff --git a/board.h b/board.h new file mode 100644 index 0000000..c7fb477 --- /dev/null +++ b/board.h @@ -0,0 +1,57 @@ +#ifndef BOARD_H +#define BOARD_H + +#include + +// board spec from WDF rules +#define WIRE_WIDTH 1.56 +#define INNER_DIAMETER_BULL 12.7 +#define INNER_DIAMETER_25 31.8 +#define DOUBLE_OUTER_EDGE 170.0 +#define TREBLE_OUTER_EDGE 107.4 +#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(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, +enum ring { + FOREACH_RING(GEN_RING_ENUM) + R_OUT +}; + +struct segment { + enum ring ring; + int sector; +}; + +void init_board(); + +struct ccoords { + double x, y; +}; + +struct pcoords { + double a, r; +}; + +struct segment get_segment(struct pcoords c); +char *segment_name(struct segment seg); +int segment_points(struct segment seg); +bool segment_is_double(struct segment seg); +struct pcoords segment_centre(struct segment seg); +struct segment segment_from_name(char *name); + +#endif diff --git a/checkouts.c b/checkouts.c new file mode 100644 index 0000000..230c264 --- /dev/null +++ b/checkouts.c @@ -0,0 +1,525 @@ +#ifndef CHECKOUT_H +#define CHECKOUT_H + +#include + +char *CHECKOUTS[][170] = { + { + NULL, // 1 + "D1", // 2 + NULL, // 3 + "D2", // 4 + NULL, // 5 + "D3", // 6 + NULL, // 7 + "D4", // 8 + NULL, // 9 + "D5", // 10 + NULL, // 11 + "D6", // 12 + NULL, // 13 + "D7", // 14 + NULL, // 15 + "D8", // 16 + NULL, // 17 + "D9", // 18 + NULL, // 19 + "D10", // 20 + NULL, // 21 + "D11", // 22 + NULL, // 23 + "D12", // 24 + NULL, // 25 + "D13", // 26 + NULL, // 27 + "D14", // 28 + NULL, // 29 + "D15", // 30 + NULL, // 31 + "D16", // 32 + NULL, // 33 + "D17", // 34 + NULL, // 35 + "D18", // 36 + NULL, // 37 + "D19", // 38 + NULL, // 39 + "D20", // 40 + NULL, // 41 + NULL, // 42 + NULL, // 43 + NULL, // 44 + NULL, // 45 + NULL, // 46 + NULL, // 47 + NULL, // 48 + NULL, // 49 + "BULL", // 50 + NULL, // 51 + NULL, // 52 + NULL, // 53 + NULL, // 54 + NULL, // 55 + NULL, // 56 + NULL, // 57 + NULL, // 58 + NULL, // 59 + NULL, // 60 + NULL, // 61 + NULL, // 62 + NULL, // 63 + NULL, // 64 + NULL, // 65 + NULL, // 66 + NULL, // 67 + NULL, // 68 + NULL, // 69 + NULL, // 70 + NULL, // 71 + NULL, // 72 + NULL, // 73 + NULL, // 74 + NULL, // 75 + NULL, // 76 + NULL, // 77 + NULL, // 78 + NULL, // 79 + NULL, // 80 + NULL, // 81 + NULL, // 82 + NULL, // 83 + NULL, // 84 + NULL, // 85 + NULL, // 86 + NULL, // 87 + NULL, // 88 + NULL, // 89 + NULL, // 90 + NULL, // 91 + NULL, // 92 + NULL, // 93 + NULL, // 94 + NULL, // 95 + NULL, // 96 + NULL, // 97 + NULL, // 98 + NULL, // 99 + NULL, // 100 + NULL, // 101 + NULL, // 102 + NULL, // 103 + NULL, // 104 + NULL, // 105 + NULL, // 106 + NULL, // 107 + NULL, // 108 + NULL, // 109 + NULL, // 110 + NULL, // 111 + NULL, // 112 + NULL, // 113 + NULL, // 114 + NULL, // 115 + NULL, // 116 + NULL, // 117 + NULL, // 118 + NULL, // 119 + NULL, // 120 + NULL, // 121 + NULL, // 122 + NULL, // 123 + NULL, // 124 + NULL, // 125 + NULL, // 126 + NULL, // 127 + NULL, // 128 + NULL, // 129 + NULL, // 130 + NULL, // 131 + NULL, // 132 + NULL, // 133 + NULL, // 134 + NULL, // 135 + NULL, // 136 + NULL, // 137 + NULL, // 138 + NULL, // 139 + NULL, // 140 + NULL, // 141 + NULL, // 142 + NULL, // 143 + NULL, // 144 + NULL, // 145 + NULL, // 146 + NULL, // 147 + NULL, // 148 + NULL, // 149 + NULL, // 150 + NULL, // 151 + NULL, // 152 + NULL, // 153 + NULL, // 154 + NULL, // 155 + NULL, // 156 + NULL, // 157 + NULL, // 158 + NULL, // 159 + NULL, // 160 + NULL, // 161 + NULL, // 162 + NULL, // 163 + NULL, // 164 + NULL, // 165 + NULL, // 166 + NULL, // 167 + NULL, // 168 + NULL, // 169 + NULL, // 170 + }, + { + NULL, // 1 + "D1", // 2 + "1", // 3 + "D2", // 4 + "1", // 5 + "D3", // 6 + "3", // 7 + "D4", // 8 + "1", // 9 + "D5", // 10 + "3", // 11 + "D6", // 12 + "5", // 13 + "D7", // 14 + "7", // 15 + "D8", // 16 + "1", // 17 + "D9", // 18 + "3", // 19 + "D10", // 20 + "17", // 21 + "D11", // 22 + "7", // 23 + "D12", // 24 + "17", // 25 + "D13", // 26 + "3", // 27 + "D14", // 28 + "17", // 29 + "D15", // 30 + "7", // 31 + "D16", // 32 + "17", // 33 + "D17", // 34 + "3", // 35 + "D18", // 36 + "17", // 37 + "D19", // 38 + "7", // 39 + "D20", // 40 + "17", // 41 + "10", // 42 + "3", // 43 + "12", // 44 + "13", // 45 + "14", // 46 + "15", // 47 + "16", // 48 + "17", // 49 + "18", // 50 + "19", // 51 + "20", // 52 + "13", // 53 + "14", // 54 + "15", // 55 + "16", // 56 + "17", // 57 + "18", // 58 + "19", // 59 + "20", // 60 + "T11", // 61 + "T12", // 62 + "T13", // 63 + "T14", // 64 + "T15", // 65 + "T16", // 66 + "T17", // 67 + "T18", // 68 + "T19", // 69 + "T20", // 70 + "T19", // 71 + "T16", // 72 + "T19", // 73 + "T16", // 74 + "T17", // 75 + "T20", // 76 + "T19", // 77 + "T18", // 78 + "T19", // 79 + "T20", // 80 + "T19", // 81 + "T14", // 82 + "T17", // 83 + "T20", // 84 + "T15", // 85 + "T18", // 86 + "T17", // 87 + "T16", // 88 + "T19", // 89 + "T18", // 90 + "T17", // 91 + "T20", // 92 + "T19", // 93 + "T18", // 94 + "T19", // 95 + "T20", // 96 + "T19", // 97 + "T20", // 98 + NULL, // 99 + "T20", // 100 + "T17", // 101 + NULL, // 102 + NULL, // 103 + "T18", // 104 + NULL, // 105 + NULL, // 106 + "T19", // 107 + NULL, // 108 + NULL, // 109 + "T20", // 110 + NULL, // 111 + NULL, // 112 + NULL, // 113 + NULL, // 114 + NULL, // 115 + NULL, // 116 + NULL, // 117 + NULL, // 118 + NULL, // 119 + NULL, // 120 + NULL, // 121 + NULL, // 122 + NULL, // 123 + NULL, // 124 + NULL, // 125 + NULL, // 126 + NULL, // 127 + NULL, // 128 + NULL, // 129 + NULL, // 130 + NULL, // 131 + NULL, // 132 + NULL, // 133 + NULL, // 134 + NULL, // 135 + NULL, // 136 + NULL, // 137 + NULL, // 138 + NULL, // 139 + NULL, // 140 + NULL, // 141 + NULL, // 142 + NULL, // 143 + NULL, // 144 + NULL, // 145 + NULL, // 146 + NULL, // 147 + NULL, // 148 + NULL, // 149 + NULL, // 150 + NULL, // 151 + NULL, // 152 + NULL, // 153 + NULL, // 154 + NULL, // 155 + NULL, // 156 + NULL, // 157 + NULL, // 158 + NULL, // 159 + NULL, // 160 + NULL, // 161 + NULL, // 162 + NULL, // 163 + NULL, // 164 + NULL, // 165 + NULL, // 166 + NULL, // 167 + NULL, // 168 + NULL, // 169 + NULL, // 170 + }, + { + NULL, // 1 + "D1", // 2 + "1", // 3 + "D2", // 4 + "1", // 5 + "D3", // 6 + "3", // 7 + "D4", // 8 + "1", // 9 + "D5", // 10 + "3", // 11 + "D6", // 12 + "5", // 13 + "D7", // 14 + "7", // 15 + "D8", // 16 + "1", // 17 + "D9", // 18 + "3", // 19 + "D10", // 20 + "5", // 21 + "D11", // 22 + "7", // 23 + "D12", // 24 + "9", // 25 + "D13", // 26 + "11", // 27 + "D14", // 28 + "13", // 29 + "D15", // 30 + "15", // 31 + "D16", // 32 + "1", // 33 + "D17", // 34 + "3", // 35 + "D18", // 36 + "5", // 37 + "D19", // 38 + "7", // 39 + "D20", // 40 + "9", // 41 + "10", // 42 + "11", // 43 + "12", // 44 + "13", // 45 + "14", // 46 + "15", // 47 + "16", // 48 + "17", // 49 + "18", // 50 + "19", // 51 + "20", // 52 + "13", // 53 + "14", // 54 + "15", // 55 + "16", // 56 + "17", // 57 + "18", // 58 + "19", // 59 + "20", // 60 + "BULL", // 61 + "T10", // 62 + "T13", // 63 + "T16", // 64 + "BULL", // 65 + "T14", // 66 + "T17", // 67 + "T12", // 68 + "T15", // 69 + "T18", // 70 + "T13", // 71 + "T16", // 72 + "T19", // 73 + "T14", // 74 + "T17", // 75 + "T16", // 76 + "T19", // 77 + "T18", // 78 + "T19", // 79 + "T20", // 80 + "T19", // 81 + "BULL", // 82 + "T17", // 83 + "T20", // 84 + "T15", // 85 + "T18", // 86 + "T17", // 87 + "T20", // 88 + "T19", // 89 + "T20", // 90 + "T17", // 91 + "T20", // 92 + "T19", // 93 + "T18", // 94 + "T19", // 95 + "T20", // 96 + "T19", // 97 + "T20", // 98 + "T19", // 99 + "T20", // 100 + "T19", // 101 + "T20", // 102 + "T19", // 103 + "T19", // 104 + "T20", // 105 + "T20", // 106 + "T19", // 107 + "T20", // 108 + "T20", // 109 + "T19", // 110 + "T19", // 111 + "T20", // 112 + "T19", // 113 + "T20", // 114 + "T19", // 115 + "T19", // 116 + "T20", // 117 + "T20", // 118 + "T19", // 119 + "T20", // 120 + "T20", // 121 + "T18", // 122 + "T19", // 123 + "T20", // 124 + "BULL", // 125 + "T19", // 126 + "T20", // 127 + "T20", // 128 + "T19", // 129 + "T20", // 130 + "T19", // 131 + "BULL", // 132 + "T14", // 133 + "T14", // 134 + "BULL", // 135 + "T20", // 136 + "T14", // 137 + "T20", // 138 + "T19", // 139 + "T15", // 140 + "T19", // 141 + "T20", // 142 + "T20", // 143 + "T20", // 144 + "T20", // 145 + "T19", // 146 + "T19", // 147 + "T20", // 148 + "T20", // 149 + "T20", // 150 + "T20", // 151 + "T20", // 152 + "T20", // 153 + "T19", // 154 + "T20", // 155 + "T20", // 156 + "T20", // 157 + "T20", // 158 + NULL, // 159 + "T20", // 160 + "T20", // 161 + NULL, // 162 + NULL, // 163 + "T19", // 164 + NULL, // 165 + NULL, // 166 + "T19", // 167 + NULL, // 168 + NULL, // 169 + "T20", // 170 + } +}; + +#endif diff --git a/checkouts.h b/checkouts.h index 230c264..5d0874e 100644 --- a/checkouts.h +++ b/checkouts.h @@ -3,523 +3,6 @@ #include -char *CHECKOUTS[][170] = { - { - NULL, // 1 - "D1", // 2 - NULL, // 3 - "D2", // 4 - NULL, // 5 - "D3", // 6 - NULL, // 7 - "D4", // 8 - NULL, // 9 - "D5", // 10 - NULL, // 11 - "D6", // 12 - NULL, // 13 - "D7", // 14 - NULL, // 15 - "D8", // 16 - NULL, // 17 - "D9", // 18 - NULL, // 19 - "D10", // 20 - NULL, // 21 - "D11", // 22 - NULL, // 23 - "D12", // 24 - NULL, // 25 - "D13", // 26 - NULL, // 27 - "D14", // 28 - NULL, // 29 - "D15", // 30 - NULL, // 31 - "D16", // 32 - NULL, // 33 - "D17", // 34 - NULL, // 35 - "D18", // 36 - NULL, // 37 - "D19", // 38 - NULL, // 39 - "D20", // 40 - NULL, // 41 - NULL, // 42 - NULL, // 43 - NULL, // 44 - NULL, // 45 - NULL, // 46 - NULL, // 47 - NULL, // 48 - NULL, // 49 - "BULL", // 50 - NULL, // 51 - NULL, // 52 - NULL, // 53 - NULL, // 54 - NULL, // 55 - NULL, // 56 - NULL, // 57 - NULL, // 58 - NULL, // 59 - NULL, // 60 - NULL, // 61 - NULL, // 62 - NULL, // 63 - NULL, // 64 - NULL, // 65 - NULL, // 66 - NULL, // 67 - NULL, // 68 - NULL, // 69 - NULL, // 70 - NULL, // 71 - NULL, // 72 - NULL, // 73 - NULL, // 74 - NULL, // 75 - NULL, // 76 - NULL, // 77 - NULL, // 78 - NULL, // 79 - NULL, // 80 - NULL, // 81 - NULL, // 82 - NULL, // 83 - NULL, // 84 - NULL, // 85 - NULL, // 86 - NULL, // 87 - NULL, // 88 - NULL, // 89 - NULL, // 90 - NULL, // 91 - NULL, // 92 - NULL, // 93 - NULL, // 94 - NULL, // 95 - NULL, // 96 - NULL, // 97 - NULL, // 98 - NULL, // 99 - NULL, // 100 - NULL, // 101 - NULL, // 102 - NULL, // 103 - NULL, // 104 - NULL, // 105 - NULL, // 106 - NULL, // 107 - NULL, // 108 - NULL, // 109 - NULL, // 110 - NULL, // 111 - NULL, // 112 - NULL, // 113 - NULL, // 114 - NULL, // 115 - NULL, // 116 - NULL, // 117 - NULL, // 118 - NULL, // 119 - NULL, // 120 - NULL, // 121 - NULL, // 122 - NULL, // 123 - NULL, // 124 - NULL, // 125 - NULL, // 126 - NULL, // 127 - NULL, // 128 - NULL, // 129 - NULL, // 130 - NULL, // 131 - NULL, // 132 - NULL, // 133 - NULL, // 134 - NULL, // 135 - NULL, // 136 - NULL, // 137 - NULL, // 138 - NULL, // 139 - NULL, // 140 - NULL, // 141 - NULL, // 142 - NULL, // 143 - NULL, // 144 - NULL, // 145 - NULL, // 146 - NULL, // 147 - NULL, // 148 - NULL, // 149 - NULL, // 150 - NULL, // 151 - NULL, // 152 - NULL, // 153 - NULL, // 154 - NULL, // 155 - NULL, // 156 - NULL, // 157 - NULL, // 158 - NULL, // 159 - NULL, // 160 - NULL, // 161 - NULL, // 162 - NULL, // 163 - NULL, // 164 - NULL, // 165 - NULL, // 166 - NULL, // 167 - NULL, // 168 - NULL, // 169 - NULL, // 170 - }, - { - NULL, // 1 - "D1", // 2 - "1", // 3 - "D2", // 4 - "1", // 5 - "D3", // 6 - "3", // 7 - "D4", // 8 - "1", // 9 - "D5", // 10 - "3", // 11 - "D6", // 12 - "5", // 13 - "D7", // 14 - "7", // 15 - "D8", // 16 - "1", // 17 - "D9", // 18 - "3", // 19 - "D10", // 20 - "17", // 21 - "D11", // 22 - "7", // 23 - "D12", // 24 - "17", // 25 - "D13", // 26 - "3", // 27 - "D14", // 28 - "17", // 29 - "D15", // 30 - "7", // 31 - "D16", // 32 - "17", // 33 - "D17", // 34 - "3", // 35 - "D18", // 36 - "17", // 37 - "D19", // 38 - "7", // 39 - "D20", // 40 - "17", // 41 - "10", // 42 - "3", // 43 - "12", // 44 - "13", // 45 - "14", // 46 - "15", // 47 - "16", // 48 - "17", // 49 - "18", // 50 - "19", // 51 - "20", // 52 - "13", // 53 - "14", // 54 - "15", // 55 - "16", // 56 - "17", // 57 - "18", // 58 - "19", // 59 - "20", // 60 - "T11", // 61 - "T12", // 62 - "T13", // 63 - "T14", // 64 - "T15", // 65 - "T16", // 66 - "T17", // 67 - "T18", // 68 - "T19", // 69 - "T20", // 70 - "T19", // 71 - "T16", // 72 - "T19", // 73 - "T16", // 74 - "T17", // 75 - "T20", // 76 - "T19", // 77 - "T18", // 78 - "T19", // 79 - "T20", // 80 - "T19", // 81 - "T14", // 82 - "T17", // 83 - "T20", // 84 - "T15", // 85 - "T18", // 86 - "T17", // 87 - "T16", // 88 - "T19", // 89 - "T18", // 90 - "T17", // 91 - "T20", // 92 - "T19", // 93 - "T18", // 94 - "T19", // 95 - "T20", // 96 - "T19", // 97 - "T20", // 98 - NULL, // 99 - "T20", // 100 - "T17", // 101 - NULL, // 102 - NULL, // 103 - "T18", // 104 - NULL, // 105 - NULL, // 106 - "T19", // 107 - NULL, // 108 - NULL, // 109 - "T20", // 110 - NULL, // 111 - NULL, // 112 - NULL, // 113 - NULL, // 114 - NULL, // 115 - NULL, // 116 - NULL, // 117 - NULL, // 118 - NULL, // 119 - NULL, // 120 - NULL, // 121 - NULL, // 122 - NULL, // 123 - NULL, // 124 - NULL, // 125 - NULL, // 126 - NULL, // 127 - NULL, // 128 - NULL, // 129 - NULL, // 130 - NULL, // 131 - NULL, // 132 - NULL, // 133 - NULL, // 134 - NULL, // 135 - NULL, // 136 - NULL, // 137 - NULL, // 138 - NULL, // 139 - NULL, // 140 - NULL, // 141 - NULL, // 142 - NULL, // 143 - NULL, // 144 - NULL, // 145 - NULL, // 146 - NULL, // 147 - NULL, // 148 - NULL, // 149 - NULL, // 150 - NULL, // 151 - NULL, // 152 - NULL, // 153 - NULL, // 154 - NULL, // 155 - NULL, // 156 - NULL, // 157 - NULL, // 158 - NULL, // 159 - NULL, // 160 - NULL, // 161 - NULL, // 162 - NULL, // 163 - NULL, // 164 - NULL, // 165 - NULL, // 166 - NULL, // 167 - NULL, // 168 - NULL, // 169 - NULL, // 170 - }, - { - NULL, // 1 - "D1", // 2 - "1", // 3 - "D2", // 4 - "1", // 5 - "D3", // 6 - "3", // 7 - "D4", // 8 - "1", // 9 - "D5", // 10 - "3", // 11 - "D6", // 12 - "5", // 13 - "D7", // 14 - "7", // 15 - "D8", // 16 - "1", // 17 - "D9", // 18 - "3", // 19 - "D10", // 20 - "5", // 21 - "D11", // 22 - "7", // 23 - "D12", // 24 - "9", // 25 - "D13", // 26 - "11", // 27 - "D14", // 28 - "13", // 29 - "D15", // 30 - "15", // 31 - "D16", // 32 - "1", // 33 - "D17", // 34 - "3", // 35 - "D18", // 36 - "5", // 37 - "D19", // 38 - "7", // 39 - "D20", // 40 - "9", // 41 - "10", // 42 - "11", // 43 - "12", // 44 - "13", // 45 - "14", // 46 - "15", // 47 - "16", // 48 - "17", // 49 - "18", // 50 - "19", // 51 - "20", // 52 - "13", // 53 - "14", // 54 - "15", // 55 - "16", // 56 - "17", // 57 - "18", // 58 - "19", // 59 - "20", // 60 - "BULL", // 61 - "T10", // 62 - "T13", // 63 - "T16", // 64 - "BULL", // 65 - "T14", // 66 - "T17", // 67 - "T12", // 68 - "T15", // 69 - "T18", // 70 - "T13", // 71 - "T16", // 72 - "T19", // 73 - "T14", // 74 - "T17", // 75 - "T16", // 76 - "T19", // 77 - "T18", // 78 - "T19", // 79 - "T20", // 80 - "T19", // 81 - "BULL", // 82 - "T17", // 83 - "T20", // 84 - "T15", // 85 - "T18", // 86 - "T17", // 87 - "T20", // 88 - "T19", // 89 - "T20", // 90 - "T17", // 91 - "T20", // 92 - "T19", // 93 - "T18", // 94 - "T19", // 95 - "T20", // 96 - "T19", // 97 - "T20", // 98 - "T19", // 99 - "T20", // 100 - "T19", // 101 - "T20", // 102 - "T19", // 103 - "T19", // 104 - "T20", // 105 - "T20", // 106 - "T19", // 107 - "T20", // 108 - "T20", // 109 - "T19", // 110 - "T19", // 111 - "T20", // 112 - "T19", // 113 - "T20", // 114 - "T19", // 115 - "T19", // 116 - "T20", // 117 - "T20", // 118 - "T19", // 119 - "T20", // 120 - "T20", // 121 - "T18", // 122 - "T19", // 123 - "T20", // 124 - "BULL", // 125 - "T19", // 126 - "T20", // 127 - "T20", // 128 - "T19", // 129 - "T20", // 130 - "T19", // 131 - "BULL", // 132 - "T14", // 133 - "T14", // 134 - "BULL", // 135 - "T20", // 136 - "T14", // 137 - "T20", // 138 - "T19", // 139 - "T15", // 140 - "T19", // 141 - "T20", // 142 - "T20", // 143 - "T20", // 144 - "T20", // 145 - "T19", // 146 - "T19", // 147 - "T20", // 148 - "T20", // 149 - "T20", // 150 - "T20", // 151 - "T20", // 152 - "T20", // 153 - "T19", // 154 - "T20", // 155 - "T20", // 156 - "T20", // 157 - "T20", // 158 - NULL, // 159 - "T20", // 160 - "T20", // 161 - NULL, // 162 - NULL, // 163 - "T19", // 164 - NULL, // 165 - NULL, // 166 - "T19", // 167 - NULL, // 168 - NULL, // 169 - "T20", // 170 - } -}; +extern char *CHECKOUTS[3][170]; #endif diff --git a/comp.c b/comp.c new file mode 100644 index 0000000..f1adb75 --- /dev/null +++ b/comp.c @@ -0,0 +1,106 @@ +#include "board.h" +#include "checkouts.h" +#include "comp.h" +#include "match.h" + +#include +#include +#include + +#define HORIZONTAL_STDEV 24 +#define VERTICAL_STDEV 24 + +double drand() +{ + 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() +{ + return (struct ccoords){ .x = gauss(0, HORIZONTAL_STDEV), + .y = gauss(0, VERTICAL_STDEV) }; +} + +struct ccoords pol_to_cart(struct pcoords c) +{ + 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 }; +} + +struct pcoords cart_to_pol(struct ccoords c) +{ + double a = atan2(c.y, c.x) * (180 / M_PI); + double r = sqrt(pow(c.x, 2) + pow(c.y, 2)); + + return (struct pcoords){ .a = a, .r = r }; +} + +struct pcoords throw_dart(struct pcoords target) +{ + struct ccoords cc = pol_to_cart(target); + struct ccoords offset = get_offset(); + + return cart_to_pol((struct ccoords){ .x = cc.x + offset.x, + .y = cc.y + offset.y }); +} + +struct segment next_dart(int rem, int darts_in_hand) +{ + char *c = NULL; + if (rem <= 170) + c = CHECKOUTS[darts_in_hand-1][rem-1]; + if (!c) c = "T20"; + + return segment_from_name(c); +} + +void comp_visit(struct leg *l) +{ + struct visit *v = l->visits + l->n_visits++; + v->darts = calloc(3, sizeof(*(v->darts))); + + for (int i = 0; i < 3; ++i) { + struct segment ts = next_dart(l->rem - v->points, 3 - i); + struct pcoords tc = segment_centre(ts); + struct pcoords dc = throw_dart(tc); + struct segment ds = get_segment(dc); + + v->darts[v->n_darts++] = ds; + v->points += segment_points(ds); + + if (l->rem - v->points == 0 && segment_is_double(ds)) + break; + + if (l->rem - v->points <= 1) { + v->points = 0; + break; + } + } + + l->rem -= v->points; + v->rem = l->rem; +} diff --git a/comp.h b/comp.h new file mode 100644 index 0000000..c7bc830 --- /dev/null +++ b/comp.h @@ -0,0 +1,8 @@ +#ifndef COMP_H +#define COMP_H + +#include "match.h" + +void comp_visit(struct leg *l); + +#endif diff --git a/curses.c b/curses.c new file mode 100644 index 0000000..4169906 --- /dev/null +++ b/curses.c @@ -0,0 +1,144 @@ +#include "curses.h" +#include "match.h" + +#include +#include + +WINDOW *w, *titlew, *statw, *promptw; + +void init_curses() +{ + initscr(); + refresh(); + start_color(); + init_colours(); + curs_set(0); + noecho(); + + w = newwin(LINES-3, COLS, 1, 0); + titlew = newwin(1, COLS, 0, 0); + statw = newwin(1, COLS, LINES-2, 0); + promptw = newwin(1, COLS, LINES-1, 0); + wbkgd(titlew, COLOR_PAIR(C_STATUS)); + wbkgd(statw, COLOR_PAIR(C_STATUS)); + waddstr(titlew, " dartbot"); + wrefresh(titlew); +} + +void free_curses() +{ + delwin(promptw); + delwin(statw); + delwin(titlew); + delwin(w); + endwin(); +} + +void init_colours() +{ + FOREACH_COLOUR(GEN_COLOUR_INIT_PAIR) +} + +void curses_status(char *status) +{ + wmove(statw, 0, 0); + wclrtoeol(statw); + waddstr(statw, status); + wrefresh(statw); +} + +void curses_prompt(char *prompt) +{ + wmove(promptw, 0, 0); + wclrtoeol(promptw); + waddstr(promptw, prompt); + wrefresh(promptw); +} + +void flushbuf(char *buf, int *buflen, int col) +{ + if (!(*buflen)) return; + + if (col) wattron(w, col); + waddstr(w, buf); + if (col) wattroff(w, col); + + *buflen = 0; +} + +int points_colour(int points) +{ + if (points >= 180) + return COLOR_PAIR(C_140) | A_BOLD; + else if (points >= 140) + return COLOR_PAIR(C_140); + else if (points >= 100) + return COLOR_PAIR(C_100); + else if (points >= 60) + return COLOR_PAIR(C_60); + else if (points >= 40) + return COLOR_PAIR(C_40); + else if (points >= 20) + return COLOR_PAIR(C_20); + else if (points > 0) + return COLOR_PAIR(C_0); + else + return COLOR_PAIR(C_0) | A_BOLD; +} + +void curses_draw(struct leg *l1, struct leg *l2) +{ + werase(w); + + char buf[100]; + int buflen = 0; + + int wlines = LINES - 3; + int n_visits = l1->n_visits > l2->n_visits ? l1->n_visits : l2->n_visits; + int start_visit = (wlines > n_visits) ? 0 : (n_visits - wlines); + int offset = 0; + + if (start_visit == 0 && wlines > n_visits) { + wmove(w, (offset++)-start_visit, 1); + buflen = sprintf(buf, "(%2d)", 0); + flushbuf(buf, &buflen, COLOR_PAIR(C_VISIT)); + buflen = sprintf(buf, " %3d %3d", l1->start, l2->start); + flushbuf(buf, &buflen, 0); + } + + for (int i = start_visit; i < n_visits; ++i) { + wmove(w, offset+i-start_visit, 1); + buflen += sprintf(buf + buflen, "(%2d)", i+1); + flushbuf(buf, &buflen, COLOR_PAIR(C_VISIT)); + buflen += sprintf(buf + buflen, " "); + flushbuf(buf, &buflen, 0); + + struct visit *v = l1->visits + i; + + flushbuf(buf, &buflen, 0); + buflen += sprintf(buf + buflen, "%3d", v->points); + flushbuf(buf, &buflen, points_colour(v->points)); + + buflen += sprintf(buf + buflen, " %3d", v->rem); + + if (i < l2->n_visits) { + v = l2->visits + i; + + buflen += sprintf(buf + buflen, " %3d ", v->rem); + + flushbuf(buf, &buflen, 0); + buflen += sprintf(buf + buflen, "%3d", v->points); + flushbuf(buf, &buflen, points_colour(v->points)); + + for (int j = 0; j < v->n_darts; ++j) { + char *n = segment_name(v->darts[j]); + buflen += sprintf(buf + buflen, j == 0 ? " %4s" :" %4s", n); + free(n); + } + flushbuf(buf, &buflen, COLOR_PAIR(C_DARTS)); + } + + flushbuf(buf, &buflen, 0); + } + wrefresh(w); +} diff --git a/curses.h b/curses.h new file mode 100644 index 0000000..4a34a16 --- /dev/null +++ b/curses.h @@ -0,0 +1,40 @@ +#ifndef CURSES_H +#define CURSES_H + +#include "match.h" + +#include + +extern WINDOW *w, *titlew, *statw, *promptw; + +#define FOREACH_COLOUR(M) \ + M(140, 82, 0) \ + M(100, 154, 0) \ + M(60, 226, 0) \ + M(40, 214, 0) \ + M(20, 202, 0) \ + M(0, 196, 0) \ + M(DARTS, 235, 0) \ + M(VISIT, 244, 0) \ + M(STATUS, 7, 4) +#define GEN_COLOUR_ENUM(X, FG, BG) C_ ## X, +#define GEN_COLOUR_INIT_PAIR(X, FG, BG) init_pair(C_ ## X, FG, BG); + +enum colour { + C_DEFAULT, // index 0 is reserved for default colours + FOREACH_COLOUR(GEN_COLOUR_ENUM) +}; + +void init_curses(); +void free_curses(); +void init_colours(); + +void curses_status(char *status); +void curses_prompt(char *prompt); + +void flushbuf(char *buf, int *buflen, int col); +int points_colour(int points); + +void curses_draw(struct leg *l1, struct leg *l2); + +#endif diff --git a/dartbot.c b/dartbot.c index abd6045..314548f 100644 --- a/dartbot.c +++ b/dartbot.c @@ -1,338 +1,13 @@ +#include "board.h" #include "checkouts.h" +#include "comp.h" +#include "curses.h" +#include "match.h" -#include #include -#include +#include #include -#include #include -#include - -#define HORIZONTAL_STDEV 24 -#define VERTICAL_STDEV 24 - -// board spec from WDF rules -#define WIRE_WIDTH 1.56 -#define INNER_DIAMETER_BULL 12.7 -#define INNER_DIAMETER_25 31.8 -#define DOUBLE_OUTER_EDGE 170.0 -#define TREBLE_OUTER_EDGE 107.4 -#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(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, - -enum ring { - FOREACH_RING(GEN_RING_ENUM) - R_OUT -}; - -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)]; -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)); -} - -int SECTORS[] = { 20, 1, 18, 4, 13, 6, 10, 15, 2, 17, 3, 19, 7, - 16, 8, 11, 14, 9, 12, 5 }; -#define NUM_SECTORS (sizeof(SECTORS) / sizeof(*SECTORS)) -#define SECTOR_WIDTH (360.0 / NUM_SECTORS) -int SECTOR_INDS[NUM_SECTORS]; -double SECTOR_ANGLES[NUM_SECTORS]; -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; - } -} - -#define FOREACH_COLOUR(M) \ - M(140, 82, 0) \ - M(100, 154, 0) \ - M(60, 226, 0) \ - M(40, 214, 0) \ - M(20, 202, 0) \ - M(0, 196, 0) \ - M(DARTS, 235, 0) \ - M(VISIT, 244, 0) \ - M(STATUS, 7, 4) -#define GEN_COLOUR_ENUM(X, FG, BG) C_ ## X, -#define GEN_COLOUR_INIT_PAIR(X, FG, BG) init_pair(C_ ## X, FG, BG); - -enum colour { - C_DEFAULT, // index 0 is reserved for default colours - FOREACH_COLOUR(GEN_COLOUR_ENUM) -}; - -void init_colours() -{ - FOREACH_COLOUR(GEN_COLOUR_INIT_PAIR) -} - -WINDOW *w, *titlew, *statw, *promptw; - -struct ccoords { - double x, y; -}; - -struct pcoords { - double a, r; -}; - -struct segment { - enum ring ring; - int sector; -}; - -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; -} - -double drand() -{ - 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() -{ - return (struct ccoords){ .x = gauss(0, HORIZONTAL_STDEV), - .y = gauss(0, VERTICAL_STDEV) }; -} - -struct ccoords pol_to_cart(struct pcoords c) -{ - 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 }; -} - -struct pcoords cart_to_pol(struct ccoords c) -{ - double a = atan2(c.y, c.x) * (180 / M_PI); - double r = sqrt(pow(c.x, 2) + pow(c.y, 2)); - - return (struct pcoords){ .a = a, .r = r }; -} - -struct pcoords throw_dart(struct pcoords target) -{ - struct ccoords cc = pol_to_cart(target); - struct ccoords offset = get_offset(); - - return cart_to_pol((struct ccoords){ .x = cc.x + offset.x, - .y = cc.y + offset.y }); -} - -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 }; -} - -struct segment next_dart(int rem, int darts_in_hand) -{ - char *c = NULL; - if (rem <= 170) - c = CHECKOUTS[darts_in_hand-1][rem-1]; - if (!c) c = "T20"; - - return segment_from_name(c); -} - -struct visit { - int points; - int rem; - int n_darts; - struct segment *darts; -}; - -struct leg { - char *name; - int start; - int rem; - int n_visits; - struct visit *visits; -}; - -struct leg *leg_init(int points, char *name) -{ - struct leg *l = calloc(1, sizeof(*l)); - l->name = name; - l->start = l->rem = points; - l->visits = calloc(1000, sizeof(*(l->visits))); // FIXME - - return l; -} - -void leg_free(struct leg *l) -{ - for (int i = 0; i < l->n_visits; ++i) - if (l->visits[i].darts) - free(l->visits[i].darts); - free(l->visits); - free(l); -} - -void comp_visit(struct leg *l) -{ - struct visit *v = l->visits + l->n_visits++; - v->darts = calloc(3, sizeof(*(v->darts))); - - for (int i = 0; i < 3; ++i) { - struct segment ts = next_dart(l->rem - v->points, 3 - i); - struct pcoords tc = segment_centre(ts); - struct pcoords dc = throw_dart(tc); - struct segment ds = get_segment(dc); - - v->darts[v->n_darts++] = ds; - v->points += segment_points(ds); - - if (l->rem - v->points == 0 && segment_is_double(ds)) - break; - - if (l->rem - v->points <= 1) { - v->points = 0; - break; - } - } - - l->rem -= v->points; - v->rem = l->rem; -} void test_match(int start_points) { @@ -357,22 +32,6 @@ void test_match(int start_points) leg_free(l); } -void curses_status(char *status) -{ - wmove(statw, 0, 0); - wclrtoeol(statw); - waddstr(statw, status); - wrefresh(statw); -} - -void curses_prompt(char *prompt) -{ - wmove(promptw, 0, 0); - wclrtoeol(promptw); - waddstr(promptw, prompt); - wrefresh(promptw); -} - void user_visit(struct leg *l) { struct visit *v = l->visits + l->n_visits++; @@ -425,113 +84,10 @@ void user_visit(struct leg *l) v->rem = l->rem; } -int points_colour(int points) -{ - if (points >= 180) - return COLOR_PAIR(C_140) | A_BOLD; - else if (points >= 140) - return COLOR_PAIR(C_140); - else if (points >= 100) - return COLOR_PAIR(C_100); - else if (points >= 60) - return COLOR_PAIR(C_60); - else if (points >= 40) - return COLOR_PAIR(C_40); - else if (points >= 20) - return COLOR_PAIR(C_20); - else if (points > 0) - return COLOR_PAIR(C_0); - else - return COLOR_PAIR(C_0) | A_BOLD; -} - -void flushbuf(char *buf, int *buflen, int col) -{ - if (!(*buflen)) return; - - if (col) wattron(w, col); - waddstr(w, buf); - if (col) wattroff(w, col); - - *buflen = 0; -} - -void curses_draw(struct leg *l1, struct leg *l2) -{ - werase(w); - - char buf[100]; - int buflen = 0; - - int wlines = LINES - 3; - int n_visits = l1->n_visits > l2->n_visits ? l1->n_visits : l2->n_visits; - int start_visit = (wlines > n_visits) ? 0 : (n_visits - wlines); - int offset = 0; - - if (start_visit == 0 && wlines > n_visits) { - wmove(w, (offset++)-start_visit, 1); - buflen = sprintf(buf, "(%2d)", 0); - flushbuf(buf, &buflen, COLOR_PAIR(C_VISIT)); - buflen = sprintf(buf, " %3d %3d", l1->start, l2->start); - flushbuf(buf, &buflen, 0); - } - - for (int i = start_visit; i < n_visits; ++i) { - wmove(w, offset+i-start_visit, 1); - buflen += sprintf(buf + buflen, "(%2d)", i+1); - flushbuf(buf, &buflen, COLOR_PAIR(C_VISIT)); - buflen += sprintf(buf + buflen, " "); - flushbuf(buf, &buflen, 0); - - struct visit *v = l1->visits + i; - - flushbuf(buf, &buflen, 0); - buflen += sprintf(buf + buflen, "%3d", v->points); - flushbuf(buf, &buflen, points_colour(v->points)); - - buflen += sprintf(buf + buflen, " %3d", v->rem); - - if (i < l2->n_visits) { - v = l2->visits + i; - - buflen += sprintf(buf + buflen, " %3d ", v->rem); - - flushbuf(buf, &buflen, 0); - buflen += sprintf(buf + buflen, "%3d", v->points); - flushbuf(buf, &buflen, points_colour(v->points)); - - for (int j = 0; j < v->n_darts; ++j) { - char *n = segment_name(v->darts[j]); - buflen += sprintf(buf + buflen, j == 0 ? " %4s" :" %4s", n); - free(n); - } - flushbuf(buf, &buflen, COLOR_PAIR(C_DARTS)); - } - - flushbuf(buf, &buflen, 0); - } - - wrefresh(w); -} - void curses_match(int start_points, char *n1, void (*f1)(struct leg *), char *n2, void (*f2)(struct leg *)) { - initscr(); - refresh(); - start_color(); - init_colours(); - curs_set(0); - noecho(); - - w = newwin(LINES-3, COLS, 1, 0); - titlew = newwin(1, COLS, 0, 0); - statw = newwin(1, COLS, LINES-2, 0); - promptw = newwin(1, COLS, LINES-1, 0); - wbkgd(titlew, COLOR_PAIR(C_STATUS)); - wbkgd(statw, COLOR_PAIR(C_STATUS)); - waddstr(titlew, " dartbot"); - wrefresh(titlew); + init_curses(); struct leg *l1 = leg_init(start_points, n1); struct leg *l2 = leg_init(start_points, n2); @@ -555,11 +111,7 @@ void curses_match(int start_points, char *n1, void (*f1)(struct leg *), leg_free(l1); leg_free(l2); wgetch(w); - delwin(promptw); - delwin(statw); - delwin(titlew); - delwin(w); - endwin(); + free_curses(); } void cvc_curses_match(int start_points) @@ -580,8 +132,7 @@ void pvp_curses_match(int start_points) int main() { srand(time(NULL)); - init_sectors(); - init_centre_dists(); + init_board(); //cvc_curses_match(501); pvc_curses_match(501); diff --git a/match.c b/match.c new file mode 100644 index 0000000..17ce3b1 --- /dev/null +++ b/match.c @@ -0,0 +1,22 @@ +#include "match.h" + +#include + +struct leg *leg_init(int points, char *name) +{ + struct leg *l = calloc(1, sizeof(*l)); + l->name = name; + l->start = l->rem = points; + l->visits = calloc(1000, sizeof(*(l->visits))); // FIXME + + return l; +} + +void leg_free(struct leg *l) +{ + for (int i = 0; i < l->n_visits; ++i) + if (l->visits[i].darts) + free(l->visits[i].darts); + free(l->visits); + free(l); +} diff --git a/match.h b/match.h new file mode 100644 index 0000000..0b44b45 --- /dev/null +++ b/match.h @@ -0,0 +1,24 @@ +#ifndef MATCH_H +#define MATCH_H + +#include "board.h" + +struct visit { + int points; + int rem; + int n_darts; + struct segment *darts; +}; + +struct leg { + char *name; + int start; + int rem; + int n_visits; + struct visit *visits; +}; + +struct leg *leg_init(int points, char *name); +void leg_free(struct leg *l); + +#endif -- cgit v1.2.3-70-g09d2