summaryrefslogtreecommitdiff
path: root/22.c
diff options
context:
space:
mode:
Diffstat (limited to '22.c')
-rw-r--r--22.c82
1 files changed, 77 insertions, 5 deletions
diff --git a/22.c b/22.c
index af654c7..10d202f 100644
--- a/22.c
+++ b/22.c
@@ -470,8 +470,6 @@ map_init(struct map * map, char * buf, size_t buflen, enum map_type type)
free(map->_buf);
return NULL;
}
-
- fprintf(stderr, "Faces initialised\n");
}
return map;
@@ -695,8 +693,9 @@ int
elf_move(struct elf * elf, struct map const * map, int distance)
{
while (distance > 0) {
- int dx = 0, dy = 0, elem;
+ int dx = 0, dy = 0, elem, fsrcid, fdestid;
struct elf newelf;
+ struct face const * fsrc, * fdest;
switch (elf->dir) {
case D_NORTH: dy = +1; break;
@@ -724,8 +723,81 @@ elf_move(struct elf * elf, struct map const * map, int distance)
break;
case M_NET:
- fprintf(stderr, "Map type not yet supported!\n");
- return -1;
+ // Find the face at the elf's current position
+ if ((fsrc = map_face_at(map, elf->x, elf->y)) == NULL) {
+ fprintf(stderr, "No face at %d,%d\n", elf->x, elf->y);
+ return -1;
+ }
+ fsrcid = fsrc - map->faces;
+
+ // And the face after one more step.
+ if ((fdest = map_face_at(map, elf->x + dx, elf->y + dy)) == NULL) {
+ int offset, approach;
+
+ // Find the face that should be next to the
+ // current one, in the direction the elf is
+ // travelling.
+ if ((fdestid = faceid_look(fsrcid, fsrc->dir, elf->dir)) == -1) {
+ fprintf(stderr, "No face from %d in dir %d\n",
+ fsrcid, elf->dir);
+ return -1;
+ }
+ fdest = map->faces + fdestid;
+
+ // Find the offset along the face edge we're leaving from
+ switch (elf->dir) {
+ case D_NORTH: offset = fsrc->vertices[2].x - 1 - elf->x; break;
+ case D_SOUTH: offset = elf->x - fsrc->vertices[0].x; break;
+ case D_EAST: offset = elf->y - fsrc->vertices[1].y; break;
+ case D_WEST: offset = fsrc->vertices[3].y - 1 - elf->y; break;
+ }
+
+ // Find the direction we should need to go from
+ // `dest` to the face we're coming from
+ approach = faceid_find(fdestid, fdest->dir, fsrcid);
+
+ // Whatever that direction is, we're arriving
+ // the other way. e.g. if we're travelling from
+ // face 0 to face 1, and face 0 is supposed to
+ // be south of face 1, then we're travelling
+ // north as we arrive on face 1.
+ switch (approach) {
+ case D_NORTH: // Approaching from the north, heading south, crossing edge 2->3
+ newelf.x = fdest->vertices[3].x + offset;
+ newelf.y = fdest->vertices[3].y - 1;
+ newelf.dir = D_SOUTH;
+ break;
+
+ case D_SOUTH: // Approaching from the south, heading north, crossing edge 0->1
+ newelf.x = fdest->vertices[1].x - 1 - offset;
+ newelf.y = fdest->vertices[1].y;
+ newelf.dir = D_NORTH;
+ break;
+
+ case D_EAST: // Approaching from the east, heading west, crossing edge 1->2
+ newelf.x = fdest->vertices[2].x - 1;
+ newelf.y = fdest->vertices[2].y - 1 - offset;
+ newelf.dir = D_WEST;
+ break;
+
+ case D_WEST: // Approaching from the west, heading east, crossing edge 3->0
+ newelf.x = fdest->vertices[0].x;
+ newelf.y = fdest->vertices[0].y + offset;
+ newelf.dir = D_EAST;
+ break;
+
+ default:
+ fprintf(stderr, "Unable to get from here to there.\n");
+ return -1;
+ }
+ }
+ else {
+ newelf.x = elf->x + dx;
+ newelf.y = elf->y + dy;
+ newelf.dir = elf->dir;
+ }
+ elem = map_elem(map, newelf.x, newelf.y);
+ break;
default:
fprintf(stderr, "Unknown map type %d\n", map->type);