chiark / gitweb /
Automate creation of Bedbugs.rule
authorJacob Nevins <0jacobnk.git@chiark.greenend.org.uk>
Sat, 18 Jan 2014 16:23:17 +0000 (16:23 +0000)
committerJacob Nevins <0jacobnk.git@chiark.greenend.org.uk>
Sat, 18 Jan 2014 16:23:17 +0000 (16:23 +0000)
All the manual hackery is now automated, but the result is equivalent.
Still quite shonky.

Bedbugs.rule
src/.gitignore
src/Bedbugs.rule.template [new file with mode: 0644]
src/Makefile
src/bedbugs.c
src/mungetable.pl

index fdcb9b4..7c2c381 100644 (file)
@@ -9,7 +9,6 @@ neighborhood:Moore
 symmetries:none
 # Bedsteadisation rules generated by bedbugs.c
 # FIXME: vars to allow edit in off states?
-# 1st one hacked
 0,0,0,0,0,0,0,0,0,0
 0,0,0,0,0,0,0,0,1,2
 0,1,0,0,0,0,0,0,0,2
@@ -523,8 +522,15 @@ symmetries:none
 1,1,1,1,1,1,1,1,0,33
 1,1,1,1,1,1,1,1,1,33
 # Conway rules (autogenerated)
-#zz,qn,qne,qe,qse,qs,qsw,qw,qnw,0
-#aa,qn,qne,qe,qse,qs,qsw,qw,qnw,1
+# rules: 190
+#
+# Golly rule-table format.
+# Each rule: C,N,NE,E,SE,S,SW,W,NW,C'
+# N.B. Where the same variable appears multiple times in a transition,
+# it takes the same value each time.
+#
+# All transitions should be included below, including no-change ones.
+#
 var zz={0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}
 var aa={18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33}
 var zc={zz}
index 0afa5f6..731092d 100644 (file)
@@ -2,4 +2,3 @@ bedbugs
 make-ruletable
 life.table
 mungedlife.table
-bedbugs.rule
diff --git a/src/Bedbugs.rule.template b/src/Bedbugs.rule.template
new file mode 100644 (file)
index 0000000..12b4811
--- /dev/null
@@ -0,0 +1,20 @@
+@RULE Bedbugs
+Bedbugs: standard Conway life with complication to use Bedstead rendering
+Alternates between Conway propagation and Bedsteadisation
+2 states for Conway -> 32 states (16x2) for Bedstead -> 2 etc.
+
+@TABLE
+n_states:34
+neighborhood:Moore
+symmetries:none
+# Bedsteadisation rules generated by bedbugs.c
+# FIXME: vars to allow edit in off states?
+@@BEDSTEAD
+# Conway rules (autogenerated)
+@@mungedlife.table
+
+@COLORS
+255 255 255  255 255 255  white to white
+
+@ICONS
+@@ICONS
index 8c41a02..fc8c0a0 100644 (file)
@@ -1,12 +1,12 @@
-all: bedbugs.rule mungedlife.table
+../Bedbugs.rule: bedbugs mungedlife.table
+       ./bedbugs <Bedbugs.rule.template >../Bedbugs.rule
 
 clean:
-       rm bedbugs bedbugs.rule make-ruletable life.table mungedlife.table
+       rm -f bedbugs make-ruletable life.table mungedlife.table
+reallyquiteclean: clean
+       rm -f ../Bedbugs.rule
 .PHONY: clean
 
-bedbugs.rule: bedbugs
-       ./bedbugs >bedbugs.rule
-
 mungedlife.table: life.table mungetable.pl
        perl mungetable.pl <life.table >mungedlife.table
 
index f703ad6..05d22ba 100644 (file)
  * [...]
  */
 
+#include <assert.h>
+#include <errno.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -208,16 +210,12 @@ blackpixel(bool *r, int size, int bl, int br, int tr, int tl)
     }
 }
 
