chiark / gitweb /
12 months agochangelog: document last change for-aldabra
Ian Jackson [Sun, 24 Sep 2017 13:38:56 +0000 (14:38 +0100)]
changelog: document last change

12 months agoRevert "Switch to using Halibut's new direct .CHM generation."
Ian Jackson [Sun, 24 Sep 2017 13:38:29 +0000 (14:38 +0100)]
Revert "Switch to using Halibut's new direct .CHM generation."

This reverts commit 7bdfda840962e0de7442c4f58d37ca1f560a5797.


12 months agoremove -pedantic
Ian Jackson [Sun, 24 Sep 2017 13:28:04 +0000 (14:28 +0100)]
remove -pedantic

12 months agochangelog: version
Ian Jackson [Sun, 24 Sep 2017 13:15:45 +0000 (14:15 +0100)]
changelog: version

12 months agoMerge remote-tracking branch 'upstream/master' into aldabra
Ian Jackson [Sun, 24 Sep 2017 13:15:10 +0000 (14:15 +0100)]
Merge remote-tracking branch 'upstream/master' into aldabra

12 months agochangelog: version
Ian Jackson [Sun, 24 Sep 2017 13:06:29 +0000 (14:06 +0100)]
changelog: version

12 months agodeclare ff Merge commit '7cae89f' into HEAD
Ian Jackson [Sun, 24 Sep 2017 13:00:36 +0000 (14:00 +0100)]
declare ff Merge commit '7cae89f' into HEAD

12 months agoPattern: randomise rounding bias in generate().
Simon Tatham [Sat, 23 Sep 2017 18:22:37 +0000 (19:22 +0100)]
Pattern: randomise rounding bias in generate().

Now, with an odd grid size, we choose the posterisation threshold so
that half the time it delivers ceil(n/2) black squares and half the
time it delivers floor(n/2). Previously it only did the former, which
meant that asking Pattern to generate a 1x1 puzzle (with the bug in
the previous commit fixed) would always generate the one with a single
black square, and never the one with a single white square. Both are
trivial to solve, of course, but it seemed inelegant!

No change to the number of black squares in the puzzle solution can
constitute a spoiler for the player, of course, because that number is
trivial to determine without doing any difficult reasoning, just by
adding up all the clues in one dimension.

12 months agoPattern: missing special case in the solver.
Simon Tatham [Sat, 23 Sep 2017 18:17:36 +0000 (19:17 +0100)]
Pattern: missing special case in the solver.

We were filling in a row immediately as all-white if it had no clues
at all, but weren't filling in a row as all-black if it had a single
clue covering the entire row. Now we do both.

In particular, this caused the Pattern solver to be unable to take
advantage of one of the two kinds of totally obvious clue across the
_easy_ dimension of a trivial 1xN puzzle - and a special case of
_that_, as a user pointed out, is that the game generator hangs trying
to create a 1x1 puzzle, which ought to be the easiest thing in the

12 months agoBuild test HTML wrapper pages for the Javascript puzzles.
Simon Tatham [Wed, 20 Sep 2017 09:22:28 +0000 (10:22 +0100)]
Build test HTML wrapper pages for the Javascript puzzles.

This should make it less annoying for me to do local testing of the JS
output of a build, before I push a change. There's a new
build.out/jstest directory containing .html files suitable for loading
in a local browser, which refer to the JS files via an appropriate
relative path to the existing build.out/js directory.

12 months agoMap Ctrl-Shift-Z to Redo.
Simon Tatham [Wed, 20 Sep 2017 15:38:31 +0000 (16:38 +0100)]
Map Ctrl-Shift-Z to Redo.

This is in addition to the existing keystrokes r, ^R and ^Y. I've
become used to Ctrl-Shift-Z in other GUI games, and my fingers keep
getting confused when my own puzzles don't handle it the same way.

12 months agoGenerate special fake keypresses from menu options.
Simon Tatham [Wed, 20 Sep 2017 09:13:36 +0000 (10:13 +0100)]
Generate special fake keypresses from menu options.

This fixes an amusing UI bug that I think can currently only come up
in the unpublished puzzle 'Group', but there's no reason why other
puzzles _couldn't_ do the thing that triggers the bug, if they wanted

Group has unusual keyboard handling, in that sometimes (when a cell is
selected for input and the key in question is valid for the current
puzzle size) the game's interpret_move function will eat keystrokes
like 'n' and 'u' that would otherwise trigger special UI events like
New Game or Undo.

The bug is that fake keypress events generated from the GUI menus
looked enough like those keystrokes that interpret_move would eat
those too. So if you start, say, a 16x16 Group puzzle, select an empty
cell, and then choose 'new game' from the menu, Group will enter 'n'
into the cell instead of starting a new game!

I've fixed this by inventing a new set of special keystroke values
called things like UI_NEWGAME and UI_UNDO, and having the GUI menus in
all my front ends generate those in place of 'n' and 'u'. So now the
midend can tell the difference between 'n' on the keyboard and New
Game from the menu, and so Group can treat them differently too. In
fact, out of sheer overcaution, midend.c will spot keystrokes in this
range and not even _pass_ them to the game back end, so Group
shouldn't be able to override these special events even by mistake.

One fiddly consequence is that in gtk.c I've had to rethink the menu
accelerator system. I was adding visible menu accelerators to a few
menu items, so that (for example) 'U' and 'R' showed up to the right
of Undo and Redo in the menu. Of course this had the side effect of
making them real functioning accelerators from GTK's point of view,
which activate the menu item in the same way as usual, causing it to
send whatever keystroke the menu item generates. In other words,
whenever I entered 'n' into a cell in a large Group game, this was the
route followed by even a normal 'n' originated from a real keystroke -
it activated the New Game menu item by mistake, which would then send
'n' by mistake instead of starting a new game!

Those mistakes cancelled each other out, but now I've fixed the
latter, I've had to fix the former too or else the GTK front end would
now undo all of this good work, by _always_ translating 'n' on the
keyboard to UI_NEWGAME, even if the puzzle would have wanted to treat
a real press of 'n' differently. So I've fixed _that_ in turn by
putting those menu accelerators in a GtkAccelGroup that is never
actually enabled on the main window, so the accelerator keys will be
displayed in the menu but not processed by GTK's keyboard handling.

(Also, while I was redoing this code, I've removed the logic in
add_menu_item_with_key that reverse-engineered an ASCII value into
Control and Shift modifiers plus a base key, because the only
arguments to that function were fixed at compile time anyway so it's
easier to just write the results of that conversion directly into the
call sites; and I've added the GTK_ACCEL_LOCKED flag, in recognition
of the fact that _because_ these accelerators are processed by a weird
mechanism, they cannot be dynamically reconfigured by users and
actually work afterwards.)

12 months agoCall game_id_change_notify_function after deserialisation.
Simon Tatham [Thu, 14 Sep 2017 18:06:44 +0000 (19:06 +0100)]
Call game_id_change_notify_function after deserialisation.

