32 Commits

Author SHA1 Message Date
5f5b284c0b Use C99 bool within source modules.
This is the main bulk of this boolification work, but although it's
making the largest actual change, it should also be the least
disruptive to anyone interacting with this code base downstream of me,
because it doesn't modify any interface between modules: all the
inter-module APIs were updated one by one in the previous commits.
This just cleans up the code within each individual source file to use
bool in place of int where I think that makes things clearer.
2018-11-13 21:48:24 +00:00
a550ea0a47 Replace TRUE/FALSE with C99 true/false throughout.
This commit removes the old #defines of TRUE and FALSE from puzzles.h,
and does a mechanical search-and-replace throughout the code to
replace them with the C99 standard lowercase spellings.
2018-11-13 21:48:24 +00:00
a76d269cf2 Adopt C99 bool in the game backend API.
encode_params, validate_params and new_desc now take a bool parameter;
fetch_preset, can_format_as_text_now and timing_state all return bool;
and the data fields is_timed, wants_statusbar and can_* are all bool.
All of those were previously typed as int, but semantically boolean.

This commit changes the API declarations in puzzles.h, updates all the
games to match (including the unfinisheds), and updates the developer
docs as well.
2018-11-13 21:34:42 +00:00
60a929a250 Add a request_keys() function with a midend wrapper.
This function gives the front end a way to find out what keys the back
end requires; and as such it is mostly useful for ports without a
keyboard. It is based on changes originally found in Chris Boyle's
Android port, though some modifications were needed to make it more
flexible.
2018-04-22 17:04:50 +01:00
b3243d7504 Return error messages as 'const char *', not 'char *'.
They're never dynamically allocated, and are almost always string
literals, so const is more appropriate.
2017-10-01 16:34:41 +01:00
de67801b0f Use a proper union in struct config_item.
This allows me to use different types for the mutable, dynamically
allocated string value in a C_STRING control and the fixed constant
list of option names in a C_CHOICES.
2017-10-01 16:34:41 +01:00
eeb2db283d New name UI_UPDATE for interpret_move's return "".
Now midend.c directly tests the returned pointer for equality to this
value, instead of checking whether it's the empty string.

A minor effect of this is that games may now return a dynamically
allocated empty string from interpret_move() and treat it as just
another legal move description. But I don't expect anyone to be
perverse enough to actually do that! The main purpose is that it
avoids returning a string literal from a function whose return type is
a pointer to _non-const_ char, i.e. we are now one step closer to
being able to make this code base clean under -Wwrite-strings.
2017-10-01 15:18:14 +01:00
a7dc17c425 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.
2017-04-26 21:51:23 +01:00
0b348877e2 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).
2016-12-16 18:33:10 +00:00
b31155b732 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).
2016-04-28 20:42:23 +01:00
adc54741f0 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.)
2016-02-24 19:36:41 +00:00
c5500926bf 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
it!
2016-02-24 19:31:54 +00:00
e22a9c8396 build fix 2015-10-03 17:39:22 +01:00
ea8da331e3 Cancel dragging in Pearl by pressing Escape or Backspace. 2015-10-03 16:59:10 +01:00
bf8ff09a84 Change Pearl's cursor logic.
Keyboard dragging while holding Control now moves the cursor to the
target square. Shift-Control-arrowkey performs the previous behavior
of Control-arrowkey.
2015-10-03 16:59:04 +01:00
d64a79e2b8 Refactor Pearl's mark_in_direction, and invert a parameter. 2015-10-03 16:59:04 +01:00
8e35087e09 Refactor modifier handling in Pearl's cursor code. 2015-10-03 16:59:04 +01:00
7543082f26 Add game_text_format to Pearl. 2015-10-03 16:58:18 +01:00
4fb9776d83 Fix a typo in the comments of Pearl.
Each stone can have 2 lines radiating from its centre, not 3.
2015-10-03 16:57:44 +01:00
251b21c418 Giant const patch of doom: add a 'const' to every parameter in every
puzzle backend function which ought to have it, and propagate those
consts through to per-puzzle subroutines as needed.

I've recently had to do that to a few specific parameters which were
being misused by particular puzzles (r9657, r9830), which suggests
that it's probably a good idea to do the whole lot pre-emptively
before the next such problem shows up.