-int main(int argc, char *argv[])
+void bedstead (void)
 {
-
-        /* FIXME: output a complete rule file rather than a heap of
-         * fragments requiring manual assembly */
-
-        /* Bedbugs step 1: output smoothing rules as a Golly rule
-         * table mapping from (0,1) to an expanded set of states that
-         * we can hang icons from. (The smoothing algorithm requires
-         * a 3x3 neighbourhood, which is fortuitous.) */
+        /* Output smoothing rules as a Golly rule table mapping from
+         * (0,1) to an expanded set of states that we can hang icons
+         * from. (The smoothing algorithm requires a 3x3 neighbourhood,
+         * which is fortuitous.) */
 
         /* Index into small bitmap */
 #define GETPIX(x,y) (!!(iter & 1u<<((y)*3+(x))))
@@ -266,15 +264,26 @@ int main(int argc, char *argv[])
                                 /* Off states are 2..17 */
                                 state = 2 + (bl | br<<1 | tr<<2 | tl<<3);
                        }
+                        if (iter == 0) {
+                                /* Special case: we don't want to try to
+                                 * flip all of infinite empty space between
+                                 * 0 and 2 every step (this has odd effects
+                                 * on Golly) */
+                                assert(state == 2);
+                                state = 0;
+                        }
                         /* Output rule in Golly rule format
                          * (FIXME completely unoptimised) */
                         printf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
                                GETPIX(x,y),U,UR,R,DR,D,DL,L,UL,state);
         }
+}
 
-        /* Bedbugs step 2: icons. In each size supported by Golly,
+void icons(void)
+{
+        /* Bedbugs icons. In each size supported by Golly,
          * draw one icon per state, in the XPM format Golly wants.
-         * This does not actually depend on step 1 at all.
+         * This does not actually depend on bedstead() at all.
          * (FIXME: but it could. Some of the states we generate icons
          * and rules for are not actually reachable. We could spot
          * unused states above and avoid generating icons or rules for
@@ -313,5 +322,50 @@ int main(int argc, char *argv[])
                 }
             }
         }
-        return 0;
+}
+
+int main(int argc, char *argv[])
+{
+    while (!feof(stdin)) {
+        char l[100]; /* bleah */
+        if (!fgets(l, sizeof(l), stdin)) {
+            break;
+        }
+        if (strlen(l) == sizeof(l)-1) {
+            fprintf(stderr, "Long input line; possible truncation; I suck\n");
+            exit(1);
+        }
+        if (strlen(l) >= 2 && l[0] == '@' && l[1] == '@') {
+            size_t n = strcspn(l+2, "\n");
+            if (strncmp(l+2, "BEDSTEAD", n) == 0) {
+                bedstead();
+            } else if (strncmp(l+2, "ICONS", n) == 0) {
+                icons();
+            } else {
+                /* Bodily insert named file on stdout. */
+                FILE *f;
+                l[n+2]='\0';
+                if (!(f = fopen(l+2, "r"))) {
+                    fprintf(stderr, "Couldn't open '%s': %s\n", l+2,
+                            strerror(errno));
+                    exit(1);
+                } else {
+                    do {
+                        char buf[2048]; /* also bleah */
+                        size_t n = fread(buf, 1, sizeof(buf), f);
+                        fwrite(buf, 1, n, stdout);
+                    } while (!feof(f) && !ferror(f));
+                    if (ferror(f)) {
+                        fprintf(stderr, "Error reading '%s': %s\n", l+2,
+                                strerror(errno));
+                        exit(1);
+                    }
+                    fclose(f);
+                }
+            }
+        } else {
+            printf("%s", l);
+        }
+    }
+    return 0;
 }
index 369d861..d6eef08 100755 (executable)
@@ -33,7 +33,8 @@ while(<>) {
     if (m/^#/) {
         print $_;
     } elsif (m/^(n_states|neighborhood|symmetries):/) {
-        print $_;
+        # Suppress -- assume matching ones will be provided elsewhere
+        ;
     } elsif (m/^var /) {
         die "Complicated variable" unless m/^var (.)=\{0,1\}$/;
         $vars{$1} = 1;