From 103129a8c766dd213f90b7c23a7550005c3c20d3 Mon Sep 17 00:00:00 2001
From: Adam Spragg <adam@spra.gg>
Date: Mon, 2 Jan 2023 12:51:32 +0000
Subject: Puzzle 22: Add ability to select "net" map type

It doesn't work yet...
---
 22.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 file 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;
 		}
-- 
cgit v1.2.1