That's a case in which the current game IDs have changed, so the
midend ought to be calling the front-end function (if any) that
notifies it when that happens.

The only front end of mine that was affected by this missing call was
the Javascript one, which uses that callback to update the 'Link to
this puzzle' links below the game canvas - but, of course, that front
end didn't ever call midend_deserialise until this month, so no wonder
I never noticed before.

(But downstream front ends might be affected too, for all I know.)

12 months agoFix borders on the HTML menu bar.
Simon Tatham [Thu, 7 Sep 2017 17:44:58 +0000 (18:44 +0100)]
Fix borders on the HTML menu bar.

Commit ef39e6e17 made a goof in which the 'New game' button had no
border on the left and an accidental extra one on the right, which I'm
really not sure how I failed to spot when I tested it yesterday.

12 months agoHTML: move 'New game' back out of the drop-down menu.
Simon Tatham [Wed, 6 Sep 2017 20:49:39 +0000 (21:49 +0100)]
HTML: move 'New game' back out of the drop-down menu.

The only user to send me a comment today on the new layout said that
that menu item in particular is annoying to have hidden behind more
clicks, so by a vote of one to nothing, it's back out in the open.

12 months agoMake the images on the web page link to the JS puzzles.
Simon Tatham [Tue, 5 Sep 2017 20:02:18 +0000 (21:02 +0100)]
Make the images on the web page link to the JS puzzles.

I've been thinking for a while that it's about time I did that. Those
images used to link to the Java versions of the puzzles, back when
Java was the in-browser applet platform of choice; then I made them
not link to either one when it wasn't clear which system would win;
but now JS has clearly won, it's past time the images linked to the JS
puzzles, as the obviously sensible default.

12 months agoSupport for loading games in Javascript puzzles.
Simon Tatham [Tue, 5 Sep 2017 19:48:42 +0000 (20:48 +0100)]
Support for loading games in Javascript puzzles.

This is done by showing a dialog containing an <input type="file">
through which the user can 'upload' a save file - though, of course,
the 'upload' doesn't go to any HTTP server, but only into the mind of
the Javascript running in the same browser.

It would be even nicer to support drag-and-drop as an alternative UI
for getting the save file into the browser, but that isn't critical to
getting the first version of this feature out of the door.

12 months agoSupport for saving games in Javascript puzzles.
Simon Tatham [Tue, 5 Sep 2017 19:10:16 +0000 (20:10 +0100)]
Support for saving games in Javascript puzzles.

This is done by getting midend_serialise to produce the complete
saved-game file as an in-memory string buffer, and then encoding that
into a data: URI which we provide to the user as a hyperlink in a
dialog box. The hyperlink has the 'download' attribute, which means
clicking on it should automatically offer to save the file, and also
lets me specify a not-too-silly default file name.

12 months agoFactor some HTML dialog functions out of emcclib.
Simon Tatham [Tue, 5 Sep 2017 19:09:56 +0000 (20:09 +0100)]
Factor some HTML dialog functions out of emcclib.

I'm about to want to call these from Javascript as well as from
Emscripten-compiled C, so I need versions of them that aren't wrapped
up in the Emscripten library object and also don't expect half their
parameters to be Emscripten-verse char pointers requiring calls to

The easiest way to achieve all of that is to turn the Emscripten-
ready versions of those functions in emcclib.js into tiny wrappers
around the JS versions, which do the pointer stringification and a
couple of other details like directing callbacks to the right C

12 months agoOrganise the JS menus/buttons bar more like a menu.
Simon Tatham [Tue, 5 Sep 2017 06:06:48 +0000 (07:06 +0100)]
Organise the JS menus/buttons bar more like a menu.

I'm about to introduce a few more options, and the button bar is
already a bit wide, so I think I should shrink it horizontally before
putting more stuff on it. So I've organised the options into something
more like the Game and Type submenus that the desktop versions use.

However, I haven't gone quite all the way, on the basis that the web
versions will be at least slightly playable on devices without much
keyboard, which makes it worth keeping the in-play actions (Undo,
Redo, and to a lesser extent Restart and Solve) accessible as
top-level buttons in a single click each.

As part of this change, I've also separated the menu bar into a
drop-down menus section and a top-level buttons section with a gap
between them, and put a signalling "..." on the end of the titles in
the former section.

This change also removes the class="left" on the game-type menu and
its submenus, which were previously there to deal with that menu being
all the way over on the far right of the menu bar. But the CSS for
those classes is still there in, and should still work if I
need it again in future.

12 months agoMines: show the number of safe squares left, if it's small.
Simon Tatham [Mon, 4 Sep 2017 18:50:43 +0000 (19:50 +0100)]
Mines: show the number of safe squares left, if it's small.

This is intended to make life easier for the _really_ dense grids in
which the generator algorithm falls back to a bare clearing, a tightly
packed section round the edges, and a fringe of deductions required in

In that situation, you can deduce _in principle_ from the remaining-
mines counter that there are (say) one, or two, squares left to be
uncovered before everything remaining has to be a mine. And often the
game will require that deduction in order to solve it all by pure
logic. But actually doing it requires counting up the huge number of
covered squares in an irregularly shaped area and subtracting the mine
count in the status line, which is a real pain.

In fact, people failing to do that are the biggest source of (wrong)
bug reports about Mines games having no solution, so with any luck
this will make my own life easier.

13 months agoSwitch the Windows builds over to clang-cl.
Simon Tatham [Thu, 24 Aug 2017 18:12:54 +0000 (19:12 +0100)]
Switch the Windows builds over to clang-cl.

This also switches them to being 64-bit, which I think is
probably acceptable in this modern age, especially for such
a non-essential piece of software. If anyone complains I can
always reinstate a parallel 32-bit build.

To support the switch to 64-bit, this commit also changes the default
install directory in the MSI to 'Program Files' rather than 'Program
Files (x86)'.

13 months agoSet up a clang-cl makefile.
Simon Tatham [Thu, 24 Aug 2017 18:11:52 +0000 (19:11 +0100)]
Set up a clang-cl makefile.

Mostly just cribbed from the corresponding changes in PuTTY's
build setup, although since the two scripts are not
_quite_ identical, I had to make a few tweaks.

13 months agoWin64-cleanness: switch to {Get,Set}WindowLongPtr.
Simon Tatham [Thu, 24 Aug 2017 18:11:13 +0000 (19:11 +0100)]
Win64-cleanness: switch to {Get,Set}WindowLongPtr.

13 months agoDiscontinue the Inno Setup Puzzles installer.
Simon Tatham [Thu, 24 Aug 2017 18:09:53 +0000 (19:09 +0100)]
Discontinue the Inno Setup Puzzles installer.

