summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dartbot.c210
1 files changed, 93 insertions, 117 deletions
diff --git a/dartbot.c b/dartbot.c
index defd528..c1db96d 100644
--- a/dartbot.c
+++ b/dartbot.c
@@ -36,24 +36,29 @@
#define GEN_RING_STRING(X, D) #X,
#define GEN_RING_OUTER_DIST(X, D) D,
-#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(PROMPT, 0, 7)
-#define GEN_COLOUR_ENUM(X, FG, BG) C_ ## X,
-#define GEN_COLOUR_INIT_PAIR(X, FG, BG) init_pair(C_ ## X, FG, BG);
+enum ring {
+ FOREACH_RING(GEN_RING_ENUM)
+ R_OUT
+};
-enum colour {
- C_DEFAULT, // need rest to start at 1
- FOREACH_COLOUR(GEN_COLOUR_ENUM)
+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))
@@ -71,29 +76,31 @@ void init_sectors()
}
}
-enum ring {
- FOREACH_RING(GEN_RING_ENUM)
- R_OUT
-};
-
-char *RING_NAMES[] = {
- FOREACH_RING(GEN_RING_STRING)
- "OUT"
-};
+#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(PROMPT, 0, 7)
+#define GEN_COLOUR_ENUM(X, FG, BG) C_ ## X,
+#define GEN_COLOUR_INIT_PAIR(X, FG, BG) init_pair(C_ ## X, FG, BG);
-double OUTER_DISTS[] = {
- FOREACH_RING(GEN_RING_OUTER_DIST)
+enum colour {
+ C_DEFAULT, // index 0 is reserved for default colours
+ FOREACH_COLOUR(GEN_COLOUR_ENUM)
};
-double CENTRE_DISTS[sizeof(OUTER_DISTS)/sizeof(*OUTER_DISTS)];
-void init_centre_dists()
+void init_colours()
{
- 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));
+ FOREACH_COLOUR(GEN_COLOUR_INIT_PAIR)
}
+WINDOW *w, *statw;
+
struct ccoords {
double x, y;
};
@@ -298,7 +305,7 @@ void leg_free(struct leg *l)
free(l);
}
-void comp_visit(__attribute__((unused)) WINDOW *w, struct leg *l)
+void comp_visit(struct leg *l)
{
struct visit *v = l->visits + l->n_visits++;
v->darts = calloc(3, sizeof(*(v->darts)));
@@ -330,9 +337,9 @@ void test_match(int start_points)
struct leg *l = leg_init(start_points);
while(l->rem > 0)
- comp_visit(NULL, l);
+ comp_visit(l);
- printf("(%2d) %3d\n", l->n_visits, l->start);
+ printf("(%2d) %3d\n", 0, l->start);
for(int i = 0; i < l->n_visits; ++i) {
struct visit *v = l->visits + i;
printf("(%2d) %3d %3d", i+1, v->points, v->rem);
@@ -348,85 +355,44 @@ void test_match(int start_points)
leg_free(l);
}
-void draw(WINDOW *w, struct leg *l)
+void curses_status(char *status)
{
- werase(w);
- box(w, 0, 0);
- wmove(w, 0, 2);
- waddstr(w, "dartbot");
-
- char buf[100];
- int buflen = 0;
-
- int offset = 2;
- int start_visit = (LINES - 3 > l->n_visits) ? 0 : (l->n_visits - (LINES - 3));
- if (start_visit == 0 && LINES - 3 > l->n_visits) {
- wmove(w, (offset++)-start_visit, 2);
- sprintf(buf, "(%2d) %3d", 0, l->start);
- waddstr(w, buf);
- }
-
- for (int i = start_visit; i < l->n_visits; ++i) {
- wmove(w, offset+i-start_visit, 2);
- struct visit *v = l->visits + i;
-
- buflen += sprintf(buf, "(%2d) %3d %3d", i+1, v->points, v->rem);
-
- 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);
- }
-
- buflen = 0;
- waddstr(w, buf);
- }
-
- wrefresh(w);
+ wmove(statw, 0, 0);
+ wclrtoeol(statw);
+ waddstr(statw, status);
+ wrefresh(statw);
}
-void user_visit(WINDOW *w, struct leg *l)
+void user_visit(struct leg *l)
{
struct visit *v = l->visits + l->n_visits++;
char prompt[] = " Enter points: ";
- WINDOW *iw = subwin(w, 1, COLS-2, LINES-2, 1);
- wbkgd(iw, COLOR_PAIR(C_PROMPT));
- waddstr(iw, prompt);
- touchwin(w);
- wrefresh(iw);
+ curses_status(prompt);
char buf[100] = { 0 };
int buflen = 0;
int c;
- while((c = wgetch(iw)) != 10) {
+ while((c = wgetch(statw)) != 10) {
if (c == 127) {
if (buflen > 0) {
buf[--buflen] = 0;
- wmove(iw, 0, sizeof(prompt) - 1 + buflen);
- wclrtoeol(iw);
- touchwin(w);
- wrefresh(iw);
+ wmove(statw, 0, sizeof(prompt) - 1 + buflen);
+ wclrtoeol(statw);
+ wrefresh(statw);
}
- } else if (c >= (int)'0' && c <= (int)'9') {
+ } else if (c >= '0' && c <= '9') {
buf[buflen++] = c;
- wechochar(iw, c);
+ wechochar(statw, c);
}
}
- delwin(iw);
-
v->points = atoi(buf);
l->rem -= v->points;
v->rem = l->rem;
}
-void init_colours()
-{
- FOREACH_COLOUR(GEN_COLOUR_INIT_PAIR)
-}
-
int points_colour(int points)
{
if (points >= 180)
@@ -447,7 +413,7 @@ int points_colour(int points)
return COLOR_PAIR(C_0) | A_BOLD;
}
-void flushbuf(WINDOW *w, char *buf, int *buflen, int col)
+void flushbuf(char *buf, int *buflen, int col)
{
if (!(*buflen)) return;
@@ -458,40 +424,38 @@ void flushbuf(WINDOW *w, char *buf, int *buflen, int col)
*buflen = 0;
}
-void curses_draw(WINDOW *w, struct leg *l1, struct leg *l2)
+void curses_draw(struct leg *l1, struct leg *l2)
{
werase(w);
- box(w, 0, 0);
- wmove(w, 0, 2);
- waddstr(w, "dartbot");
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;
- int offset = 2;
- int start_visit = (LINES - 3 > n_visits) ? 0 : (n_visits - (LINES - 3));
- if (start_visit == 0 && LINES - 3 > n_visits) {
- wmove(w, (offset++)-start_visit, 2);
+ if (start_visit == 0 && wlines > n_visits) {
+ wmove(w, (offset++)-start_visit, 1);
buflen = sprintf(buf, "(%2d)", 0);
- flushbuf(w, buf, &buflen, COLOR_PAIR(C_VISIT));
+ flushbuf(buf, &buflen, COLOR_PAIR(C_VISIT));
buflen = sprintf(buf, " %3d %3d", l1->start, l2->start);
- flushbuf(w, buf, &buflen, 0);
+ flushbuf(buf, &buflen, 0);
}
for (int i = start_visit; i < n_visits; ++i) {
- wmove(w, offset+i-start_visit, 2);
+ wmove(w, offset+i-start_visit, 1);
buflen += sprintf(buf + buflen, "(%2d)", i+1);
- flushbuf(w, buf, &buflen, COLOR_PAIR(C_VISIT));
+ flushbuf(buf, &buflen, COLOR_PAIR(C_VISIT));
buflen += sprintf(buf + buflen, " ");
- flushbuf(w, buf, &buflen, 0);
+ flushbuf(buf, &buflen, 0);
struct visit *v = l1->visits + i;
- flushbuf(w, buf, &buflen, 0);
+ flushbuf(buf, &buflen, 0);
buflen += sprintf(buf + buflen, "%3d", v->points);
- flushbuf(w, buf, &buflen, points_colour(v->points));
+ flushbuf(buf, &buflen, points_colour(v->points));
buflen += sprintf(buf + buflen, " %3d", v->rem);
@@ -500,53 +464,65 @@ void curses_draw(WINDOW *w, struct leg *l1, struct leg *l2)
buflen += sprintf(buf + buflen, " %3d ", v->rem);
- flushbuf(w, buf, &buflen, 0);
+ flushbuf(buf, &buflen, 0);
buflen += sprintf(buf + buflen, "%3d", v->points);
- flushbuf(w, buf, &buflen, points_colour(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(w, buf, &buflen, COLOR_PAIR(C_DARTS));
+ flushbuf(buf, &buflen, COLOR_PAIR(C_DARTS));
}
- flushbuf(w, buf, &buflen, 0);
+ flushbuf(buf, &buflen, 0);
}
wrefresh(w);
}
-void curses_match(int start_points, void (*f1)(WINDOW *, struct leg *),
- void (*f2)(WINDOW *, struct leg *))
+void curses_match(int start_points, void (*f1)(struct leg *),
+ void (*f2)(struct leg *))
{
initscr();
+ border(0, 0, 0, 0, 0, 0, 0, 0);
+ move(0, 2);
+ addstr("dartbot");
+ refresh();
start_color();
init_colours();
curs_set(0);
noecho();
- WINDOW *w = newwin(LINES, COLS, 0, 0);
+ w = newwin(LINES-3, COLS-2, 1, 1);
+ statw = newwin(1, COLS-2, LINES-2, 1);
+ wbkgd(statw, COLOR_PAIR(C_PROMPT));
struct leg *l1 = leg_init(start_points);
struct leg *l2 = leg_init(start_points);
- curses_draw(w, l1, l2);
+ curses_draw(l1, l2);
while (l1->rem > 0 && l2->rem > 0) {
- (*f1)(w, l1);
- curses_draw(w, l1, l2);
+ (*f1)(l1);
+ curses_draw(l1, l2);
if (l1->rem > 0)
- (*f2)(w, l2);
+ (*f2)(l2);
- curses_draw(w, l1, l2);
+ curses_draw(l1, l2);
}
+ if (l1->rem <= 0)
+ curses_status("Player 1 wins.");
+ else if (l2->rem <= 0)
+ curses_status("Player 2 wins.");
+
leg_free(l1);
leg_free(l2);
wgetch(w);
+ delwin(statw);
delwin(w);
endwin();
}