aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAge
* Use a dedicated copy function to copy dsfs.Simon Tatham2023-04-20
| | | | | | | | | Previously we were duplicating the contents of a dsf using straight-up memcpy. Now there's a dsf_copy function wrapping the same memcpy. For the moment, this still has to take a size parameter, because the size isn't stored inside the dsf itself. But once we make a proper data type, it will be.
* Use a dedicated free function to free dsfs.Simon Tatham2023-04-20
| | | | | No functional change: currently, this just wraps the previous sfree call.
* Stop putting dsfs in existing scratch int arrays.Simon Tatham2023-04-20
| | | | | | | | | | | | | | | | | | | | | | | I'm going to work towards turning 'dsf' into an opaque type, so that I can improve its implementation without breaking clients. The first step is to deal manually with puzzles that currently reuse a single array of ints for multiple purposes, some of which are dsf and some are not. In divvy_rectangle_attempt, 'tmp' was used as an int array and later a dsf, and I've made a new 'tmpdsf' to be the latter. In Dominosa, solver->pc_scratch2 was sometimes a dsf, and now there's a new solver->dsf_scratch. In Map, parse_edge_list() needed a dsf internally and then never exported it; it expected to be passed an array of 2*w*h ints and used the second half as a dsf. Now it expects only w*h ints, and allocates its own dsf internally, freeing it again before returning. And in Tents, find_errors() was allocating a single block of 2*w*h ints and using the second half of it as a dsf, apparently just to save one malloc. Now we malloc and free the dsf separately.
* Remove an unnecessary extern function declaration.Simon Tatham2023-04-20
| | | | | | | unfinished/separate.c had its own declaration of divvy_rectangle(), duplicating the one in puzzles.h. Probably that was where the declaration originally lived, before I moved it out into the main header.
* Move obfuscator tests into obfusc.c.Simon Tatham2023-04-16
| | | | | | | | I just found these self-tests lying around in mines.c under an #ifdef that nobody ever enables. Let's put them somewhere more sensible! We already have a separate tool for working with the obfuscation system in a puzzle-independent way, and it seems reasonable to put them in there.
* Reference my just-published article about aperiodic tilings.Simon Tatham2023-04-10
| | | | | | | | | | | | | | | | | | | In commit 8d6647548f7d005 I added the Hats grid type to Loopy, and mentioned in the commit message that I was very pleased with the algorithm I came up with. In fact, I was so pleased with it that I've decided it deserves a proper public writeup. So I've spent the Easter weekend producing one: https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/aperiodic-tilings/ In this commit I adjust the header comments in both penrose.c and hat.c to refer to the article (replacing a previous comment in penrose.c to a much less polished page containing a copy of my jotting-grade personal notes that I sent James Harvey once). Also, added some code to hatgen.c to output Python hat descriptions in a similar style to hat-test, which I used to generate a couple of the more difficult diagrams in the new article, and didn't want to lose.
* Don't allow zero clues in PatternBen Harris2023-04-08
| | | | | | | | | | | | | | Some nonogram implementations allow zero clues so that a row or column with a single zero clue is equivalent to one with no clues, that is it has no black squares in it. Pattern, however, doesn't interpret them like this and treats a puzzle with a zero clue as insoluble, so it's not helpful to permit them. Permitting zero clues also confuses Pattern's memory allocation so that it can suffer a buffer overrun. As an example, before this commit a build with AddressSanitizer would report a buffer overrun with the description "1:0/0.0" because it tries to put two clues in a row that can have a maximum of one.
* Net: validate co-ordinates in decode_ui()Ben Harris2023-04-08
| | | | | | | | | | | | | | | | The offset and centre location should be within the grid. Otherwise the redraw code will suffer an assertion failure. This save file demonstrates the problem: SAVEFILE:41:Simon Tatham's Portable Puzzle Collection VERSION :1:1 GAME :3:Net PARAMS :4:5x5w CPARAMS :4:5x5w DESC :25:9893e85285bb72e6de5182741 UI :9:O0,0;C6,6 NSTATES :1:1 STATEPOS:1:1
* Add a game_state argument to decode_ui()Ben Harris2023-04-08
| | | | | | | | Some games would like a way to check that the parameters in the encoded UI string are consistent with the game parameters. Since this might depend on the current state of the game (this being what changed_state() is for), implement this by adding a game_state parameter to decode_ui(). Nothing currently uses it, though Guess usefully could.
* Make encode_ui() and decode_ui() optional in back-endsBen Harris2023-04-08
| | | | | | | | | | | | The majority of back-ends define encode_ui() to return NULL and decode_ui() to do nothing. This commit allows them to instead specify the relevant function pointers as NULL, in which case the mid-end won't try to call them. I'm planning to add a parameter to decode_ui(), and if I'm going to have to touch every back-end's version of decode_ui(), I may as well ensure that most of them never need to be touched again. And obviously encode_ui() should go the same way for symmetry.
* Net: assert that cx and cy are in range in compute_active()Ben Harris2023-04-08
| | | | | | | | | | | | | | | | | | | This avoids an out-of-range heap write shortly afterwards. An assertion failure is better than a buffer overrun, but still not ideal. Fixing the problem properly will require fairly wide-ranging changes, though. The bug can be demonstrated by loading this save file into a build with AddressSanitizer: SAVEFILE:41:Simon Tatham's Portable Puzzle Collection VERSION :1:1 GAME :3:Net PARAMS :4:5x5w CPARAMS :4:5x5w DESC :25:9893e85285bb72e6de5182741 UI :9:O0,0;C6,6 NSTATES :1:1 STATEPOS:1:1
* js: explicitly tell Emscripten which browsers to targetBen Harris2023-04-06
| | | | | | | | | | | | | | | Emscripten has settings indicating which browser versions it should build code for. These are now by default slightly newer than I'd been targeting with my hand-written JavaScript. They also don't include Firefox 48, which KaiOS 2.5 is based on. This commit adds CMake variables to set the minimum versions that we pass to Emscripten. They default to the earliest versions with WebAssembly support, except that Firefox 48 is also supported. I think the main consequence of this change is to stop Emscripten using sign-extension and mutable-globals in WebAssembly, which it's done by default since version 3.1.26.
* js: set -s ENVIRONMENT=web in EmscriptenBen Harris2023-04-06
| | | | | | Puzzles only runs in Web browsers, so there's no need to include support for Node or (for now at least) running in a Web worker. This removes about 5 kiB of code from the boilerplate JavaScript.
* Fall back to <math.h> if <tgmath.h> doesn't work.Simon Tatham2023-04-06
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This fixes a build failure introduced by commit 2e48ce132e011e8 yesterday. When I saw that commit I expected the most likely problem would be in the NestedVM build, which is currently the thing with the most most out-of-date C implementation. And indeed the NestedVM toolchain doesn't have <tgmath.h> - but much more surprisingly, our _Windows_ builds failed too, with a compile error inside <tgmath.h> itself! I haven't looked closely into the problem yet. Our Windows builds are done with clang, which comes with its own <tgmath.h> superseding the standard Windows one. So you'd _hope_ that clang could make sense of its own header! But perhaps the problem is that this is an unusual compile mode and hasn't been tested. My fix is to simply add a cmake check for <tgmath.h> - which doesn't just check the file's existence, it actually tries compiling a file that #includes it, so it will detect 'file exists but is mysteriously broken' just as easily as 'not there at all'. So this makes the builds start working again, precisely on Ben's theory of opportunistically using <tgmath.h> where possible and falling back to <math.h> otherwise. It looks ugly, though! I'm half tempted to make a new header file whose job is to include a standard set of system headers, just so that that nasty #ifdef doesn't have to sit at the top of almost all the source files. But for the moment this at least gets the build working again.
* Remove obsolete testbuild.c.Simon Tatham2023-04-06
| | | | | | | | | It was originally used for probing the available warning flags in the compiler, by adding them one by one and making sure this test file still compiled. But that whole mechanism was removed in commit 306fab356e357ef, and since then, testbuild.c has been unused. Belatedly throw it away.
* KaiOS: include extra copyright notices in manualBen Harris2023-04-06
| | | | | | | | | | | | | | | | The KaiOS build includes compiled versions of various Emscripten library files. These are generally under the MIT licence like Puzzles itself. The MIT licence requires that the licence, and the copyright notice, be "included in all copies or substantial portions of the Software." Since each KaiOS package includes the full manual, which already contains the licence for Puzzles itself, adding the copyright notices there seems like the best approach. I've done this by providing an additional input file that contains the licences for source files used by a current Emscripten build. More automation might be nice, but the set of copyright notices is unlikely to change very much. There are basically one for Emscripten, one for musl, and a few for odd bits of third-party code embedded in musl.
* Replace <math.h> with <tgmath.h> throughoutBen Harris2023-04-04
| | | | | | | | | | | | | | | C89 provided only double-precision mathematical functions (sin() etc), and so despite using single-precision elsewhere, those are what Puzzles has traditionally used. C99 introduced single-precision equivalents (sinf() etc), and I hope it's been long enough that we can safely use them. Maybe they'll even be faster. Rather than directly use the single-precision functions, though, we use the magic macros from <tgmath.h> that automatically choose the precision of mathematical functions based on their arguments. This has the advantage that we only need to change which header we include, and thus that we can switch back again if some platform has trouble with the new header.
* js: stop using EXTRA_EXPORTED_RUNTIME_METHODSBen Harris2023-04-03
| | | | | Current Emscripten has deprecated it in favour of EXPORTED_RUNTIME_METHODS, and using that avoids generating warnings.
* js: use the "load" event for loading save filesBen Harris2023-04-03
| | | | | | | | | | | | | | | This is in place of the "loadend" event. In Chromium, (and in the specification), "loadend" is triggered not only when the file is loaded but also when loading fails. Obviously when loading fails we don't want to try to parse the (nonexistent) resulting file. Using the "load" event works better, since it's only fired on success, and we can also have an "error" handler to report problems with loading files, albeit with no detail at all. This doesn't seem to make any difference in Firefox, which in my testing fires "load" and "loadend" on success and nothing at all on failure.
* js: Load save files into the C side incrementallyBen Harris2023-04-03
| | | | | | | | | | | | | | | | | | | | | | | | | Before this commit, JavaScript Puzzles loaded a save file by pushing the entire file onto the Emscripten stack and then reading it from there. This worked tolerably for typical save files, but Emscripten's stack defaults to only having 64 kiB of space. That meant that trying to load something that wasn't a real save file tended to cause a stack overflow. I expect that at least some real save files would suffer from the same problem. The stack overflow would generally cause a JavaScript exception and then leave the stack pointer outside the stack, so that any future attempt to call into C would fail as well. To fix this, arrange that the C function for reading data from the save file calls out to JavaScript. The JavaScript can then copy just the requested data into the caller's buffer. We can't pass a JavaScript function pointer to C, but since only one file can be loaded at a time, we can just have a global variable that's the current loading callback. There might still be a problem if you try to load a stupendously large file, since I think FileReader.readAsArrayBuffer() reads the whole file into the browser's RAM. It works on my laptop with files up to a few hundred megabytes, though.
* js: load games using FileReader.readAsArrayBuffer()Ben Harris2023-04-02
| | | | | | | | | | | | | | | | Using .readAsText() meant that trying to load a non-text file (for instance something that's not a save file at all) would generate an "RuntimeError: index out of bounds". This would then leave the Emscripten runtime in a broken state. It might even be possible for a real save file not to be valid UTF-8, for instance if it came from a platform that used a different character encoding for random seeds. There's still a problem with opening very large files, apparently because Emscripten tries to stuff the entire file onto the C stack. That will probably have to be fixed by properly exposing the incremental file-loading API to JavaScript.
* hat-test: more scaling and clipping options.Simon Tatham2023-04-02
| | | | | | | | | | | | | | | | This adds the ability to turn off hat-test's normal scaling of the bounding box to fit on an A4 page, which I intended for printing test patches (but never actually found a need to print one). The --unscaled mode seems more useful if you're planning to turn the output into an image, e.g. to use as a desktop background. Also added --clip, which generates a rectangle completely covered in hats (i.e. shows any hat that overlaps the output rectangle at all), as opposed to the normal mode which omits any hat that doesn't fit _entirely_ in the output rectangle (more similar to what Loopy wants). Actually generating a desktop background by this method is still a bit fiddly to get right, but it's better than before.
* hat-test: fix array underrun.Simon Tatham2023-04-02
| | | | | Having _checked_ whether a hat index in my four-colouring maps was -1, I then went ahead and used it as an array index anyway, oops!
* Remove penrose_count_tiles().Simon Tatham2023-04-02
| | | | | Nothing uses it, and that's not surprising, because if anything had, we'd have noticed that it never actually got written!
* Move other test main()s out of library source files.Simon Tatham2023-04-02
| | | | | | | | | | | | | | | | | | | | | | | | | | Having stated the principle in the previous commit, I should apply it consistently. A source file linked into the Puzzles library of common support code should not also define a main() under ifdef. This commit only goes as far as the _library_ support modules. It would be a much bigger job to do the same for all the actual _puzzles_ that have test main()s or standalone-solver main()s. And it's not necessary, because modifying one of those source files only triggers a rebuild of _one_ puzzle, not absolutely everything. (Not to mention that it's quite likely the puzzle and the test main() will need to be modified in conjunction anyway.) As in the previous commit, this has required exposing a few internal API functions as global, and maybe editing them a bit. In particular, the one-shot internal function that divvy_rectangle() loops on until it succeeds is now exposed as divvy_rectangle_attempt(), which means the test program doesn't have to condition a failure counter into the real function. I've thrown away penrose-vector-test completely, because that didn't look like a test program with any ongoing use at all - it was surely vestigial, while James was getting the vector representation up and running in the first place.
* Move hat-test into its own source file.Simon Tatham2023-04-02
| | | | | | | | | | | | | | | I noticed while hacking on hat-test recently that it's quite awkward to be compiling a test main() program that lives in a source file also built into the Puzzles support library, because every modification to main() also triggers a rebuild of the library, and thence of all the actual puzzles. So it's better if such a test main() has its own source file. In order to make hat-test work standalone, I've had to move a lot of hat.c's internal declarations out into a second header file. This also means making a bunch of internal functions global, which means they're also in the namespace of programs other than hat-test, which means in turn that they should have names with less implicit context.
* Magnets: add a check that magnets don't wrap between linesBen Harris2023-04-01
| | | | | | | | | | | | There was nothing in Magnet's description validation to prevent there being the left end of a magnet at the right end of a row and the right end of a magnet at the left end of the row below. Indeed as far as I can such a game (e.g. 3x3:..2,2..,...,1.1,TLRB*LRLR) plays entirely correctly except that one magnet is discontinuous. While this worked, it was entirely an artefact of the particular memory layout that Magnets uses and shouldn't have been allowed, so I've added an additional validation rule to stop it.
* Correct a range check in Magnets' layout verificationBen Harris2023-03-31
| | | | | | Squares in the grid are numbered from 0, so the upper limit check needs to use "<=" rather than "<". Without this, invalid descriptions can cause a read overrun off the end of the board.
* hat-test: option to generate four-coloured hat tilings.Simon Tatham2023-03-31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit is purely frivolous even by Puzzles standards, in that it's totally unrelated to any actual puzzle. But I know at least one person has already used the 'hat-test' tool in this code base to generate a patch of hat tiling for decorative purposes, so it's useful in its own right. Also, now that I've worked out _how_ to do this, it's a shame not to keep the code. Of course, any tiling of the plane _can_ be four-coloured, just by the Four Colour Theorem. But for a tiling with structure it's nicer if the colouring is related to the structure in some way. And there's a reasonably nice explicit construction that does just that: the paper introducing the tiling observes that if each reflected hat is fused with a particular one of its neighbours, the resulting tiling is graph-theoretically equivalent to a tiling of the plane by hexagons. And _that_ tiling can be three-coloured, in a unique way up to colour choices. This induces a four-colouring of the hat tiling in which the reflected hats have a colour to themselves, and everything else is coloured the same as its corresponding hexagon in the three-colouring. Actually implementing this turns out not to be too difficult using my coordinate system. I hand-wrote tables giving a patch of colouring for each of the four kitemaps; then, whenever two kitemaps meet, you can determine how the colours map to each other by looking at the overlapping tiles. So I can have hat-test work out the colour of each tile as it goes. So hat-test now supports a '--fourcolour' option to apply this colouring to the output tiling.
* Require a grid description for hats gridBen Harris2023-03-31
| | | | | Without this, you can cause a null-pointer dereference by passing Loopy a game description with no grid description, like "10x10t16:".
* hat-test: allow choosing a random number seed.Simon Tatham2023-03-30
| | | | | | | The default one is always the same, because the main purpose of this tool is debugging. But one person has already wanted to use it for actually generating a tiling patch for another use, so let's make it easier to vary the randomness!
* Hats: choose the tiling's starting hat more uniformly.Simon Tatham2023-03-30
| | | | | | | This fills in the missing piece of commit 6f75879e9fe7cb5, which was trying to make the output patches of tiling as uniformly random as possible across the whole space of possible ones. I fixed every _intermediate_ step in the algorithm, but forgot the starting one!
* Hats: factor out the parent-choosing system.Simon Tatham2023-03-30
| | | | NFC, but I'm about to want to use it again elsewhere.
* Loopy: widen clip rectangle for redrawing clues.Simon Tatham2023-03-28
| | | | | | | | The new Hats tiling generates a lot of clues that are 2-digit numbers. At large puzzle sizes, the previous clip rectangle didn't quite include the ends of such a number, meaning that if the number had to be redrawn in red to highlight an error, the leftmost and rightmost parts of the text would remain black.
* hat-test: alternative data output mode to write Python.Simon Tatham2023-03-28
| | | | | | This mode emits a sequence of calls to an imaginary Python function. Should be useful to anyone wanting to post-process the tiling in any way.
* hat-test: allow specifying tiling size on the command line.Simon Tatham2023-03-28
| | | | | I'm tired of recompiling every time I want a different size of test patch.
* Hats tiling: make hat-test draw each hat in one go.Simon Tatham2023-03-28
| | | | | | | | | | | | | By introducing a second callback between the client of hat.c and the maybe_report_hat function, I enable the test main() to provide a different version of that callback, so that instead of enumerating each kite, it can directly generate a Postscript path per actual hat. This should make it more useful to people wanting to generate hat patterns for any other purpose. The internal callback gets more details than the external one; in particular, it receives a HatCoords, so that it can colour hats based on their position in the hierarchical structure.
* Hats tiling: more uniform parent selection.Simon Tatham2023-03-28
| | | | | | | | | | | | | This tweak improves the uniformity of the generated patches of hat tiling, by selecting from (the closest 32-bit approximation I can get to) the limiting probability distribution of finite patches in the whole plane. This shouldn't invalidate any grid description that contains enough coordinates to uniquely specify a piece of tiling - in particular, any generated by the game itself. But if anyone's been brave enough to hand-type a grid description in the last two days and left off some of the coordinates, then those might be invalidated.
* Fix references to the renamed 'auxiliary' directory.Simon Tatham2023-03-27
| | | | | | I renamed it in a hurry this morning after the first report of a git error message on Windows. Now I realise that several source files referred to the old name, and also need fixing.
* Rename the 'aux' subdirectory to avoid Windows restrictions.Simon Tatham2023-03-27
| | | | | James Harvey points out that Windows still forbids calling a file 'aux' in any context. Even a directory. Gaaah.
* Loopy / grid.c: new grid type, 'Hats'.Simon Tatham2023-03-26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The big mathematical news this month is that a polygon has been discovered that will tile the plane but only aperiodically. Penrose tiles achieve this with two tile types; it's been an open question for decades whether you could do it with only one tile. Now someone has announced the discovery of such a thing, so _obviously_ this mathematically exciting tiling ought to be one of the Loopy grid options! The polygon, named a 'hat' by its discoverers, consists of the union of eight cells of the 'Kites' periodic tiling that Loopy already implements. So all the vertex coordinates of the whole tiling are vertices of the Kites grid, which makes handling the coordinates in an exact manner a lot easier than Penrose tilings. What's _harder_ than Penrose tilings is that, although this tiling can be generated by a vaguely similar system of recursive expansion, the expansion is geometrically distorting, which means you can't easily figure out which tiles can be discarded early to save CPU. Instead I've come up with a completely different system for generating a patch of tiling, by using a hierarchical coordinate system to track a location within many levels of the expansion process without ever simulating the process as a whole. I'm really quite pleased with that technique, and am tempted to try switching the Penrose generator over to it too - except that we'd have to keep the old generator around to stop old game ids being invalidated, and also, I think it would be slightly trickier without an underlying fixed grid and without overlaps in the tile expansion system. However, before coming up with that, I got most of the way through implementing the more obvious system of actually doing the expansions. The result worked, but was very slow (because I changed approach rather than try to implement tree-pruning under distortion). But the code was reusable for two other useful purposes: it generated the lookup tables needed for the production code, and it also generated a lot of useful diagrams. So I've committed it anyway as a supporting program, in a new 'aux' source subdirectory, and in aux/doc is a writeup of the coordinate system's concepts, with all those diagrams. (That's the kind of thing I'd normally put in a huge comment at the top of the file, but doing all those diagrams in ASCII art would be beyond miserable.) From a gameplay perspective: the hat polygon has 13 edges, but one of them has a vertex of the Kites tiling in the middle, and sometimes two other tile boundaries meet at that vertex. I've chosen to represent every hat as having degree 14 for Loopy purposes, because if you only included that extra vertex when it was needed, then people would be forever having to check whether this was a 13-hat or a 14-hat and it would be nightmarish to play. Even so, there's a lot of clicking involved to turn all those fiddly individual edges on or off. This grid is noticeably nicer to play in 'autofollow' mode, by setting LOOPY_AUTOFOLLOW in the environment to either 'fixed' or 'adaptive'. I'm tempted to make 'fixed' the default, except that I think it would confuse players of ordinary square Loopy!
* KaiOS: be more careful detecting the presence of KaiAdsBen Harris2023-03-22
| | | | | | | | | Now that we catch JavaScript errors and report them to the user, I could tell that the way we were detecting the presence of getKaiAd() didn't work because it caused an alert every time a build without KaiAds was started. Detecting the presence of a global variable is slightly tricky, but explicitly looking for it on "window" works and isn't very ugly.
* Turn on PUZZLES_SHOW_CURSOR on KaiOSBen Harris2023-03-22
| | | | | | | | Most KaiOS devices are primarily keyboard-based, so this seems like a reasonable approach. I've also switched to specifying boolean values as JSON booleans because that works now.
* Treat environment variable values beginning with "T" as trueBen Harris2023-03-22
| | | | | | So a value is true iff it begins with 'T', 't', 'Y', or 'y'. This is mostly so that naively converting JSON "true" to a string will work properly, but it should keep LISPers happy too.
* Add an environment variable to control initial cursor visibilityBen Harris2023-03-22
| | | | | | | | | | | | | If you define PUZZLES_INITIAL_CURSOR=y, puzzles that have a keyboard cursor will default to making it visible rather than invisible at the start of a new game. Behaviour is otherwise the same, so mouse actions will cause the cursor to vanish and keyboard actions will cause it to appear. It's just the default that has changed. The purpose of this is for use on devices and platforms where the primary or only means of interaction is keyboard-based. In those cases, starting with the keyboard cursor invisible is weird and a bit confusing.
* New shared function, getenv_bool()Ben Harris2023-03-22
| | | | | | | | | | | | | This provides a standard way to get a boolean from an environment variable. It treats the variable as true iff its value begins with 'y' or 'Y', like most of the current implementations. The function takes a default value which it returns if the environment variable is undefined. This replaces the various ad-hoc tests of environment variable scattered around and mostly doesn't change their behaviour. The exceptions are TOWERS_2D in Towers and DEBUG_PUZZLES in the Windows front end. Both of those were treated as true if they were defined at all, but now follow the same rules as other boolean environment variables.
* Galaxies: skew grid generation in favour of wiggliness.Simon Tatham2023-03-12
| | | | | | | | | | | | | | | | | | | Ben complained yesterday that Galaxies had a nasty habit of generating games whose solution was a boring set of rectangles. Now that even at Normal mode the solver is better at coping with wiggly tentacled regions, it seems like a good moment to fix that. This change arranges that when we initially generate a filled grid, we try ten times, and pick the wiggliest of the grids we found. This doesn't make any boring rectangle-filled grid _impossible_ - players will still have to stay on their toes, and can't rely 100% on at least a certain number of wiggles existing - but it makes the interesting grids a lot more likely to come up. This skew happens before checking solubility. So it doesn't increase grid generation time by a factor of ten (as it would if we generated ten _soluble_ grids and picked the wiggliest). It's still a speed drop, of course, but a more modest one than that.
* Galaxies: remove 'solver_recurse_depth' in live use.Simon Tatham2023-03-12
| | | | | | | | | | | | | | | | | | | It's horrible to have static mutable state in the live puzzle game. What if some downstream wanted to run the system in multiple threads? For purposes of limiting the recursion depth, we now pass an 'int depth' argument to each call to solver_state_inner(). So in the normal build of the actual puzzle, the static variable isn't needed at all. We only include it in binaries that are going to want to use it for printing indented diagnostics: the CLI solver program, and the live puzzle only if DEBUGGING is defined. The rest of the time, it's absent. A side effect of this change is that when the recursion code makes a guess at a particular tile, the message about that is now indented to the _outer_ level instead of the inner one, because the previous 'depth++' and 'depth--' statements wrapped the whole loop rather than just the recursive call to the solver inside. This makes recursive solving much easier to follow!
* Galaxies: add some higher Unreasonable presets.Simon Tatham2023-03-12
| | | | 10x10 and 15x15 Unreasonable are now feasible, so why not include them?
* Galaxies: remove the 'maxtries' system.Simon Tatham2023-03-12
| | | | | | | | | | | | | | | | | | Most games in this collection don't have one. If you ask them for a hard puzzle, they'll just keep looping round until they actually manage to deliver one. We try to arrange that the standard presets don't take too long to generate, but if the user turns up the game size _and_ uses an expensive difficulty level, our view is that that's up to them. After fixing the bug from the previous commit in which the Galaxies recursion depth limit was not actually doing anything, even 15x15 Unreasonable now generates happily in under a second. So I don't see any reason why Galaxies should be an exception. Hence, now if you ask Galaxies for an Unreasonable puzzle, you _will_ get a puzzle that it grades as Unreasonable, even if that takes a long time to generate.