New puzzle: `Light Up', by James H.
[sgt/puzzles] / print.py
index 92c9875..13b4263 100755 (executable)
--- a/print.py
+++ b/print.py
@@ -13,8 +13,8 @@
 #     print.py <game-name> <format>
 #
 # <game-name> is one of `rect', `rectangles', `pattern', `solo',
-# `net'. <format> is two numbers separated by an x: `2x3', for
-# example, means two columns by three rows.
+# `net', `dominosa'. <format> is two numbers separated by an x:
+# `2x3', for example, means two columns by three rows.
 #
 # The program will then read game IDs from stdin until it sees EOF,
 # and generate as many PostScript pages on stdout as it needs.
@@ -333,12 +333,154 @@ def solo_format(s):
                ((x+0.5)*gridpitch, (cr-y-0.5)*gridpitch, s))
     return ret.coords, ret.s
 
+def dominosa_format(s):
+    ret = Holder()
+    ret.s = ""
+    params, seed = string.split(s, ":")
+    n = string.atoi(params)
+    w = n+2
+    h = n+1
+    grid = []
+    while len(seed) > 0:
+        if seed[0] == '[': # XXX
+            d, seed = string.split(seed[1:], "]")
+            grid.append(string.atoi(d))
+        else:
+            assert seed[0] in string.digits
+            grid.append(string.atoi(seed[0:1]))
+            seed = seed[1:]
+    assert w*h == len(grid)
+    # I'm going to arbitrarily choose to use 9pt text for the
+    # numbers, and a 16pt grid pitch.
+    textht = 9
+    gridpitch = 16
+    pw = gridpitch * w
+    ph = gridpitch * h
+    psprint(ret, "/Helvetica findfont %g scalefont setfont" % textht)
+    ret.coords = (pw/2, pw/2, ph/2, ph/2)
+    psprint(ret, "%g %g translate" % (-ret.coords[0], -ret.coords[2]))
+    for y in xrange(h):
+        for x in xrange(w):
+            psprint(ret, "%g %g (%d) ctshow" % \
+                ((x+0.5)*gridpitch, (h-y-0.5)*gridpitch, grid[y*w+x]))
+    return ret.coords, ret.s
+
+def slant_format(s):
+    # Parse the game ID.
+    ret = Holder()
+    ret.s = ""
+    params, seed = string.split(s, ":")
+    w, h = map(string.atoi, string.split(params, "x"))
+    W = w+1
+    H = h+1
+    grid = []
+    while len(seed) > 0:
+       if seed[0] in string.lowercase:
+           grid.extend([-1] * (ord(seed[0]) - ord('a') + 1))
+           seed = seed[1:]
+       elif seed[0] in "01234":
+           grid.append(string.atoi(seed[0]))
+           seed = seed[1:]
+    assert W * H == len(grid)
+    # I'm going to arbitrarily choose to use 7pt text for the
+    # numbers, and a 14pt grid pitch.
+    textht = 7
+    gridpitch = 14
+    radius = textht * 2.0 / 3.0
+    # Set up coordinate system.
+    pw = gridpitch * w
+    ph = gridpitch * h
+    ret.coords = (pw/2, pw/2, ph/2, ph/2)
+    psprint(ret, "%g %g translate" % (-ret.coords[0], -ret.coords[2]))
+    # Draw round the grid exterior, thickly.
+    psprint(ret, "newpath 1 setlinewidth")
+    psprint(ret, "0 0 moveto 0 %g rlineto %g 0 rlineto 0 %g rlineto" % \
+    (h * gridpitch, w * gridpitch, -h * gridpitch))
+    psprint(ret, "closepath stroke")
+    # Draw the internal grid lines, _very_ thin (the player will
+    # need to draw over them visibly).
+    psprint(ret, "newpath 0.01 setlinewidth")
+    for x in xrange(1,w):
+       psprint(ret, "%g 0 moveto 0 %g rlineto" % (x * gridpitch, h * gridpitch))
+    for y in xrange(1,h):
+       psprint(ret, "0 %g moveto %g 0 rlineto" % (y * gridpitch, w * gridpitch))
+    psprint(ret, "stroke")
+    # And draw the numbers.
+    psprint(ret, "/Helvetica findfont %g scalefont setfont" % textht)
+    for y in xrange(H):
+       for x in xrange(W):
+           n = grid[y*W+x]
+           if n >= 0:
+               psprint(ret, "newpath %g %g %g 0 360 arc" % \
+               ((x)*gridpitch, (h-y)*gridpitch, radius),
+               "gsave 1 setgray fill grestore stroke")
+               psprint(ret, "%g %g (%d) ctshow" % \
+               ((x)*gridpitch, (h-y)*gridpitch, n))
+    return ret.coords, ret.s
+
+def lightup_format(s):
+    # Parse the game ID.
+    ret = Holder()
+    ret.s = ""
+    params, seed = string.split(s, ":")
+    w, h = map(string.atoi, string.split(params, "x"))
+    grid = []
+    while len(seed) > 0:
+       if seed[0] in string.lowercase:
+           grid.extend([-2] * (ord(seed[0]) - ord('a') + 1))
+           seed = seed[1:]
+       elif seed[0] == "B":
+           grid.append(-1)
+           seed = seed[1:]
+       elif seed[0] in "01234":
+           grid.append(string.atoi(seed[0]))
+           seed = seed[1:]
+    assert w * h == len(grid)
+    # I'm going to arbitrarily choose to use 9pt text for the
+    # numbers, and a 14pt grid pitch.
+    textht = 10
+    gridpitch = 14
+    # Set up coordinate system.
+    pw = gridpitch * w
+    ph = gridpitch * h
+    ret.coords = (pw/2, pw/2, ph/2, ph/2)
+    psprint(ret, "%g %g translate" % (-ret.coords[0], -ret.coords[2]))
+    # Draw round the grid exterior, thickly.
+    psprint(ret, "newpath 1 setlinewidth")
+    psprint(ret, "0 0 moveto 0 %g rlineto %g 0 rlineto 0 %g rlineto" % \
+    (h * gridpitch, w * gridpitch, -h * gridpitch))
+    psprint(ret, "closepath stroke")
+    # Draw the internal grid lines.
+    psprint(ret, "newpath 0.02 setlinewidth")
+    for x in xrange(1,w):
+       psprint(ret, "%g 0 moveto 0 %g rlineto" % (x * gridpitch, h * gridpitch))
+    for y in xrange(1,h):
+       psprint(ret, "0 %g moveto %g 0 rlineto" % (y * gridpitch, w * gridpitch))
+    psprint(ret, "stroke")
+    # And draw the black squares and numbers.
+    psprint(ret, "/Helvetica-Bold findfont %g scalefont setfont" % textht)
+    for y in xrange(h):
+       for x in xrange(w):
+           n = grid[y*w+x]
+           if n >= -1:
+               psprint(ret, ("newpath %g %g moveto 0 %g rlineto " +
+               "%g 0 rlineto 0 %g rlineto closepath fill") % \
+               ((x)*gridpitch, (h-1-y)*gridpitch, gridpitch, gridpitch, \
+               -gridpitch))
+               if n >= 0:
+                   psprint(ret, "gsave 1 setgray %g %g (%d) ctshow grestore" % \
+                   ((x+0.5)*gridpitch, (h-y-0.5)*gridpitch, n))
+    return ret.coords, ret.s
+
 formatters = {
 "net": net_format,
 "rect": rect_format,
 "rectangles": rect_format,
 "pattern": pattern_format,
-"solo": solo_format
+"solo": solo_format,
+"dominosa": dominosa_format,
+"slant": slant_format,
+"lightup": lightup_format
 }
 
 if len(sys.argv) < 3: