summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Spragg <adam@spra.gg>2023-01-02 12:51:32 +0000
committerAdam Spragg <adam@spra.gg>2023-01-02 12:51:32 +0000
commit103129a8c766dd213f90b7c23a7550005c3c20d3 (patch)
tree53da50abc03ebb31de09f1ebd85f5e85f87a48a7
parent6b2cac18fd1c8cba3149f42c2c458ea1e05c6fb4 (diff)
Puzzle 22: Add ability to select "net" map type
It doesn't work yet...
-rw-r--r--22.c71
1 files changed, 65 insertions, 6 deletions
diff --git a/22.c b/22.c
index bcde74a..cd4a15d 100644
--- a/22.c
+++ b/22.c
@@ -5,12 +5,19 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
// Proper modulo operator
#define modulo(n, m) ((((n) % (m)) + (m)) % (m))
+enum map_type {
+ M_FLAT,
+ M_NET,
+};
+
+
enum direction {
D_NORTH = 3,
D_EAST = 0,
@@ -76,7 +83,7 @@ elf_turn(struct elf * elf, char turn)
int
-elf_move(struct elf * elf, char const * map, int cols, int rows, int distance)
+elf_move(struct elf * elf, char const * map, int cols, int rows, enum map_type mtype, int distance)
{
while (distance > 0) {
int skip, wrap, base, newpos;
@@ -111,8 +118,23 @@ elf_move(struct elf * elf, char const * map, int cols, int rows, int distance)
newpos = base + modulo(elf->pos + skip, wrap);
- while (map[newpos] == ' ' || map[newpos] == '\n')
- newpos = base + modulo(newpos + skip, wrap);
+ if (map[newpos] == ' ' || map[newpos] == '\n') {
+ switch (mtype) {
+ case M_FLAT:
+ // Just keep going until we wrap around to a non-blank position
+ while (map[newpos] == ' ' || map[newpos] == '\n')
+ newpos = base + modulo(newpos + skip, wrap);
+ break;
+
+ case M_NET:
+ fprintf(stderr, "Map type not yet supported!\n");
+ return -1;
+
+ default:
+ fprintf(stderr, "Unknown map type %d\n", mtype);
+ return -1;
+ }
+ }
switch (map[newpos]) {
case '.':
@@ -135,15 +157,52 @@ elf_move(struct elf * elf, char const * map, int cols, int rows, int distance)
int
-main()
+main(int argc, char ** argv)
{
char * buf = NULL, * beg, * end;
+ enum map_type mtype = M_FLAT;
long bufsiz = 0, buflen = 0, maxline = 0, lines = 0;
long pos;
struct elf elf;
char distance[8], c;
int dlen = 0;
+ while ((pos = getopt(argc, argv, "p:m:")) != -1) {
+ switch (pos) {
+ case 'p':
+ switch (atoi(optarg)) {
+ case 1:
+ mtype = M_FLAT;
+ break;
+
+ case 2:
+ mtype = M_NET;
+ break;
+
+ default:
+ fprintf(stderr, "Unexpected puzzle part %s\n", optarg);
+ return -1;
+ }
+ break;
+
+ case 'm':
+ if (strcmp(optarg, "flat") == 0) {
+ mtype = M_FLAT;
+ }
+ else if (strcmp(optarg, "net") == 0) {
+ mtype = M_NET;
+ }
+ else {
+ fprintf(stderr, "Unexpected map type %s\n", optarg);
+ return -1;
+ }
+ break;
+
+ default:
+ return -1;
+ }
+ }
+
// Read map data
// Don't try and figure out lines yet, in case we get a line longer than
// our read buffer, which could make things awkward.
@@ -215,7 +274,7 @@ main()
else if (c == 'L' || c == 'R') {
distance[dlen] = '\0';
- if (elf_move(&elf, buf, maxline, lines, atoi(distance)) != 0)
+ if (elf_move(&elf, buf, maxline, lines, mtype, atoi(distance)) != 0)
elf.pos = -1;
if (elf_turn(&elf, c) != 0)
elf.pos = -1;
@@ -225,7 +284,7 @@ main()
else if (c == '\n') {
// Cover last bit of distance, if any
distance[dlen] = '\0';
- if (elf_move(&elf, buf, maxline, lines, atoi(distance)) != 0)
+ if (elf_move(&elf, buf, maxline, lines, mtype, atoi(distance)) != 0)
elf.pos = -1;
break;
}