I'm getting rid of these installers in general, and also I'm about to
switch the Windows builds over to my new-look non-Windows non-Wine
system, which can't run the Inno Setup builder anyway.

13 months agoNet: fix assertion failure on insoluble puzzles.
Simon Tatham [Thu, 24 Aug 2017 18:38:29 +0000 (19:38 +0100)]
Net: fix assertion failure on insoluble puzzles.

The solver code still had an assumption, which must have dated before
the Solve menu option was introduced, that all puzzles presented to it
had at least one valid solution, and was enforcing that assumption by
assert(). Now the solver returns a more sensible failure code which
solve_game() can convert into a proper error message.

15 months agoMake cellsize a char.
Phil Bordelon [Mon, 5 Jun 2017 03:48:56 +0000 (23:48 -0400)]
Make cellsize a char.

Apparently new versions of GCC get grumpy if the possible range for a sprintf()
call exceeds MAXINT, which would never happen in actuality here due to the size
of the puzzles we're dealing with... but the compiler doesn't know that, of
course, so thinks that something may have gone horribly awry.  Changing it to a
char solves the problem neatly.

16 months agoSwitch to using Halibut's new direct .CHM generation.
Simon Tatham [Sat, 13 May 2017 17:55:52 +0000 (18:55 +0100)]
Switch to using Halibut's new direct .CHM generation.

This allows me to remove HTML Help Workshop completely from my build
dependencies, and good riddance!

16 months agoSwitch chiark URLs to https.
Simon Tatham [Sun, 7 May 2017 15:25:56 +0000 (16:25 +0100)]
Switch chiark URLs to https.

16 months agoFix infinite-loop bug in Loopy's autofollow feature.
Simon Tatham [Fri, 5 May 2017 06:09:22 +0000 (07:09 +0100)]
Fix infinite-loop bug in Loopy's autofollow feature.

Thanks to Glen Sawyer for reporting it. This is surely a consequence
of separating interpret_move from execute_move - if I'd done things in
the more obvious way, then this bug would never have happened, because
once the autofollow code had gone once round the loop it would find
that the starting edge was no longer in the same state it was looking
for. But since we don't start changing the states of edges until
execute_move(), it's possible for interpret_move() to go round and
round a cycle for ever.

Fortunately, it can _only_ happen if the edge you clicked on was part
of a loop which is the whole of its connected component - i.e. every
vertex in the cycle has degree 2 - and therefore we don't need O(N)
space to detect it (e.g. by recording whether each edge has been
visited already), but instead we can simply check if we've come back
to the starting edge.

16 months agoNitpicks to the previous commit.
Simon Tatham [Sun, 30 Apr 2017 17:40:41 +0000 (18:40 +0100)]
Nitpicks to the previous commit.

We enforce by assertion that the target buffer size is nonzero before
subtracting 1 from it; the call to fatal() is replaced by another
assert so that it will give clearer diagnostic information if it
fails; the variable holding the return value of strlen should be
size_t and its declaration should be in a C90-compatible location.
Finally, the reason why the function needs to be exist is clarified.

16 months agoWork around non-compliant sprintf().
Franklin Wei [Fri, 28 Apr 2017 23:48:36 +0000 (19:48 -0400)]
Work around non-compliant sprintf().

Rockbox's sprintf() lacks the ability to left-justify a string. Fixed
by adding a copy_left_justfied() function to misc.c.

This is a new version of this commit, as the previous version broke

17 months agoLoopy: optional 'autofollow' UI feature.
Simon Tatham [Mon, 24 Apr 2017 17:32:57 +0000 (18:32 +0100)]
Loopy: optional 'autofollow' UI feature.

This is mostly intended to make play more convenient for grid types
like the new Great-Great-Dodecagonal, and other grids with very
high-degree faces, in which it's annoying to have to spend half a
dozen mouse clicks on filling in a path of edges round the outside of
one of those faces which clearly have to all be set (or clear) if any
one of them is.

For now, the new feature is enabled by yet another of my hacky
environment variables, called LOOPY_AUTOFOLLOW. You can set it to
"off", "fixed" or "adaptive", where "off" is currently the default
(hence, no user-visible change in the default behaviour from this
change). If set to 'fixed', then toggling the state of any edge will
automatically toggle any further edges which are in the same state and
share a degree-2 vertex of the underlying grid design with the
original one. In 'adaptive' mode, the game goes even further, and will
consider outgoing edges in LINE_NO state not to count for purposes of
deciding if a vertex has degree 2.

17 months agoUse the new hierarchical preset menu feature in Loopy.
Simon Tatham [Mon, 24 Apr 2017 16:06:36 +0000 (17:06 +0100)]
Use the new hierarchical preset menu feature in Loopy.

This is the game for which I bothered to introduce the feature at all.
Because of the large number of grid types, the presets menu was
getting quite unwieldy; but because the grid dimensions for each grid
type are more or less arbitrary, it's still useful to have at least
one reasonably sized example of each grid type. So I've compromised by
moving some of the grid types into a 'More' submenu.

(I'm not particularly wedded to _which_ settings deserve relegation. I
may change my mind and move things about later on.)

17 months agoRework the preset menu system to permit submenus.
Simon Tatham [Mon, 24 Apr 2017 15:00:24 +0000 (16:00 +0100)]
Rework the preset menu system to permit submenus.

To do this, I've completely replaced the API between mid-end and front
end, so any downstream front end maintainers will have to do some
rewriting of their own (sorry). I've done the necessary work in all
five of the front ends I keep in-tree here - Windows, GTK, OS X,
Javascript/Emscripten, and Java/NestedVM - and I've done it in various
different styles (as each front end found most convenient), so that
should provide a variety of sample code to show downstreams how, if
they should need it.

I've left in the old puzzle back-end API function to return a flat
list of presets, so for the moment, all the puzzle backends are
unchanged apart from an extra null pointer appearing in their
top-level game structure. In a future commit I'll actually use the new
feature in a puzzle; perhaps in the further future it might make sense
to migrate all the puzzles to the new API and stop providing back ends
with two alternative ways of doing things, but this seemed like enough
upheaval for one day.

17 months agoJavascript puzzles: switch to a CSS-based drop-down system.
Simon Tatham [Wed, 26 Apr 2017 13:39:45 +0000 (14:39 +0100)]
Javascript puzzles: switch to a CSS-based drop-down system.

The previous control buttons and dropdowns based on form elements were
always a bit ugly: partly in a purely visual sense, and partly because
of the nasty bodge I had to do with splitting the usual 'Custom' game
type menu item into two (to get round the fact that if an element of a
<select> is already selected, browsers won't send an event when it's
re-selected). Also, I'm about to want to introduce hierarchical
submenus in the Type menu, and <select> doesn't support that at all.

So here's a replacement system which does everything by CSS
properties, including the popping-up of menus when the mouse moves
over their parent menu item. (Thanks to the Internet in general for
showing me how that trick is done.)

17 months agoUse symbolic enum values in the Loopy presets array.
Simon Tatham [Mon, 24 Apr 2017 16:09:30 +0000 (17:09 +0100)]
Use symbolic enum values in the Loopy presets array.

The use of plain numbers was needlessly confusing, and in particular
made it too easy to make unintended changes to the existing Loopy
presets when inserting a new grid enum value anywhere other than at
the end of the list.

But in the course of doing this I realised that, against all
sensibleness, the numeric indices for grid types in grid.h and in
Loopy itself don't match up! Right now I don't want to get sidetracked
into fixing the structural confusion that made that happen in the
first place, but I've at least materialised Loopy's version of the
enum with clearly identifiable LOOPY_GRID_* names.

17 months agoNew Loopy tiling: 'Great Great Dodecagonal'.
Simon Tatham [Sun, 23 Apr 2017 06:41:46 +0000 (07:41 +0100)]
New Loopy tiling: 'Great Great Dodecagonal'.

Officially known as the '3-4-6-12 tiling', according to, e.g., .

Thanks to Michael Quevillon for contributing this patch (and for
choosing a less hard-to-remember name for the tiling :-).

18 months agoNet: rework status line to cope with empty squares.
Simon Tatham [Mon, 13 Mar 2017 19:58:22 +0000 (19:58 +0000)]
Net: rework status line to cope with empty squares.

Another oddity involving an empty square is that if it coincides with
the source square for highlights (either by original design of the
game id, or because the player Ctrl-moves the source square into an
empty grid cell during play), then everything stops being lit up as
active. That's fine - you can still play the game using other
indications of error, such as the loop detection highlight - but it
looks silly for the status line to say 'Active: 1/lots'. So in that
situation I suppress the 'active' counter completely; it comes back
when you move the source square to somewhere it's _possible_ to
highlight more than one square.

While I'm at it, I've also removed the active counter in the case
where the game is completely solved, because in that situation it's
more or less unnecessary anyway, and that way the normal course of
play on the default small grid size doesn't overflow the available
status line space.

18 months agoNet: fix completion check if top left square is empty.
Simon Tatham [Sun, 12 Mar 2017 09:11:43 +0000 (09:11 +0000)]
Net: fix completion check if top left square is empty.