[originally from svn r9832]
[r9657 == 3b250baa02a7332510685948bf17576c397b8ceb]
[r9830 == 0b93de904a98f119b1a95d3a53029f1ed4bfb9b3]
2013-04-13 10:37:32 +00:00
0b93de904a Add 'const' to the game_params arguments in validate_desc and
new_desc. Oddities in the 'make test' output brought to my attention
that a few puzzles have been modifying their input game_params for
various reasons; they shouldn't do that, because that's the
game_params held permanently by the midend and it will affect
subsequent game generations if they modify it. So now those arguments
are const, and all the games which previously modified their
game_params now take a copy and modify that instead.

[originally from svn r9830]
2013-04-12 17:11:49 +00:00
8a7dad6d2d Bring Pearl's game-completion handling in line with my usual practice:
the 'completed' flag is not reset if you make a new move transforming
a solved game into an unsolved state, so the game won't flash again if
you manually erase and redraw a line segment (though it still will if
you undo and redo past the first solved state in the undo history).

[originally from svn r9750]
2013-01-19 18:56:06 +00:00
3b250baa02 New rule: interpret_move() is passed a pointer to the game_drawstate
basically just so that it can divide mouse coordinates by the tile
size, but is definitely not expected to _write_ to it, and it hadn't
previously occurred to me that anyone might try. Therefore,
interpret_move() now gets a pointer to a _const_ game_drawstate
instead of a writable one.

All existing puzzles cope fine with this API change (as long as the
new const qualifier is also added to a couple of subfunctions to which
interpret_move delegates work), except for the just-committed Undead,
which somehow had ds->ascii and ui->ascii the wrong way round but is
otherwise unproblematic.

[originally from svn r9657]
2012-09-09 18:40:12 +00:00
ec732a4f4e Add a difficulty exception to prevent Pearl spinning forever when
asked to generate a 5x5 Tricky puzzle. (Debian bug #667963)

[originally from svn r9454]
2012-04-08 13:45:10 +00:00
faabfe3b62 Patch from Jonas Koelker to add keyboard control support to Pearl.
[originally from svn r9411]
2012-02-19 10:15:59 +00:00
f38adf6394 Tweak a conditional expression in pearl.c to work around a display bug
in the Java build - which turns out to be a JVM bug in OpenJDK 6,
causing the NestedVM rendition of the expression (i==1?3:4) to be
mis-JITed. OpenJDK 7 appears not to do that any more, but this
equivalent (for these purposes) rephrasing should perturb the code
just enough to dodge the problem.

[originally from svn r9408]
2012-02-17 19:07:31 +00:00
21629d7e44 Fix one-character typo in r9405 which was breaking right-clicks.
[originally from svn r9406]
[r9405 == 0c13787c2a17adc891f8e47c06b259f80bc8251a]
2012-02-13 21:10:47 +00:00
0c13787c2a David Nickerson reports odd behaviour involving a drag start point
persisting between separate mouse actions. Revamp all uses of the
ndragcoords field in an attempt to stamp that out: we now distinguish
between active drags (>0), a valid click but no drag yet (0), and a
totally invalid situation in which all mouse activity will be ignored
until the next fresh attempt (-1).

[originally from svn r9405]
2012-02-08 23:31:58 +00:00
340c300c1d David Nickerson reports that it's possible to lay a line over a 'no
line here' cross mark by dragging, and furthermore, that doing so puts
that grid edge into a stuck state that no UI action short of undo can
get it back out of. Fix drags to stop at crosses, and fix execute_move
to fault any move string that nonetheless somehow managed to try to
set a line over a cross without explicitly tagging it 'R'.

[originally from svn r9400]
2012-02-02 07:18:14 +00:00
f3168895c8 Move a debug statement at the end of new_clues from the caller (just
after return) to the callee (just before). Might print something
useful in the soak-test context (where that debug statement will now
be printed and previously wasn't), but the main aim is to remove the
variable 'ngen' at the main call site, which triggered a set-but-not-
used warning if the debug statement that printed it was compiled out.

[originally from svn r9392]
2012-01-31 08:32:26 +00:00
e406092a0e Tweak right-click processing to be less finicky.
[originally from svn r9381]
2012-01-22 15:12:56 +00:00
b16eece9fc New puzzle! Or rather, new-ish, because this one has been lying around
in the 'unfinished' directory for a while, and has now been finished
up thanks to James Harvey putting in some effort and galvanising me to
put in the rest. This is 'Pearl', an implementation of Nikoli's 'Masyu'.

The code in Loopy that generates a random loop along grid edges to use
as the puzzle solution has been abstracted out into loopgen.[ch] so
that Pearl can use it for its puzzle solutions too. I've also
introduced a new utility module called 'tdq' (for 'to-do queue').

[originally from svn r9379]
2012-01-22 14:14:26 +00:00