mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 16:05:44 -07:00
It occurred to me yesterday that Net could perfectly well be played
on paper, so here's a routine to print it out. [originally from svn r5826]
This commit is contained in:
114
print.py
114
print.py
@ -6,15 +6,15 @@
|
|||||||
# and how many you want per page.
|
# and how many you want per page.
|
||||||
|
|
||||||
# Supported games are those which are sensibly solvable using
|
# Supported games are those which are sensibly solvable using
|
||||||
# pencil and paper: Rectangles, Pattern and Solo.
|
# pencil and paper: Rectangles, Pattern, Solo, Net.
|
||||||
|
|
||||||
# Command-line syntax is
|
# Command-line syntax is
|
||||||
#
|
#
|
||||||
# print.py <game-name> <format>
|
# print.py <game-name> <format>
|
||||||
#
|
#
|
||||||
# <game-name> is one of `rect', `rectangles', `pattern', `solo'.
|
# <game-name> is one of `rect', `rectangles', `pattern', `solo',
|
||||||
# <format> is two numbers separated by an x: `2x3', for example,
|
# `net'. <format> is two numbers separated by an x: `2x3', for
|
||||||
# means two columns by three rows.
|
# example, means two columns by three rows.
|
||||||
#
|
#
|
||||||
# The program will then read game IDs from stdin until it sees EOF,
|
# The program will then read game IDs from stdin until it sees EOF,
|
||||||
# and generate as many PostScript pages on stdout as it needs.
|
# and generate as many PostScript pages on stdout as it needs.
|
||||||
@ -92,6 +92,111 @@ def rect_format(s):
|
|||||||
((x+0.5)*gridpitch, (h-y-0.5)*gridpitch, n))
|
((x+0.5)*gridpitch, (h-y-0.5)*gridpitch, n))
|
||||||
return ret.coords, ret.s
|
return ret.coords, ret.s
|
||||||
|
|
||||||
|
def net_format(s):
|
||||||
|
# Parse the game ID.
|
||||||
|
ret = Holder()
|
||||||
|
ret.s = ""
|
||||||
|
params, seed = string.split(s, ":")
|
||||||
|
wrapping = 0
|
||||||
|
if params[-1:] == "w":
|
||||||
|
wrapping = 1
|
||||||
|
params = params[:-1]
|
||||||
|
w, h = map(string.atoi, string.split(params, "x"))
|
||||||
|
grid = []
|
||||||
|
hbarriers = []
|
||||||
|
vbarriers = []
|
||||||
|
while len(seed) > 0:
|
||||||
|
n = string.atoi(seed[0], 16)
|
||||||
|
seed = seed[1:]
|
||||||
|
while len(seed) > 0 and seed[0] in 'hv':
|
||||||
|
x = len(grid) % w
|
||||||
|
y = len(grid) / w
|
||||||
|
if seed[0] == 'h':
|
||||||
|
hbarriers.append((x, y+1))
|
||||||
|
else:
|
||||||
|
vbarriers.append((x+1, y))
|
||||||
|
seed = seed[1:]
|
||||||
|
grid.append(n)
|
||||||
|
assert w * h == len(grid)
|
||||||
|
# I'm going to arbitrarily choose a 24pt grid pitch.
|
||||||
|
gridpitch = 24
|
||||||
|
scale = 0.25
|
||||||
|
bigoffset = 0.25
|
||||||
|
smalloffset = 0.17
|
||||||
|
# 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 the base 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")
|
||||||
|
# Draw round the grid exterior.
|
||||||
|
psprint(ret, "newpath")
|
||||||
|
if not wrapping:
|
||||||
|
psprint(ret, "2 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 any barriers.
|
||||||
|
psprint(ret, "newpath 2 setlinewidth 1 setlinecap")
|
||||||
|
for x, y in hbarriers:
|
||||||
|
psprint(ret, "%g %g moveto %g 0 rlineto" % \
|
||||||
|
(x * gridpitch, (h - y) * gridpitch, gridpitch))
|
||||||
|
for x, y in vbarriers:
|
||||||
|
psprint(ret, "%g %g moveto 0 -%g rlineto" % \
|
||||||
|
(x * gridpitch, (h - y) * gridpitch, gridpitch))
|
||||||
|
psprint(ret, "stroke")
|
||||||
|
# And draw the symbol in each box.
|
||||||
|
for i in xrange(len(grid)):
|
||||||
|
x = i % w
|
||||||
|
y = i / w
|
||||||
|
v = grid[i]
|
||||||
|
# Rotate to canonical form.
|
||||||
|
if v in (1,2,4,8):
|
||||||
|
v = 1
|
||||||
|
elif v in (5,10):
|
||||||
|
v = 5
|
||||||
|
elif v in (3,6,9,12):
|
||||||
|
v = 9
|
||||||
|
elif v in (7,11,13,14):
|
||||||
|
v = 13
|
||||||
|
# Centre on an area in the corner of the tile.
|
||||||
|
psprint(ret, "gsave")
|
||||||
|
if v & 4:
|
||||||
|
hoffset = bigoffset
|
||||||
|
else:
|
||||||
|
hoffset = smalloffset
|
||||||
|
if v & 2:
|
||||||
|
voffset = bigoffset
|
||||||
|
else:
|
||||||
|
voffset = smalloffset
|
||||||
|
psprint(ret, "%g %g translate" % \
|
||||||
|
((x + hoffset) * gridpitch, (h - y - voffset) * gridpitch))
|
||||||
|
psprint(ret, "%g dup scale" % (float(gridpitch) * scale / 2))
|
||||||
|
psprint(ret, "newpath 0.07 setlinewidth")
|
||||||
|
# Draw the radial lines.
|
||||||
|
for dx, dy, z in ((1,0,1), (0,1,2), (-1,0,4), (0,-1,8)):
|
||||||
|
if v & z:
|
||||||
|
psprint(ret, "0 0 moveto %d %d lineto" % (dx, dy))
|
||||||
|
psprint(ret, "stroke")
|
||||||
|
# Draw additional figures if desired.
|
||||||
|
if v == 13:
|
||||||
|
# T-pieces have a little circular blob where the lines join.
|
||||||
|
psprint(ret, "newpath 0 0 0.15 0 360 arc fill")
|
||||||
|
elif v == 1:
|
||||||
|
# Endpoints have a little empty square at the centre.
|
||||||
|
psprint(ret, "newpath 0.35 0.35 moveto 0 -0.7 rlineto")
|
||||||
|
psprint(ret, "-0.7 0 rlineto 0 0.7 rlineto closepath")
|
||||||
|
psprint(ret, "gsave 1 setgray fill grestore stroke")
|
||||||
|
# Clean up.
|
||||||
|
psprint(ret, "grestore")
|
||||||
|
return ret.coords, ret.s
|
||||||
|
|
||||||
def pattern_format(s):
|
def pattern_format(s):
|
||||||
ret = Holder()
|
ret = Holder()
|
||||||
ret.s = ""
|
ret.s = ""
|
||||||
@ -219,6 +324,7 @@ def solo_format(s):
|
|||||||
return ret.coords, ret.s
|
return ret.coords, ret.s
|
||||||
|
|
||||||
formatters = {
|
formatters = {
|
||||||
|
"net": net_format,
|
||||||
"rect": rect_format,
|
"rect": rect_format,
|
||||||
"rectangles": rect_format,
|
"rectangles": rect_format,
|
||||||
"pattern": pattern_format,
|
"pattern": pattern_format,
|
||||||
|
Reference in New Issue
Block a user