A hand-typed grid is permitted to use the square type '0' (never
generated by Net's own grid generator), which is a completely empty
square. This requires an adjustment to the completion checker, so that
such squares aren't required to be connected; otherwise, a grid
containing one would be permanently uncompletable.

However, the completion checker missed one case - it was
unconditionally checking that all squares are connected to the _top
left corner_, on the basis that (before I thought of the zero square)
any source square is as good as any other if what you really want to
know is whether they're all connected to each other. But that means
that if the top left square _is_ the empty one, things to wrong - e.g.
5x5:02c328ade11adb129d7c3e524 would fail to give a completion flash.

Fixed by starting the completion-checking search from the first
non-empty square we find.

18 months agoGTK API deprecation: in GTK 3.22, stop using gdk_cairo_create.
Simon Tatham [Mon, 27 Feb 2017 19:26:06 +0000 (19:26 +0000)]
GTK API deprecation: in GTK 3.22, stop using gdk_cairo_create.

This is another annoyingly removed function, replaced by a tower of
about four assorted objects you have to create in succession.

18 months agoGTK API deprecation: use GtkCssProvider for window background.
Simon Tatham [Mon, 27 Feb 2017 19:11:02 +0000 (19:11 +0000)]
GTK API deprecation: use GtkCssProvider for window background.

gdk_window_set_background_rgba is deprecated as of GTK 3.22, because
apparently you can't just _say_ any more 'here is what I want my
window's background colour to be in places where a widget isn't'.
Instead you have to provide a GtkStyleProvider which can be slotted
into a wobbly tower of other providers with associated priorities, so
that the user can override your choices if they really want to.

And the easiest way to constructc a GtkStyleProvider in turn is to
write *actual CSS* and get GTK to parse it, so I end up converting my
nice numeric RGB values into a complicated text format for another
part of _the same process_ to parse back into numbers. Sigh.

20 months ago_show-debian-version-number
Ben Hutchings [Tue, 17 Jan 2017 23:57:33 +0000 (23:57 +0000)]

Include Debian version number in any version display to make
it obvious that the binaries are built from modified source.

Gbp-Pq: Name 303_show-debian-version-number.diff

20 months ago_slant-shade-filled
Ben Hutchings [Tue, 17 Jan 2017 23:57:33 +0000 (23:57 +0000)]

Gbp-Pq: Name 207_slant-shade-filled.diff

20 months ago_online-help
Ben Hutchings [Tue, 17 Jan 2017 23:57:33 +0000 (23:57 +0000)]

This works along the same lines as the Windows implementation,
though we have to try a bit harder to find a help browser.

Gbp-Pq: Name 202_online-help.diff

20 months ago_make-more-docs
Ben Hutchings [Tue, 17 Jan 2017 23:57:33 +0000 (23:57 +0000)]

Halibut already supports these formats but since the documentation is
all combined we need to do a bit more work to extract the right
information for each game's manual page.

Gbp-Pq: Name 201_make-more-docs.diff

20 months ago_translate-docs
Ben Hutchings [Tue, 17 Jan 2017 23:57:33 +0000 (23:57 +0000)]

Gbp-Pq: Name 206_translate-docs.diff

20 months agofix-ftbfs-with-gcc-6
Ben Hutchings [Tue, 17 Jan 2017 23:57:33 +0000 (23:57 +0000)]

Gbp-Pq: Name fix-ftbfs-with-gcc-6.patch

20 months ago_fix-pearl-min-dimensions
Ben Hutchings [Tue, 17 Jan 2017 23:57:33 +0000 (23:57 +0000)]

Josh Triplett reported:
> If I ask pearl to generate a 5x5 tricky puzzle, it runs forever.

I find that 5x6 or 6x5 works, so set the minimum accordingly.

Gbp-Pq: Name 102_fix-pearl-min-dimensions.diff

20 months agosgt-puzzles (20161228.7cae89f-1) unstable; urgency=medium
Ben Hutchings [Tue, 17 Jan 2017 23:57:33 +0000 (23:57 +0000)]
sgt-puzzles (20161228.7cae89f-1) unstable; urgency=medium

  * New upstream version
  * debian/rules: Generate menu file automatically, fixing the omission
    of Undead and Unruly (Closes: #832797)
  * Use debhelper compatibility level 9
  * debian/control: Update Standards-Version to 3.9.8; no changes needed
  * Build with Gtk+ 3

[dgit import unpatched sgt-puzzles 20161228.7cae89f-1]

20 months agoImport sgt-puzzles_20161228.7cae89f.orig.tar.gz
Ben Hutchings [Tue, 17 Jan 2017 23:57:33 +0000 (23:57 +0000)]
Import sgt-puzzles_20161228.7cae89f.orig.tar.gz

[dgit import orig sgt-puzzles_20161228.7cae89f.orig.tar.gz]

20 months agoImport sgt-puzzles_20161228.7cae89f-1.debian.tar.xz
Ben Hutchings [Tue, 17 Jan 2017 23:57:33 +0000 (23:57 +0000)]
Import sgt-puzzles_20161228.7cae89f-1.debian.tar.xz

[dgit import tarball sgt-puzzles 20161228.7cae89f-1 sgt-puzzles_20161228.7cae89f-1.debian.tar.xz]

20 months agoAdd some missing calls to midend_redraw().
Simon Tatham [Tue, 27 Dec 2016 16:13:01 +0000 (16:13 +0000)]
Add some missing calls to midend_redraw().

I've just noticed that the GTK game window was not being redrawn when
changing between puzzle modes that don't involve a window resize - by
selecting a preset from the Type menu (e.g. changing between different
12x12 settings in Flood) or via the Custom menu.

It looks as if the bug was introduced in commit 8dfe5cec3, which
suggests that it was a side effect of the switch from
gtk_window_resize_to_geometry to plain gtk_window_resize. My guess is
that the implementation of the former function inside GTK might have
happened to trigger an unconditional window resize, while the latter
took the shortcut of doing nothing if the window was already the right
size; hence, resize_fe() would have been reliably generating a redraw
event without me having to ask for one, but now it doesn't, so I have
to trigger one myself any time I've just called resize_fe.

21 months agoFix missing error highlights (+ array underrun!) in Pearl.
Simon Tatham [Fri, 16 Dec 2016 18:33:10 +0000 (18:33 +0000)]
Fix missing error highlights (+ array underrun!) in Pearl.

I was accidentally re-checking the value of component_state[comp]
after resetting comp to the special value -1, which caused a failure
to highlight stray path-shaped components if they existed in addition
to a large loop component. (Plus, of course, it's just illegal no
matter what visible behaviour it does or doesn't cause in practice.)

Fixed by adjusting the code to more closely match the version in Loopy
(I wonder how I managed to add two pieces of code in commit b31155b73
without noticing this difference between them).

21 months agoCorrect a logic error in Unequal game desc validation.
Simon Tatham [Sun, 11 Dec 2016 09:19:30 +0000 (09:19 +0000)]
Correct a logic error in Unequal game desc validation.

A user points out that the error check that should have detected a
non-digit where a digit should have been was never firing, due to an
&& that should have been ||.

I don't think it was a harmful error - the subsequent check that the
number was in range, plus the skipping past only digits to find the
next part of the string, combine to arrange that not many kinds of
invalid game id could actually get through.

But it did have the small effect that a 0 could be elided without
triggering an error, e.g. the game ids


would both be accepted, and would be decoded into the same game, even
though the former should have failed syntax validation. Now it does.

21 months agoClarify conditions to avoid compiler errors
Khem Raj [Tue, 6 Dec 2016 01:22:00 +0000 (01:22 +0000)]
Clarify conditions to avoid compiler errors

Fix errors pointed out by clang

error: logical not is only applied to the left hand side of this bitwise operator [-Werror,-Wlogical-not-parentheses]
|         if (only_immutable && !copy->flags[i] & FLAG_IMMUTABLE) continue;
|                               ^

Signed-off-by: Khem Raj <>
21 months agoStop using deprecated GTK 3 geometry-based functions.
Simon Tatham [Sat, 3 Dec 2016 08:49:29 +0000 (08:49 +0000)]
Stop using deprecated GTK 3 geometry-based functions.

Now we work out for ourselves how the drawing-area size relates to the
overall window size, by adding on the height of fe->menubar and/or

22 months agoClarify the Black Box rules slightly.
Simon Tatham [Sun, 30 Oct 2016 17:59:13 +0000 (17:59 +0000)]
Clarify the Black Box rules slightly.

Chris Boyle points out that two of the rules are implicitly intended
to be read as only applying if a previous rule hadn't already decided
what would happen, and suggested that since not all readers infer that
priority order, it would be better to explicitly make them mutually
exclusive so that there can be no confusion about which one applies.

22 months agoFix completion checking in Killer Solo.
Simon Tatham [Fri, 28 Oct 2016 17:57:41 +0000 (18:57 +0100)]
Fix completion checking in Killer Solo.

The check_valid() function was not verifying that each Killer cage
summed to the right thing! Thanks to Chris Goodyer for spotting it. I
wonder how nobody else has, in 8 years.

2 years agoAccount for disconnected paths in Loopy and Pearl error highlights.
Simon Tatham [Thu, 28 Apr 2016 19:42:23 +0000 (20:42 +0100)]
Account for disconnected paths in Loopy and Pearl error highlights.

In commits 24848706e and adc54741f, I revamped the highlighting of
erroneous connected components of those two puzzles' solution graphs
in cases where a non-solution loop existed, so that the largest
component was considered correct and the smaller ones lit up in red.

I intended this to work in the cases where you have most of a correct
solution as one component and a small spurious loop as another (in
which case the latter lights up red), or conversely where your mostly
correct component was joined into a loop leaving a few edges out (in
which case the left-out edges again light up red). However, a user
points out that I overlooked the case where your mostly correct
solution is not all one component! If you've got lots of separate
pieces of path, and one tiny loop that's definitely wrong, it's silly
to light up all but the longest piece of path as if they're erroneous.

Fixed by treating all the non-loop components as one unit for these
purposes. So if there is at least one loop and it isn't the only thing
on the board, then we _either_ light up all loops (if they're all
smaller than the set of non-loop paths put together), _or_ light up
everything but the largest loop (if that loop is the biggest thing on
the board).

2 years agoRe-run from within
Simon Tatham [Thu, 28 Apr 2016 19:34:59 +0000 (20:34 +0100)]
Re-run from within

It isn't necessary to cause the right files to _exist_, because is run from Buildscr which has already run mkauto. But it
turns out it _is_ important to get the relative timestamps of and the right way round, otherwise somebody
who unpacks the tarball and runs 'configure' and 'make' will find make
tries to rebuild because it thinks is newer -
and if they don't have the right automake installed, or any automake,
that will fail.

2 years agoExplicitly set RGB colourspace in's use of convert.
Simon Tatham [Sun, 24 Apr 2016 06:30:20 +0000 (07:30 +0100)]
Explicitly set RGB colourspace in's use of convert.

This is that annoying feature of up-to-date 'convert' in which
converting to or from a PNG file defaults to returning RGB values that
have been 'helpfully' gamma-corrected (or some such) from the exact
data stored in the source file to some nonsense you didn't want.

Usually the worst this causes is slightly washed-out looking graphics,
but in this case, since my entire aim was to squash the image into a
specific set of exact RGB values so as to turn it into a paletted
Windows icon file, it caused an actual build failure when the next
loop in couldn't find the gamma-corrected values in its
expected palette map, and no wonder.

2 years agoImprove 'illegal colour' error message in
Simon Tatham [Sun, 24 Apr 2016 06:29:25 +0000 (07:29 +0100)]
Improve 'illegal colour' error message in

It actually went off this morning, after an upgrade of ImageMagick,
and I found that it contained both unprintable characters in the
colour description and the wrong variable in the coordinate display.

2 years agoUpdate build script for Inno Setup 5.5.9.
Simon Tatham [Sat, 9 Apr 2016 10:44:03 +0000 (11:44 +0100)]
Update build script for Inno Setup 5.5.9.

Between 5.5.6 and 5.5.9 the default output file name changed. To
defend against that potentially happening again, I'm now explicitly
specifying the output file name in the .iss source file (or rather, in, which constructs it).

2 years agos/Subversion/git/ in README.
Simon Tatham [Mon, 14 Mar 2016 19:56:18 +0000 (19:56 +0000)]
s/Subversion/git/ in README.

Thanks to Kevin Buzzard for spotting that relic of an outmoded version
control system.

2 years agoAdd a .htaccess redirection for the new .msi file.
Simon Tatham [Fri, 11 Mar 2016 19:25:11 +0000 (19:25 +0000)]
Add a .htaccess redirection for the new .msi file.

Ahem. Left this out of yesterday's commit.

2 years agoUse WiX to generate an MSI-based Puzzles installer.
Simon Tatham [Thu, 10 Mar 2016 18:37:24 +0000 (18:37 +0000)]
Use WiX to generate an MSI-based Puzzles installer.

I've reused most of the install script I wrote for PuTTY recently,
minus the selectable-features dialog, and plus some preliminary Mason
templating to automatically build the right set of puzzle binaries
into the installer.

Stable GUIDs are autogenerated by the same technique I use in PuTTY's
Visual Studio project file generation: hash a fixed pile of randomly
generated bits (that is, randomly generated _once_ and used forever)
with each filename or other identifier and use those as your random
number source.

2 years agoUpdate Buildscr to use the new 'with' mechanism.
Simon Tatham [Tue, 1 Mar 2016 18:42:42 +0000 (18:42 +0000)]
Update Buildscr to use the new 'with' mechanism.

2 years agoTracks: fix further completion-checking loopholes.
Simon Tatham [Fri, 26 Feb 2016 06:59:46 +0000 (06:59 +0000)]
Tracks: fix further completion-checking loopholes.

A user pointed out that Tracks could sometimes flash for completion
when there wasn't even a full path from A to B! And it looks as if
that wasn't even a mistake I introduced with the loop-checking revamp
this week.

Now I _think_ it's complete: we set ret=FALSE in check_completion
wherever we also produce an error highlight, and also whenever there
is no path connecting A with B. And if there is a path connecting A
with B, then any square not on the path becomes an error highlight.

2 years agoPearl: revise loop detection similarly to Loopy.
Simon Tatham [Wed, 24 Feb 2016 19:36:41 +0000 (19:36 +0000)]
Pearl: revise loop detection similarly to Loopy.

Pearl has more or less the same attitude to loops as Loopy does, in
that a loop is required in the solution but some loops during play
want to be highlighted as errors. So it makes sense to use the same
strategy for loop highlighting.

I've cloned-and-hacked the code from Loopy rather than abstracting it
out, because there were some fiddly differences in application (like
checking of untouched clues in Pearl). Perhaps some day I can come
back and make it all neater.

Also, while I'm here, I've cleaned up the loop_length field in
game_state, which was carefully set up by check_completion() but never
actually used for anything. (If I remember rightly, it was going to be
used for a fancy victory flash which never saw the light of day.)

2 years agoPearl: reinstate a conditioned-out assertion.
Simon Tatham [Wed, 24 Feb 2016 19:31:54 +0000 (19:31 +0000)]
Pearl: reinstate a conditioned-out assertion.

I think this assertion must have been put under '#if 0' during early
development, and accidentally never taken out once the game started
actually working. Putting it back in doesn't cause the self-tests to
fail, so I'm reinstating it - if it does fail, I'd like to know about

2 years agoLoopy: be friendlier to right-click-less playing style.
Simon Tatham [Wed, 24 Feb 2016 19:27:10 +0000 (19:27 +0000)]
Loopy: be friendlier to right-click-less playing style.

Some people don't bother to use the right-click UI action that marks a
line as 'definitely not' rather than the initial default yellow
'unknown'. Previously, Loopy gave those people a UI annoyance for some
classes of mistake they made during solving: it would reliably
highlight a clue square with too _many_ edges around it, but not one
with too few - because in normal right-click-ful play, a clue with too
few LINE_YES only becomes an error when there aren't enough
LINE_UNKNOWN around it to potentially become the remaining YESes in

This change arranges that once the player closes the loop, _then_ we
light up underfilled clues, on the basis that adding any further edge
would be an obvious error, so it's no longer sensible to assume that
the user might be planning to come back and do so.

(It's not a very timely notification of errors - it's easy to imagine
someone making a mistake like this very near the start of play and
only finding out about it when they close the loop at the very end. I
discuss possible improvements in a comment, but I don't think any
improvement avoids that problem completely, so I think it may just be
a form of annoyance that right-click-less players have to live with.)

2 years agoLoopy: revamp loop detection, but not using findloop.
Simon Tatham [Wed, 24 Feb 2016 19:22:57 +0000 (19:22 +0000)]
Loopy: revamp loop detection, but not using findloop.

Loopy differs from the other recently-reworked puzzles in that it
doesn't disallow loops completely in the solution - indeed, one is
actually required! But not all loops are what you wanted, so you have
to be a bit more subtle in what you highlight as an error. And the new
findloop system doesn't make that easy, because it only answers the
question 'is this edge part of a loop?' and doesn't talk about loops
as a whole, or enumerate them.

But since I was working in this area anyway, I thought I might as well
have a think about it; and I've come up with a strategy that seems
quite sensible to me, which I describe in a big comment added in
loopy.c. In particular, the new strategy should make a more sensible
decision about whether to highlight the loop or the non-loop edges, in
cases where the user has managed to enter a loop plus some extra

2 years agoTracks: tighten up a small loophole in completion checking.
Simon Tatham [Wed, 24 Feb 2016 19:18:30 +0000 (19:18 +0000)]
Tracks: tighten up a small loophole in completion checking.

If you had a single connected path linking the source to the
destination but _also_ had a spurious edge elsewhere in the grid, then
the spurious edge would be highlighted as an error, but it wouldn't
inhibit declaring the game complete and showing the victory flash.

2 years agoTracks: use the new findloop for loop detection.
Simon Tatham [Wed, 24 Feb 2016 19:14:31 +0000 (19:14 +0000)]
Tracks: use the new findloop for loop detection.

Tracks's previous loop detector was very basic, and only bothered to
highlight one loop, even if the player managed to create more than one
at a time. Now we highlight all of them.

2 years agoSlant: use the new findloop for loop detection.
Simon Tatham [Wed, 24 Feb 2016 19:10:16 +0000 (19:10 +0000)]
Slant: use the new findloop for loop detection.

The old face-dsf based loop detector is gone, and now we just call
findloop instead.

This is just a code cleanup: it doesn't fix any bugs that I know of.
In principle, it provides the same futureproofing we gained by making
the same change in Net, but Slant as a puzzle is less adaptable to
topologically interesting surfaces - in particular, you _can't_ play
it on any edgeless surface like a torus or Klein bottle, because no
filled grid can be loop-free in the first place. (The only way a
connected component can avoid having a loop surrounding it is if it
connects to the grid edge, so there has to _be_ a grid edge.) But you
could play Slant on a Mobius strip, I think, so perhaps one day...

2 years agoNet: use the new findloop for loop detection.
Simon Tatham [Wed, 24 Feb 2016 19:05:43 +0000 (19:05 +0000)]
Net: use the new findloop for loop detection.

I've removed the old algorithm (the one described as 'footpath dsf' in
the findloop.c appendix comment, though I hadn't thought of that name
at the time), and replaced it with calls to the new API.

This should have no functional effect: there weren't any known bugs in
the previous loop-finder that affected currently supported play modes.
But this generality improvement means that non-orientable playing
surfaces could be supported in the future, which would have confused
the old algorithm. And Net, being the only puzzle as yet that's played
on a torus, is perhaps the one most likely to want to generalise
further at some point.

2 years agoBridges: use the new findloop for loop detection.
Simon Tatham [Wed, 24 Feb 2016 19:01:42 +0000 (19:01 +0000)]
Bridges: use the new findloop for loop detection.

Bridges only needs a loop detector for its non-default 'don't allow
loops' mode. But the one it had was using the graph-pruning strategy,
which means it had the dumb-bell bug - two loops joined by a path
would highlight the path as well as the loops. Switching to the new
findloop system fixes that bug.

A side effect is that I've been able to remove the 'scratch' array
from the game_state, which was only used by the old loop finder, so
that should save memory.

2 years agoNew centralised loop-finder, using Tarjan's algorithm.
Simon Tatham [Wed, 24 Feb 2016 18:57:03 +0000 (18:57 +0000)]
New centralised loop-finder, using Tarjan's algorithm.

In the course of another recent project I had occasion to read up on
Tarjan's bridge-finding algorithm. This analyses an arbitrary graph
and finds 'bridges', i.e. edges whose removal would increase the
number of connected components. This is precisely the dual problem to
error-highlighting loops in games like Slant that don't permit them,
because an edge is part of some loop if and only if it is not a

Having understood Tarjan's algorithm, it seemed like a good idea to
actually implement it for use in these puzzles, because we've got a
long and dishonourable history of messing up the loop detection in
assorted ways and I thought it would be nice to have an actually
reliable approach without any lurking time bombs. (That history is
chronicled in a long comment at the bottom of the new source file, if
anyone is interested.)

So, findloop.c is a new piece of reusable library code. You run it
over a graph, which you provide in the form of a vertex count and a
callback function to iterate over the neighbours of each vertex, and
it fills in a data structure which you can then query to find out
whether any given edge is part of a loop in the graph or not.

2 years agoAdd patternpicture to .gitignore.
Phil Bordelon [Sun, 14 Feb 2016 01:53:30 +0000 (20:53 -0500)]
Add patternpicture to .gitignore.

2 years agoUpdate documentation links.
Phil Bordelon [Sun, 14 Feb 2016 01:29:41 +0000 (20:29 -0500)]
Update documentation links.

Where possible (mostly with the Nikoli links), they've been updated to their
modern locations.  At least one link had to become a Wayback Machine link;
I didn't bother making the link a Wayback one because
there's no content there without the backing of Google App Engine.  There
are other implementations online nowadays, of course, but I didn't want to
change the meaning of the text if at all possible.  In addition, I added
Flash warnings for the Nikoli pages that now use Flash for instructions.

2 years agoAdd missing casts to unsigned char inside ctype functions.
Simon Tatham [Mon, 1 Feb 2016 19:06:36 +0000 (19:06 +0000)]
Add missing casts to unsigned char inside ctype functions.

These are necessary because the argument to a ctype function cannot be
a negative value unless it's EOF. Thanks to Cygwin gcc for pointing
out the mistake, and to Patrick Shaughnessy for this patch.

2 years agoRename the docs section for Rectangles.
Simon Tatham [Thu, 7 Jan 2016 19:33:34 +0000 (19:33 +0000)]
Rename the docs section for Rectangles.

The web page currently assumes it's called 'rect' rather than
'rectangles', because the web-page building script uses the first
field of each line of gamedesc.txt, same as the Unix binary name.
Rather than add another confusingly-almost-identical field to that
file, it's easier to just rename this one docs section to make the
assumption of equality hold.

2 years agoFix a typo in the Black Box docs examples.
Simon Tatham [Thu, 7 Jan 2016 19:30:56 +0000 (19:30 +0000)]
Fix a typo in the Black Box docs examples.

A letter offset by one from a ball on the edge should be an R, not an
H. Thanks to Kevin Buzzard for pointing out the error.

2 years agoFix a valgrind warning in the Keen DIFF_HARD solver code.
Simon Tatham [Sun, 3 Jan 2016 09:51:15 +0000 (09:51 +0000)]
Fix a valgrind warning in the Keen DIFF_HARD solver code.

The solver's array ctx->iscratch[] is used for a completely different
purpose in the DIFF_HARD code, compared to what it's used for in
DIFF_EASY and DIFF_NORMAL. In particular, a different number of
elements of the array are used - but the code which sets up the array
was not correctly initialising all of them.

I was also unable to find any clear comment that even explained _that_
the purpose of the array was entirely different between the two cases,
let alone explaining _what_ the two purposes were. So I've written
some comments as part of this commit, which should make things a bit
less confusing next time. (Though not much, I admit.)

2 years agorect: Fix compiler errors about uninitialized use of variables
Khem Raj [Wed, 30 Dec 2015 23:53:36 +0000 (23:53 +0000)]
rect: Fix compiler errors about uninitialized use of variables

error: 'r2.x' may be used uninitialized in this function

Its happening when using gcc 5.3 with musl C library. its considering
the case when case falls into default and immediately after exiting
this there is a check if (r1.h > 0 && r1.w > 0) where r1 element is
used but not assigned anything.

GCC is not noticing the control flow where the initilization will
always work due to assertion call can be a function call from libc

Signed-off-by: Khem Raj <>
2 years agoAdd a missing error message in Flood solve_game().
Simon Tatham [Thu, 24 Dec 2015 22:05:48 +0000 (22:05 +0000)]
Add a missing error message in Flood solve_game().

The only situation in which it actually can't find a solution is if
the puzzle is already solved, in which case it can at least fill in
*error to say so before it returns NULL.

2 years agoClarify in README that is for nmake.
Simon Tatham [Fri, 18 Dec 2015 14:50:44 +0000 (14:50 +0000)]
Clarify in README that is for nmake.

A user pointed out today that I hadn't actually said that!

2 years agoNew utility 'patternpicture', to build a Pattern from an xbm.
Simon Tatham [Fri, 11 Dec 2015 19:53:58 +0000 (19:53 +0000)]
New utility 'patternpicture', to build a Pattern from an xbm.

This utility works basically the same as galaxiespicture: you feed it
a .xbm bitmap on standard input, and it constructs a game ID which
solves to exactly that image. It will pre-fill some squares if that's
necessary to resolve ambiguity, or leave the grid completely blank if
it can.

2 years agoPattern: add a system of immutable pre-filled grid squares.
Simon Tatham [Fri, 11 Dec 2015 18:09:41 +0000 (18:09 +0000)]
Pattern: add a system of immutable pre-filled grid squares.

The game previously only supported numeric clues round the edge; but
if for some reason you really want a puzzle with a specific solution
bitmap and that bitmap doesn't happen to be uniquely soluble from only
its row and column counts, then this gives you a fallback approach of
pre-filling a few grid squares to resolve the ambiguities.

(This also applies if the puzzle is uniquely soluble *in principle*
but not by Pattern's limited solver - for example, Pattern has never
been able to solve 4x4:2/1/2/1/1.1/2/1/1 and still can't, but now it
can solve 4x4:2/1/2/1/1.1/2/1/1,Ap which has the hard part done for

Immutable squares are protected from modification during play, and
used as initial information by the solver.

2 years agoPattern: fix solver's handling of empty rows.
Simon Tatham [Fri, 11 Dec 2015 18:54:56 +0000 (18:54 +0000)]
Pattern: fix solver's handling of empty rows.

The algorithm for deducing how many squares in a row could be filled
in just from the initial clue set was focusing solely on _black_
squares, and forgot that if a row has a totally empty clue square then
everything in it can be filled in as white!

Now the solver can cope with puzzles such as 3x3:/1///1/ , where it
would previously have spuriously considered that it had no idea where
to start.

2 years agoPattern: make part of the game_state shared.
Simon Tatham [Thu, 10 Dec 2015 19:51:54 +0000 (19:51 +0000)]
Pattern: make part of the game_state shared.

The game_state now includes a pointer to a game_state_common
containing all the row and column clues, which is reference-counted
and therefore doesn't have to be physically copied in every dup_game.

2 years agoCode-sign the Windows puzzle binaries and installer.
Simon Tatham [Sat, 12 Dec 2015 09:17:33 +0000 (09:17 +0000)]
Code-sign the Windows puzzle binaries and installer.

Where facilities exist, that is. Like the approach I took with PuTTY
yesterday, Buildscr will now run a code-signing script over the binary
if you specify one in the bob config, and otherwise should fall back
to just leaving that step out.

2 years agoImplement align_label for GTK 3.[14,16).
Simon Tatham [Sun, 6 Dec 2015 16:00:10 +0000 (16:00 +0000)]
Implement align_label for GTK 3.[14,16).

gtk_misc_set_alignment was deprecated in GTK 3.14. But my replacement
code using gtk_label_set_{x,y}align doesn't work there, because that
function wasn't introduced until GTK 3.16, so there are two minor
versions in the middle where a third strategy is needed.

(That middle strategy doesn't permit arbitrary float alignments, but
that's OK, bceause we only actually use multiples of 0.5.)

2 years agoAllow unlocking an island despite moving slightly.
Chris Boyle [Sat, 28 Nov 2015 13:56:39 +0000 (13:56 +0000)]
Allow unlocking an island despite moving slightly.

Previously moving 1 pixel would be treated as a failed drag and not an unlock.

Now you only have to release the button somewhere on the island you started on.

2 years agoConvert Buildscr to use the new "do/win" mechanism.
Simon Tatham [Tue, 17 Nov 2015 18:47:29 +0000 (18:47 +0000)]
Convert Buildscr to use the new "do/win" mechanism.

2 years agoFix loophole in Palisade completion checker.
Simon Tatham [Tue, 3 Nov 2015 06:45:49 +0000 (06:45 +0000)]
Fix loophole in Palisade completion checker.

A user pointed out that if you construct a 'solution' in which no clue
square has too _many_ borders but at least one has too few, and then
bring those clues up to their count by adding extra stray border lines
_inside_ a connected component (avoiding actually dividing any
component completely into two), then the game checker treats that as
solved for victory-flash purposes, on the grounds that (a) the grid is
divided into components of the right size and (b) all clues are

A small example is 4x4n4:22a2b2c33, with the non-solution of dividing
the grid into four 2x2 square blocks and then adding a spurious extra
edge between the two 3 clues. The old Palisade completion check would
flash for victory _at the same time_ as highlighting the spurious edge

Fixed by enforcing in is_solved() that every border line must separate
two distinct connected components.

2 years agoFormat Palisade solve-type moves in sensible ASCII.
Simon Tatham [Tue, 3 Nov 2015 06:56:47 +0000 (06:56 +0000)]
Format Palisade solve-type moves in sensible ASCII.

The solve move stored in 'aux' by new_game_desc consists of printable
characters in the range '@' to 'O', each representing a 4-bit bitmap
of edges around a cell. But the one generated on the fly by
solve_game() was missing out the 0x40 bit and just returning
characters in the range ^@ to ^O - which would not only have been
horrible if you found such a string in a save file, but also meant
that a game with any completely borderless square would have a
solution move string terminating early due to the ^@, causing
execute_move() to reject it.

Example: ./palisade --test-solve --generate 1 5x5n5#12345-37 now
succeeds, where previously it failed an assertion.

2 years agoFix premature completion flash in Tracks.
Simon Tatham [Fri, 23 Oct 2015 18:33:52 +0000 (19:33 +0100)]
Fix premature completion flash in Tracks.

Commit 44e2690ab loosened check_completion's idea of what made a
square count as 'having track in it' for purposes of checking
violations of the row/column counts. Unfortunately, that loosened
notion also applied to the check for the game being complete - so the
game would announce a win as soon as you had every square shaded, even
if you hadn't actually laid all the exact track positions down.

Now we separately count up the number of track-ish squares and the
number of fully completed ones, and use the former for error checking
and the latter for completion checking.

2 years agoTents: mark squares as non-tents with {Shift,Control}-cursor keys.
Jonas Kölker [Mon, 19 Oct 2015 00:48:39 +0000 (02:48 +0200)]
Tents: mark squares as non-tents with {Shift,Control}-cursor keys.