shithub: puzzles

Download patch

ref: e2c84a5fd2b1ca6d3d8be0279466079b35b6c189
parent: 6920d97c0977a77be869ecfa1ae933eaaf131e90
author: Simon Tatham <anakin@pobox.com>
date: Sat Mar 30 16:04:10 EDT 2013

Introduce a mechanism in this source tree for building the container
web pages for the Java applets. Previously, those have all been
maintained by hand in my website's svn area, which is a bit silly. Now
we have a file per puzzle in the 'html' subdirectory which contains
the puzzle's name, one or two attributes, and the instructions snippet
to go below the puzzle applet; and then there's a Perl script that
builds all the real web pages out of that by adding in the parts
common across all files: the header, footer, and middle fragment with
the <applet> tag and resizing bits and pieces.

One piece _not_ checked in here is the footer text specific to my
hosting at chiark, which I think does still belong in the www area. So
Buildscr doesn't actually build the web pages; it just delivers the
bits and pieces by which my nightly snapshot script will be able to
run the program that _does_ build them, passing that footer as an
extra argument.

[originally from svn r9780]

--- a/Buildscr
+++ b/Buildscr
@@ -132,6 +132,8 @@
 deliver puzzles/puzzles.zip $@
 deliver puzzles/Output/setup.exe puzzles-r$(revision)-installer.exe
 deliver puzzles/*.jar java/$@
+deliver puzzles/html/*.html html/$@
+deliver puzzles/html/*.pl html/$@
 
 # deliver puzzles/puzzles.armv4.cab $@ # (not built at the moment)
 
--- a/CHECKLST.txt
+++ b/CHECKLST.txt
@@ -41,6 +41,9 @@
 Add the new Unix binary name, and the names of any auxiliary solver
 binaries, to the svn:ignore property.
 
+Write an instructions fragment for the webified puzzle pages, as
+html/<puzzlename>.html .
+
 Make a screenshot:
  - create an appropriate save file in `icons'
  - add the puzzle name to icons/Makefile
@@ -49,20 +52,20 @@
  - set up a CROP property in icons/Makefile if the icon wants to be
    a sub-rectangle of the whole screenshot
 
-Don't forget to `svn add' the new source file, the new .R file and
-the save file in `icons', and any other new files that might have
-been involved.
+Don't forget to `svn add' the new source file, the new .R file and the
+save file in `icons', the new .html file, and any other new files that
+might have been involved.
 
 Check in!
 
 Put the puzzle on the web:
  - run puzzlesnap first
- - make sure the screenshot and Windows binary have arrived in the
-   www directory, and the .jar file in the java subdirectory
+ - make sure the screenshot and Windows binary have arrived in the www
+   directory, and that the .jar file and its accompanying web page has
+   arrived in the java subdirectory
  - add an entry in the puzzles list in index.html
  - add the Windows executable name to the list further down
    index.html
- - add a web page in the java subdirectory
  - adjust the copyright in index.html if the puzzle is by a new
    author
  - test that the binary link and the docs link work
@@ -69,5 +72,4 @@
  - test that the Java version works
  - run webupdate
  - test again
- - `svn add' the new Java applet web page
- - check in the change to index.html and the new web page
+ - check in the change to index.html
--- /dev/null
+++ b/html/blackbox.html
@@ -1,0 +1,16 @@
+Black Box
+<p>
+Determine where the hidden balls are in the box, by observing the
+behaviour of light beams fired into the box from the sides.
+<p>
+Click in a square around the edge of the box to send a beam into the
+box. Possible results are 'H' (the beam hit a ball dead-on and
+stopped), 'R' (the beam was either reflected back the way it came or
+there was a ball just to one side of its entry point) or a number
+appearing in two squares (indicating that the beam entered one of
+those squares and emerged from the other).
+<p>
+Click in the middle of the box to place your guessed ball positions.
+When you have placed enough, a green button will appear in the top
+left; click that to indicate that you think you have the answer.
+You can also right-click to mark squares as definitely known.
--- /dev/null
+++ b/html/bridges.html
@@ -1,0 +1,13 @@
+Bridges
+<p>
+Draw horizontal or vertical bridges to link up all the islands.
+Bridges may be single or double; they may not cross; the islands
+must all end up connected to each other; the number in each island
+must match the number of bridges that end at that island (counting
+double bridges as two). Note that loops of bridges are permitted.
+<p>
+Click on an island and drag left, right, up or down to draw a bridge
+to the next island in that direction. Do the same again to create a
+double bridge, and again to remove the bridge if you change your
+mind. Click on an island without dragging to mark the island as
+completed once you think you have placed all its bridges.
--- /dev/null
+++ b/html/cube.html
@@ -1,0 +1,14 @@
+Cube
+<p>
+Roll the cube around the grid, picking up the blue squares on its
+faces. Try to get all the blue squares on to the object at the same
+time, in as few moves as possible.
+<p>
+Use the arrow keys to roll the cube, or click the mouse where you
+want it to roll towards. After every roll, the grid square and cube
+face that you brought into contact swap their colours, so that a
+non-blue cube face can pick up a blue square, but a blue face rolled
+on to a non-blue square puts it down again.
+<p>
+When you have mastered the cube, use the Type menu to select other
+regular solids!
--- /dev/null
+++ b/html/dominosa.html
@@ -1,0 +1,10 @@
+Dominosa
+<p>
+Tile the rectangle with dominoes (1&times;2 rectangles) so that
+every possible domino appears exactly once (that is, every possible
+pair of numbers, including doubles).
+<p>
+Click between two adjacent numbers to place or remove a domino.
+Right-click to place a line between numbers if you think a domino
+definitely cannot go there. Dominoes light up red if two identical
+ones appear on the grid.
--- /dev/null
+++ b/html/fifteen.html
@@ -1,0 +1,6 @@
+Fifteen
+<p>
+Slide the tiles around the box until they appear in numerical order
+from the top left, with the hole in the bottom right corner.
+<p>
+Click on a tile to slide it towards the hole.
--- /dev/null
+++ b/html/filling.html
@@ -1,0 +1,12 @@
+Filling
+<p>
+Write a number in every blank square of the grid. When the grid is
+full, every orthogonally connected group of identical numbers should
+have an area equal to that number: so 1s always appear alone, 2s in
+pairs, and so on.
+<p>
+To place a number, click the mouse in a blank square to select it,
+then type the number you want on the keyboard. You can also drag to
+select multiple squares, and then type a number to place it in all
+of them. To erase numbers, select one or more squares in the same
+way and then press Backspace.
--- /dev/null
+++ b/html/flip.html
@@ -1,0 +1,10 @@
+Flip
+<p>
+Try to light up all the squares in the grid by flipping combinations
+of them.
+<p>
+Click in a square to flip it and some of its neighbours. The diagram
+in each square indicates which other squares will flip.
+<p>
+Select one of the 'Random' settings from the Type menu for more
+varied puzzles.
--- /dev/null
+++ b/html/galaxies.html
@@ -1,0 +1,11 @@
+Galaxies
+<p>
+Draw lines along grid edges so as to divide the grid up into
+regions. Every region should have two-way rotational symmetry, and
+should contain exactly one dot which is in its centre.
+<p>
+Click on a grid edge to add or remove a line. Right-click on a dot
+and drag the mouse to place an arrow in a grid square pointing to
+that dot, to indicate that you think that square must belong in the
+same region as that dot. Right-drag an existing arrow to move it, or
+drop it off the edge of the grid to remove it.
--- /dev/null
+++ b/html/group.html
@@ -1,0 +1,52 @@
+unfinished:Group
+<p>
+Fill in the grid with the letters shown to the top and left of it, so
+that the full grid is a valid
+<a href="http://en.wikipedia.org/wiki/Cayley_table">Cayley table</a>
+for a
+<a href="http://en.wikipedia.org/wiki/Group_(mathematics)">group</a>.
+<p>
+If you don't already know what a group is, I don't really recommend
+trying to play this game. But if you want to try anyway, the above is
+equivalent to saying that the following conditions must be satisfied:
+<ul>
+<li>
+<strong>Latin square</strong>. Every row and column must contain
+exactly one of each letter.
+<li>
+<strong>Identity</strong>. There must be some letter <i>e</i> such
+that, for all <i>a</i>, the letter in row <i>e</i> column <i>a</i> and
+the one in row <i>a</i> column <i>e</i> are both <i>a</i>. In the
+default mode, this letter is always <i>e</i> and its row and column
+are filled in for you; by reconfiguring the game using the Type menu,
+you can select a mode in which you have to work out which letter is
+the identity.
+<li>
+<strong>Inverses</strong>. For every letter <i>a</i>, there must be
+some letter <i>b</i> (which may sometimes be the same letter
+as <i>a</i>) such that the letters in row <i>a</i> column <i>b</i> and
+in row <i>b</i> column <i>a</i> are both the identity letter (as
+defined above).
+<li>
+<strong>Associativity</strong>. For every combination of
+letters <i>a</i>, <i>b</i>, and <i>c</i>, denote the letter in
+row <i>a</i> column <i>b</i> by <i>d</i>, and the one in row <i>b</i>
+column <i>c</i> by <i>e</i>. Then the letters in row <i>d</i>
+column <i>c</i> and in row <i>a</i> column <i>e</i> must be the same.
+</ul>
+<p>
+To place a letter, click in a square to select it, then type the
+letter on the keyboard. To erase a letter, click to select a square
+and then press Backspace.
+<p>
+Right-click in a square and then type a letter to add or remove the
+number as a pencil mark, indicating letters that you think
+<em>might</em> go in that square.
+<p>
+You can rearrange the order of elements in the rows and columns by
+dragging the column or row headings back and forth. (The rows and
+columns will stay in sync with each other.) Also,
+left-clicking <em>between</em> two row or column headings will add or
+remove a thick line between those two rows and the corresponding pair
+of columns (which is useful if you're considering a subgroup and its
+cosets).
--- /dev/null
+++ b/html/guess.html
@@ -1,0 +1,12 @@
+Guess
+<p>
+Try to guess the hidden combination of colours. You will be given
+limited information about each guess you make, enabling you to
+refine the next guess.
+<p>
+Drag from the colours on the left into the topmost unfilled row to
+make a guess; then click on the small circles to submit that guess.
+The small circles give you your feedback: black pegs indicate how
+many of the colours you guessed were the right colour in the right
+place, and white pegs indicate how many of the rest were the right
+colours but in the wrong place.
--- /dev/null
+++ b/html/inertia.html
@@ -1,0 +1,14 @@
+Inertia
+<p>
+Slide the ball around the grid picking up the gems. Every time the
+ball moves, it will keep sliding until it either hits a wall, or
+stops on a stop square (the broken circles). Try to collect every
+gem without running into any of the mines.
+<p>
+Use the numeric keypad to slide the ball horizontally, vertically or
+diagonally. Alternatively, click on the grid to make the ball move
+towards where you clicked.
+<p>
+If you hit a mine and explode, you can select Undo from the Game
+menu and continue playing; the game will track how many times you
+died.
--- /dev/null
+++ b/html/javapage.pl
@@ -1,0 +1,104 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+open my $footerfile, "<", shift @ARGV or die "footer: open: $!\n";
+my $footer = "";
+$footer .= $_ while <$footerfile>;
+close $footerfile;
+
+for my $arg (@ARGV) {
+    $arg =~ /(.*\/)?([^\/]+)\.html$/ or die;
+    my $filename = $2;
+    open my $gamefile, "<", $arg or die "$arg: open: $!\n";
+    my $unfinished = 0;
+    my $docname = $filename;
+    chomp(my $puzzlename = <$gamefile>);
+    while ($puzzlename =~ s/^([^:=]+)(=([^:]+))?://) {
+        if ($1 eq "unfinished") {
+            $unfinished = 1;
+        } elsif ($1 eq "docname") {
+            $docname = $3;
+        } else {
+            die "$arg: unknown keyword '$1'\n";
+        }
+    }
+    my $instructions = "";
+    $instructions .= $_ while <$gamefile>;
+    close $gamefile;
+
+    open my $outpage, ">", "${filename}.html";
+
+    my $unfinishedtitlefragment = $unfinished ? "an unfinished puzzle " : "";
+    my $unfinishedheading = $unfinished ? "<h2 align=center>an unfinished puzzle</h2>\n" : "";
+    my $unfinishedpara;
+    my $links;
+    if ($unfinished) {
+        $unfinishedpara = <<EOF;
+<p>
+You have found your way to a page containing an <em>unfinished</em>
+puzzle in my collection, not linked from the <a href="../">main
+puzzles page</a>. Don't be surprised if things are hard to understand
+or don't work as you expect.
+EOF
+        $links = <<EOF;
+<p align="center">
+<a href="../">Back to main puzzles page</a> (which does not link to this)
+EOF
+    } else {
+        $unfinishedpara = "";
+        $links = <<EOF;
+<p align="center">
+<a href="../doc/${docname}.html#${docname}">Full instructions</a>
+|
+<a href="../">Back to main puzzles page</a>
+EOF
+    }
+
+    print $outpage <<EOF;
+<html>
+<head>
+<title>${puzzlename}, ${unfinishedtitlefragment}from Simon Tatham's Portable Puzzle Collection</title>
+<link rel="stylesheet" type="text/css" href="../../sitestyle.css" name="Simon Tatham's Home Page Style">
+<script type="text/javascript" src="resize-puzzle-applet.js"></script>
+</head>
+<body onLoad="initResizablePuzzleApplet();">
+<h1 align=center>${puzzlename}</h1>
+${unfinishedheading}
+<h2 align=center>from Simon Tatham's Portable Puzzle Collection</h2>
+
+${unfinishedpara}
+
+<p align="center">
+<table cellpadding="0">
+<tr>
+<td>
+<applet id="applet" archive="${filename}.jar" code="PuzzleApplet"
+        width="700" height="500">
+</applet>
+</td>
+<td>
+<div id="eresize" style="width:5px;height:500px;cursor:e-resize;"></div>
+</td>
+</tr>
+<td>
+<div id="sresize" style="width:700px;height:5px;cursor:s-resize;"></div>
+</td>
+<td>
+<div id="seresize" style="width:5px;height:5px;cursor:se-resize;"></div>
+</td>
+</tr>
+</table>
+
+${instructions}
+
+${links}
+
+${footer}
+</body>
+</html>
+EOF
+
+    close $outpage;
+}
--- /dev/null
+++ b/html/keen.html
@@ -1,0 +1,15 @@
+Keen
+<p>
+Fill in the grid with digits from 1 to the grid size, so that every
+digit appears exactly once in each row and column, and so that all
+the arithmetic clues are satisfied (i.e. the clue number in each
+thick box should be possible to construct from the digits in the box
+using the specified arithmetic operation).
+<p>
+To place a number, click in a square to select it, then type the
+number on the keyboard. To erase a number, click to select a square
+and then press Backspace.
+<p>
+Right-click in a square and then type a number to add or remove the
+number as a pencil mark, indicating numbers that you think
+<em>might</em> go in that square.
--- /dev/null
+++ b/html/lightup.html
@@ -1,0 +1,10 @@
+Light Up
+<p>
+Place light bulbs in the grid so as to light up all the blank
+squares. A light illuminates its own square and all the squares in
+the same row or column unless blocked by walls (black squares).
+Lights may not illuminate each other. Each numbered square must be
+orthogonally adjacent to exactly the given number of lights.
+<p>
+Click on a square to place or remove a light. Right-click to place a
+dot indicating that you think there is no light in that square.
--- /dev/null
+++ b/html/loopy.html
@@ -1,0 +1,13 @@
+Loopy
+<p>
+Form a single closed loop out of the grid edges, in such a way that
+every numbered square has exactly that many of its edges included in
+the loop.
+<p>
+Click on a grid edge to mark it as part of the loop (black), and
+again to return to marking it as undecided (yellow). Right-click on
+a grid edge to mark it as definitely not part of the loop (faint
+grey), and again to mark it as undecided again.
+<p>
+When you have mastered the square grid, look in the Type menu for
+many other types of tiling!
--- /dev/null
+++ b/html/magnets.html
@@ -1,0 +1,14 @@
+Magnets
+<p>
+Fill each domino shape with either a magnet (consisting of a + and
+&#8722; pole) or a neutral domino (green).
+<p>
+The number of + poles that in each row and column must match the
+numbers along the top and left; the number of &#8722; poles must
+match the numbers along the bottom and right. Two + poles may not be
+orthogonally adjacent to each other, and similarly two &#8722; poles.
+<p>
+Left-click a domino to toggle it between being empty and being a
+magnet (the + is placed in the end you click). Right-click to toggle
+between empty, neutral, and a ?? mark indicating that you're sure
+it's a magnet but don't yet know which way round it goes.
--- /dev/null
+++ b/html/map.html
@@ -1,0 +1,15 @@
+Map
+<p>
+Colour the map with four colours, so that no two adjacent regions
+have the same colour. (Regions touching at only one corner do not
+count as adjacent.) There is a unique colouring consistent with the
+coloured regions you are already given.
+<p>
+Drag from a coloured region to a blank one to colour the latter the
+same colour as the former. Drag from outside the grid into a region
+to erase its colour. (You cannot change the colours of the regions
+you are given at the start of the game.)
+<p>
+Right-drag from a coloured region to a blank one to add dots marking
+the latter region as <em>possibly</em> the same colour as the
+former, or to remove those dots again.
--- /dev/null
+++ b/html/mines.html
@@ -1,0 +1,18 @@
+Mines
+<p>
+Try to expose every square in the grid that is not one of the hidden
+mines, without opening any square that is a mine.
+<p>
+Click in a square to open it. Every opened square are marked with
+the number of mines in the surrounding 8 squares, if there are any;
+if not, all the surrounding squares are automatically opened.
+<p>
+Right-click in a square to mark it with a flag if you think it is a
+mine. If a numbered square has exactly the right number of flags
+around it, you can click in it to open all the squares around it
+that are not flagged.
+<p>
+The first square you open is guaranteed to be safe, and (by default)
+you are guaranteed to be able to solve the whole grid by deduction
+rather than guesswork. (Deductions may require you to think about
+the total number of mines.)
--- /dev/null
+++ b/html/net.html
@@ -1,0 +1,17 @@
+Net
+<p>
+Rotate the grid squares so that they all join up into a single
+connected network with no loops.
+<p>
+Left-click in a square to rotate it anticlockwise. Right-click to
+rotate it clockwise. Middle-click, or shift-left-click if you have
+no middle mouse button, to lock a square once you think it is
+correct (so you don't accidentally rotate it again); do the same
+again to unlock it if you change your mind.
+<p>
+Squares connected to the middle square are lit up. Aim to light up
+every square in the grid (not just the endpoint blobs).
+<p>
+When this gets too easy, select a 'wrapping' variant from the Type
+menu to enable grid lines to run off one edge of the playing area
+and come back on the opposite edge!
--- /dev/null
+++ b/html/netslide.html
@@ -1,0 +1,14 @@
+Netslide
+<p>
+Slide the grid squares around so that they all join up into a single
+connected network with no loops.
+<p>
+Click on the arrows at the edges of the grid to move a row or column
+left, right, up or down. The square that falls off the end of the
+row comes back on the other end.
+<p>
+Squares connected to the middle square are lit up. Aim to light up
+every square in the grid (not just the endpoint blobs).
+<p>
+Connecting across a red barrier line is forbidden. On harder levels,
+there are fewer barriers, which makes it harder rather than easier!
--- /dev/null
+++ b/html/pattern.html
@@ -1,0 +1,12 @@
+Pattern
+<p>
+Fill in the grid with a pattern of black and white squares, so that
+the numbers in each row and column match the lengths of consecutive
+runs of black squares.
+<p>
+Left-click in a square to mark it black; right-click (or hold Ctrl
+while left-clicking) to mark it white. Click and drag along a row or
+column to mark multiple squares black or white at once. Middle-click
+(or hold Shift while left-clicking) to return a square to grey
+(meaning undecided): dragging like that can erase a whole rectangle,
+not just a row or column.
--- /dev/null
+++ b/html/pearl.html
@@ -1,0 +1,13 @@
+Pearl
+<p>
+Draw a single closed loop by connecting together the centres of
+adjacent grid squares, so that some squares end up as corners, some as
+straights (horizontal or vertical), and some may be empty. Every
+square containing a black circle must be a corner not connected
+directly to another corner; every square containing a white circle
+must be a straight which is connected to <em>at least one</em> corner.
+<p>
+Drag between squares to draw or undraw pieces of the loop.
+Alternatively, left-click the edge between two squares to turn it on
+or off. Right-click an edge to mark it with a cross indicating that
+you are sure the loop does not go through it.
--- /dev/null
+++ b/html/pegs.html
@@ -1,0 +1,8 @@
+Pegs
+<p>
+Jump one peg over another to remove the one you jumped over. Try to
+remove all but one peg.
+<p>
+Drag a peg into an empty space to make a move. The target space must
+be exactly two holes away from the starting peg, in an orthogonal
+direction, and there must be a peg in the hole in between.
--- /dev/null
+++ b/html/range.html
@@ -1,0 +1,21 @@
+Range
+<p>
+Colour some squares black, so as to meet the following conditions:
+<ul>
+<li>
+No two black squares are orthogonally adjacent.
+<li>
+No group of white squares is separated from the rest of the grid by
+black squares.
+<li>
+Each numbered cell can see precisely that many white squares in
+total by looking in all four orthogonal directions, counting itself.
+(Black squares block the view. So, for example, a 2 clue must be
+adjacent to three black squares or grid edges, and in the fourth
+direction there must be one white square and then a black one beyond
+it.)
+</ul>
+
+<p>
+Left-click to colour a square black. Right-click to mark a square
+with a dot, if you know it should not be black.
--- /dev/null
+++ b/html/rect.html
@@ -1,0 +1,10 @@
+docname=rectangles:Rectangles
+<p>
+Draw lines along the grid edges to divide the grid into rectangles,
+so that each rectangle contains exactly one numbered square and its
+area is equal to the number written in that square.
+<p>
+Click and drag from one grid corner to another, or from one square
+centre to another, to draw a rectangle. You can also drag along a
+grid line to just draw a line at a time, or just click on a single
+grid edge to draw or erase it.
--- /dev/null
+++ b/html/samegame.html
@@ -1,0 +1,14 @@
+Same Game
+<p>
+Try to empty the playing area completely, by removing connected
+groups of two or more squares of the same colour. Then try to score
+as much as possible, by removing large groups at a time instead of
+small ones.
+<p>
+Click on a coloured square to highlight the rest of its connected
+group. The status line will print the number of squares selected,
+and the score you would gain by removing them. Click again to remove
+the group; other squares will fall down to fill the space, and if
+you empty a whole column then the other columns will move up. You
+cannot remove a single isolated square: try to avoid dead-end
+positions where all remaining squares are isolated.
--- /dev/null
+++ b/html/signpost.html
@@ -1,0 +1,14 @@
+Signpost
+<p>
+Connect all the squares together into a sequence, so that every
+square's arrow points towards the square that follows it (though the
+next square can be any distance away in that direction).
+
+<p>
+Left-drag from a square to the square that should follow it, or
+right-drag from a square to the square that should precede it.
+
+<p>
+Left-drag a square off the grid to break all links to it. Right-drag
+a square off the grid to break all links to it and everything else
+in its connected chain.
--- /dev/null
+++ b/html/singles.html
@@ -1,0 +1,11 @@
+Singles
+<p>
+Black out some of the squares, in such a way that:
+<ul><li>no number appears twice in any row or column
+<li>no two black squares are adjacent
+<li>the white squares form a single connected group (connections
+along diagonals do not count).</ul>
+<p>
+Click in a square to black it out, and again to uncover it.
+Right-click in a square to mark it with a circle, indicating that
+you're sure it should <em>not</em> be blacked out.
--- /dev/null
+++ b/html/sixteen.html
@@ -1,0 +1,8 @@
+Sixteen
+<p>
+Slide the grid squares around so that the numbers end up in
+consecutive order from the top left corner.
+<p>
+Click on the arrows at the edges of the grid to move a row or column
+left, right, up or down. The square that falls off the end of the
+row comes back on the other end.
--- /dev/null
+++ b/html/slant.html
@@ -1,0 +1,9 @@
+Slant
+<p>
+Fill in a diagonal line in every grid square so that there are no
+loops in the grid, and so that every numbered point has that many
+lines meeting at it.
+<p>
+Left-click in a square to mark it with a <code>\</code>; right-click
+to mark it with a <code>/</code>. Keep clicking in a square to
+cycle it between <code>\</code>, <code>/</code> and empty.
--- /dev/null
+++ b/html/solo.html
@@ -1,0 +1,20 @@
+Solo
+<p>
+Fill in a number in every square so that every number appears
+exactly once in each row, each column and each block marked by thick
+lines.
+<p>
+To place a number, click in a square to select it, then type the
+number on the keyboard. To erase a number, click to select a square
+and then press Backspace.
+<p>
+Right-click in a square and then type a number to add or remove the
+number as a pencil mark, indicating numbers that you think
+<em>might</em> go in that square.
+<p>
+When you master the basic game, try Jigsaw mode (irregularly shaped
+blocks), X mode (the two main diagonals of the grid must also
+contain every number once), Killer mode (instead of single-cell
+clues you are given regions of the grid each of which must add up to
+a given total, again without reusing any digits), or all of those at
+once!
--- /dev/null
+++ b/html/tents.html
@@ -1,0 +1,20 @@
+Tents
+<p>
+Place tents in the empty squares in such a way that:
+<ul>
+<li>no two tents are adjacent, even diagonally
+<li>the number of tents in each row and column matches the numbers
+around the edge of the grid
+<li>it is possible to match tents to trees so that each tree is
+orthogonally adjacent to its own tent (but may also be adjacent to
+other tents).
+</ul>
+<p>
+Click in a square to place or remove a tent. Right-click to mark a
+square as empty (not a tent). Right-click and drag along a row or
+column to mark many squares at once as empty.
+<p>
+Warning '!' marks appear to indicate adjacent tents. Numbers round
+the edge of the grid light up red to indicate they do not match the
+number of tents in the row. Groups of tents light up red to indicate
+that they have too few trees between them, and vice versa.
--- /dev/null
+++ b/html/towers.html
@@ -1,0 +1,19 @@
+Towers
+<p>
+Fill in the grid with towers whose heights range from 1 to the grid
+size, so that every possible height appears exactly once in each row
+and column, and so that each clue around the edge counts the number
+of towers that are visible when looking into the grid from that
+direction. (Taller towers hide shorter ones behind them. So the
+sequence 2,1,4,3,5 would match a clue of 3 on the left, because the
+1 is hidden behind the 2 and the 3 is hidden behind the 4. On the
+right, it would match a clue of 1 because the 5 hides everything
+else.)
+<p>
+To place a tower, click in a square to select it, then type the
+desired height on the keyboard. To erase a tower, click to select a
+square and then press Backspace.
+<p>
+Right-click in a square and then type a number to add or remove the
+number as a pencil mark, indicating tower heights that you think
+<em>might</em> go in that square.
--- /dev/null
+++ b/html/twiddle.html
@@ -1,0 +1,15 @@
+Twiddle
+<p>
+Rotate square sections of the grid to arrange the squares into
+numerical order starting from the top left.
+<p>
+In the basic game, you rotate a 2&times;2 square section. Left-click
+in the centre of that section (i.e. on a corner point between four
+squares) to rotate the whole section anticlockwise. Right-click to
+rotate the section clockwise.
+<p>
+When you master the basic game, go to the Type menu to try it with
+larger rotating groups (for a 3&times;3 group you must click in the
+centre of a square to rotate the block around it). Or select the
+'orientable' mode in which every square must end up the right way
+round as well as in the right place. Or both!
--- /dev/null
+++ b/html/undead.html
@@ -1,0 +1,19 @@
+Undead
+<p>
+Fill in every grid square which doesn't contain a mirror with either a
+ghost, a vampire, or a zombie. The numbers round the grid edges show
+how many monsters must be visible along your line of sight if you look
+directly into the grid from that position, along a row or column.
+Zombies are always visible; ghosts are only visible when reflected in
+at least one mirror; vampires are only visible when not reflected in
+any mirror.
+
+<p>
+To place a monster, click in a square to select it, then type the
+monster's letter on the keyboard: G for a ghost, V for a vampire or Z
+for a zombie. To erase a monster, click to select a square and then
+press Backspace.
+<p>
+Right-click in a square and then type a letter to add or remove the
+monster as a pencil mark, indicating monsters that you think
+<em>might</em> go in that square.
--- /dev/null
+++ b/html/unequal.html
@@ -1,0 +1,14 @@
+Unequal
+<p>
+Fill in the grid with numbers from 1 to the grid size, so that every
+number appears exactly once in each row and column, and so that all
+the <code>&lt;</code> signs represent true inequalities (i.e. the
+number at the pointed end is smaller than the number at the open end).
+<p>
+To place a number, click in a square to select it, then type the
+number on the keyboard. To erase a number, click to select a square
+and then press Backspace.
+<p>
+Right-click in a square and then type a number to add or remove the
+number as a pencil mark, indicating numbers that you think
+<em>might</em> go in that square.
--- /dev/null
+++ b/html/unruly.html
@@ -1,0 +1,12 @@
+Unruly
+<p>
+Colour every square either black or white, in such a way that:
+<ul><li>no three consecutive squares, horizontally or vertically, are
+the same colour
+<li>each row and column contains the same number of black and white
+squares.</ul>
+<p>
+Left-click in an empty square to turn it black it out, or right-click
+to turn it white. Click again in an already-filled square to cycle it
+between black and white and empty; middle-click to reset any square to
+empty.
--- /dev/null
+++ b/html/untangle.html
@@ -1,0 +1,5 @@
+Untangle
+<p>
+Move the points around so that none of the lines cross.
+<p>
+Click on a point and drag it to move it.