summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--22.c108
1 files changed, 108 insertions, 0 deletions
diff --git a/22.c b/22.c
index 180969f..e877c5a 100644
--- a/22.c
+++ b/22.c
@@ -39,6 +39,114 @@ direction_name(enum direction dir)
}
+// For each face of a cuboid, list adjoining faces in anti-clockwise order
+//
+// The faces are numbered as a right-handed six-sided die labelled 0 to 5.
+// Opposite pairs add up to 5 (0/5, 1/4 and 2/3), and if you imagine curling the
+// fingers of your right hand from the 0 to the 1, the 2 is on the face that
+// your thumb is pointing to. e.g. if the 0 is on the front, and the 1 is on
+// top, the 2 is on the left side.
+//
+// When a face is "oriented" a certain way, then if that face is on top, the
+// first adjoining face listed in table below is in that direction.
+//
+// e.g. If the 3 face is on the top of the cuboid and "oriented" west, then the
+// 4 face is to its west, the 5 is to its south, the 1 is to its east, and the 0
+// is to its north.
+static int const faceids[6][4] = {
+ { 1, 2, 4, 3 }, // 0 sees 1, 2, 4, 3
+ { 0, 3, 5, 2 }, // 1 sees 0, 3, 5, 2
+ { 5, 4, 0, 1 }, // 2 sees 5, 4, 0, 1
+ { 4, 5, 1, 0 }, // 3 sees 4, 5, 1, 0
+ { 3, 0, 2, 5 }, // 4 sees 3, 0, 2, 5
+ { 2, 1, 3, 4 }, // 5 sees 2, 1, 3, 4
+};
+
+
+// Given an oriented top face, which face do we see in a given direction?
+int
+faceid_look(int topid, enum direction orient, enum direction look)
+{
+ static enum direction const dirs[] = { D_NORTH, D_WEST, D_SOUTH, D_EAST };
+ int topdir, destdir;
+
+ if (topid < 0 || topid >= 6)
+ return -1;
+
+ // Go through `dirs` until we find the one that topid is pointing to
+ for (topdir = 0; topdir < 4; ++topdir)
+ if (dirs[topdir % 4] == orient)
+ break;
+ if (topdir >= 4)
+ return -1;
+
+ // Keep going through `dirs` until we find the one that the caller wants
+ for (destdir = topdir; destdir < topdir + 4; ++destdir)
+ if (dirs[destdir % 4] == look)
+ break;
+ if (destdir >= topdir + 4)
+ return -1;
+
+ // Look up the destination face id.
+ return faceids[topid][destdir - topdir];
+}
+
+
+// Given an oriented top face, which direction do we look to see another face?
+enum direction
+faceid_find(int topid, enum direction orient, int destid)
+{
+ static enum direction const dirs[] = { D_NORTH, D_WEST, D_SOUTH, D_EAST };
+ int topdir, destix;
+
+ // Go through the directions until we find the one that fsrc is pointing
+ for (topdir = 0; topdir < 4; ++topdir)
+ if (dirs[topdir % 4] == orient)
+ break;
+ if (topdir >= 4)
+ return -1;
+
+ // Go through topid's faces until we find destid
+ for (destix = 0; destix < 4; ++destix)
+ if (faceids[topid][destix] == destid)
+ break;
+ if (destix >= 4)
+ return -1;
+
+ // Return the direction that dest should be in
+ return dirs[(topdir + destix) % 4];
+}
+
+
+// Given a top face, if we see another face in one direction, what is the
+// orientation of the top face?
+enum direction
+faceid_orientation(int topid, int destid, enum direction destdir)
+{
+ static enum direction const dirs[] = { D_NORTH, D_WEST, D_SOUTH, D_EAST };
+ int topdir, destix;
+
+ // Go through topid's faces until we find destid
+ for (destix = 0; destix < 4; ++destix)
+ if (faceids[topid][destix] == destid)
+ break;
+ if (destix >= 4)
+ return -1;
+
+ // From faceid_find(), if dirs[topdir + destix] points to destdir,
+ // then we just go through possible topdirs until we find the one
+ // that makes this true
+ for (topdir = 0; topdir < 4; ++topdir)
+ if (dirs[(topdir + destix) % 4] == destdir)
+ break;
+ if (topdir >= 4)
+ return -1;
+
+ // Return the direction that dest should be in
+ return dirs[topdir];
+}
+
+
struct map {
char * _buf;
int cols;