46 Commits

Author SHA1 Message Date
78bc9ea7f7 Add method for frontends to query the backend's cursor location.
The Rockbox frontend allows games to be displayed in a "zoomed-in"
state targets with small displays. Currently we use a modal interface
-- a "viewing" mode in which the cursor keys are used to pan around
the rendered bitmap; and an "interaction" mode that actually sends
keys to the game.

This commit adds a midend_get_cursor_location() function to allow the
frontend to retrieve the backend's cursor location or other "region of
interest" -- such as the player location in Cube or Inertia.

With this information, the Rockbox frontend can now intelligently
follow the cursor around in the zoomed-in state, eliminating the need
for a modal interface.
2020-12-07 19:40:06 +00:00
66b9e8c7de Unequal: fill in the latin.c validator function.
This too seems to have made no difference: each of the commands
    unequal --generate 1000 6dr#12345
    unequal --generate 1000 6adr#12345
delivers the same list of puzzles before and after the fix.
2020-05-23 10:25:38 +01:00
f21d3e4c74 latin.c: call a user-provided validator function. [NFC]
I've only just realised that there's a false-positive bug in the
latin.c solver framework.

It's designed to solve puzzles in which the solution is a latin square
but with some additional constraints provided by the individual
puzzle, and so during solving, it runs a mixture of its own standard
deduction functions that apply to any latin-square puzzle and extra
functions provided by the client puzzle to do deductions based on the
extra clues or constraints.

But what happens if the _last_ move in the solving process is
performed by one of the latin.c built-in methods, and it causes a
violation of the client puzzle's extra constraints? Nothing will ever
notice, and so the solver will report that the puzzle has a solution
when it actually has none.

An example is the Group game id 12i:m12b9a1zd9i6d10c3y2l11q4r . This
was reported by 'groupsolver -g' as being ambiguous. But if you look
at the two 'solutions' reported in the verbose diagnostics, one of
them is arrant nonsense: it has no identity element at all, and
therefore, it fails associativity all over the place. Actually that
puzzle _does_ have a unique solution.

This bug has been around for ages, and nobody has reported a problem.
For recursive solving, that's not much of a surprise, because it would
cause a spurious accusation of ambiguity, so that at generation time
some valid puzzles would be wrongly discarded, and you'd never see
them. But at non-recursive levels, I can't see a reason why this bug
_couldn't_ have led one of the games to present an actually impossible
puzzle believing it to be soluble.

Possibly this never came up because the other clients of latin.c are
more forgiving of this error in some way. For example, they might all
be very likely to use their extra clues early in the solving process,
so that the requirements are already baked in by the time the final
grid square is filled. I don't know!

Anyway. The fix is to introduce last-minute client-side validation:
whenever the centralised latin_solver thinks it's come up with a
filled grid, it should present it to a puzzle-specific validator
function and check that it's _really_ a legal solution.

This commit does the plumbing for all of that: it introduces the new
validator function as one of the many parameters to latin_solver, and
arranges to call it in an appropriate way during the solving process.
But all the per-puzzle validation functions are empty, for the moment.
2020-05-23 09:08:08 +01:00
db3b531e2c Add missing 'static' to game-internal declarations.
Another thing I spotted while trawling the whole source base was that
a couple of games had omitted 'static' on a lot of their internal
functions. Checking with nm, there turned out to be quite a few more
than I'd spotted by eye, so this should fix them all.

Also added one missing 'const', on the lookup table nbits[] in Tracks.
2018-11-13 22:06:19 +00:00
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
a1663d6650 C89 build fixes.
Recent changes introduced a couple of non-C89-compatible mixed
declarations and code.
2018-04-25 19:24:06 +01:00
441b11b310 Make static keyword come first everywhere.
I somehow missed these instances as well. Oh well.
2018-04-25 06:48:57 +01: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
38ea1599fe Unequal: run check_complete() after a hint move.
A user sent in the game id
  7:0,0L,0,0,0L,0L,1,0U,0U,0D,0UD,0,0,7,0,0D,0,0D,0,0,0,0,0,0,0,0,0,0D,0,0,3,0,0U,0,0,0,0,2,6,0,0U,0,0,0,7,2,0,0U,5L,
starting from which, one press of 'h' will fill in a 2 in the top left
corner and possibilities 345 to its right; if you then fill in 5 there
and press 'h' again, the hint system fills in the whole of an apparent
solution which isn't the one a proper use of the Solve feature would
give you - except that it's not actually a second solution, because
one < clue on the top row is violated. Without this fix, that < failed
to light up red, making the puzzle look ambiguous if you're not paying
enough attention to spot it.
2017-10-20 00:33:54 +01:00
a58c1b216b Make the code base clean under -Wwrite-strings.
I've also added that warning option and -Werror to the build script,
so that I'll find out if I break this property in future.
2017-10-01 16:35:40 +01:00
3276376d1b Assorted char * -> const char * API changes.
I went through all the char * parameters and return values I could see
in puzzles.h by eye and spotted ones that surely ought to have been
const all along.
2017-10-01 16:35:00 +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
cf6e4e272c 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

  4:0,0,0,0,0,0L,0,0,0R,0U,0,0L,0,0,,3,
  4:0,0,0,0,0,0L,0,0,0R,0U,0,0L,0,0,0,3,

would both be accepted, and would be decoded into the same game, even
though the former should have failed syntax validation. Now it does.
2016-12-11 09:19:30 +00:00
6179e8df56 Allow marking of clues as exhausted in Unequal. 2015-10-03 17:12:20 +01:00
dc688b1f23 Unequal: stop ignoring keys 'h' and 'm' while cursor active.
At least, so long as 'h' and 'm' are not "numbers".
2015-10-03 16:58:11 +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
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
73daff3937 Changed my mind about midend_is_solved: I've now reprototyped it as
midend_status(), and given it three return codes for win, (permanent)
loss and game-still-in-play. Depending on what the front end wants to
use it for, it may find any or all of these three states worth
distinguishing from each other.

(I suppose a further enhancement might be to add _non_-permanent loss
as a fourth distinct status, to describe situations in which you can't
play further without pressing Undo but doing so is not completely
pointless. That might reasonably include dead-end situations in Same
Game and Pegs, and blown-self-up situations in Mines and Inertia.
However, I haven't done this at present.)

[originally from svn r9179]
2011-06-19 13:43:35 +00:00
8dcdb33b77 Pass background colour as a parameter to draw_gts and draw_adjs, so
that we can pass -1 in calls from game_print(). Fixes a printing bug
in which all the adjs and gts were overlaid with giant black
rectangles! (Because COL_BACKGROUND doesn't mean the same thing in
that context.)

[originally from svn r9175]
2011-05-22 07:07:47 +00:00
2efc77d2fd Fix warnings generated by gcc 4.6.0 about variables set but not
thereafter read. Most of these changes are just removal of pointless
stuff or trivial reorganisations; one change is actually substantive,
and fixes a bug in Keen's clue selection (the variable 'bad' was
unreferenced not because I shouldn't have set it, but because I
_should_ have referenced it!).

[originally from svn r9164]
2011-05-04 18:22:14 +00:00
980880be1f Add a function to every game backend which indicates whether a game
state is in a solved position, and a midend function wrapping it.

(Or, at least, a situation in which further play is pointless. The
point is, given that game state, would it be a good idea for a front
end that does that sort of thing to proactively provide the option to
start a fresh game?)

[originally from svn r9140]
2011-04-02 16:19:12 +00:00
8589cb3a0c Patch from Mark Wooding to add antialiasing-safety in repeated
redrawing of inequality signs in Unequal (which are redrawn when
they change colour).

[originally from svn r8964]
2010-05-29 15:43:50 +00:00
50b6e0d708 Chris Boyle reports an off-by-two error ('a Qui-Gon Jinx' :-) in
difficulty selection in Unequal's solver. I suspect I missed this
when I refactored latin.c and its callers.

[originally from svn r8906]
2010-03-21 14:30:49 +00:00
f55dc67f43 Fix from James H: the shared code between drawing and printing
should use state->adjacent rather than ds->adjacent, because the
latter won't be initialised in printing mode.

[originally from svn r8852]
2010-01-18 21:23:27 +00:00
ed4b163b69 A user asked for the < signs in Unequal to be bolder.
[originally from svn r8808]
2010-01-05 18:26:55 +00:00
b629e34beb Fix bug causing array overrun. Only seemed to be showing a symptom
on Windows, presumably because the data after the array was harmless
elsewhere.

[originally from svn r8798]
2009-12-27 19:18:22 +00:00
a79ab34941 Normalise Unequal (and latin.c) so that solver diagnostics start
their coordinate from 1 rather than 0, for consistency with Solo.
(My geek instincts would rather work from 0, but I've generally
found that puzzle users sending me email tend to prefer 1.)

[originally from svn r8795]
2009-12-27 10:01:20 +00:00
189f833980 Refactor latin.c to make it easier to reuse. Instead of client
programs having to clone the latin_solver() function and insert
their own extra deduction routines, they can now just _call_
latin_solver with enough parameters to let it fit its own deductions
into their difficulty framework and call a set of provided function
pointers to do user deductions. Modified Unequal to work in the new
world, of course.

[originally from svn r8791]
2009-12-27 10:01:10 +00:00
b9c22e5cac New mode for Unequal, from James H. In this mode, called 'Adjacent',
the < and > clues are replaced by bars separating every pair of
squares whose contents differ by exactly 1. Unlike standard Unequal,
which presents only a subset of the available clues, in Adjacent the
clues are _all_ present, so you can deduce from the absence of a bar
that the two numbers it would separate are _not_ consecutive.

[originally from svn r8790]
2009-12-27 10:01:09 +00:00
2bdabe31cf Jonas Koelker points out that the backspace key didn't work in GTK
Guess, because Guess expected ^H whereas GTK generated ^?. Other
puzzles that use Backspace do it by being prepared to see either,
which seems wasteful. Now the midend normalises both into ^H, so
front ends can generate whichever they like while puzzles can
safely just look for ^H.

[originally from svn r8786]
2009-12-20 10:01:57 +00:00
4d79c71517 Reorder if statements in Unequal's interpret_move() so that presses
of 'h' and 'm' are treated as digits if a square is selected, and
only treated as special commands otherwise. This renders very large
games (just about) playable.

Idea from Ben Hutchings's collection of Debian patches, although I
had to redo his (trivial) patch myself since the code has changed
recently.

(Addendum after committing: hmm, I see Jacob already applied the
original version of the patch a while back. Looks as if the recent
keyboard control change reintroduced the problem. Still, re-fixed
now.)

[originally from svn r8433]
2009-01-26 22:28:17 +00:00
4a202808ee Patch from James H which adds keyboard cursor support to Unequal,
and also updates the docs for both that and the Mines cursor support
in r8402.

[originally from svn r8408]
[r8402 == f20847354cb6335fd349204f16021a72e2956cce]
2009-01-12 20:23:56 +00:00
808495cb41 Apply "103_fix-unequal-digit-h.diff" from the Debian package:
Unequal 18x18 or above was unplayable due to a clash with the undocumented
"H" (hint) key. Resolve the clash by making the hint function only fire
when no square is selected.

[originally from svn r8200]
2008-10-05 12:22:37 +00:00
a7431c0b7c New infrastructure feature. Games are now permitted to be
_conditionally_ able to format the current puzzle as text to be sent
to the clipboard. For instance, if a game were to support playing on
a square grid and on other kinds of grid such as hexagonal, then it
might reasonably feel that only the former could be sensibly
rendered in ASCII art; so it can now arrange for the "Copy" menu
item to be greyed out depending on the game_params.

To do this I've introduced a new backend function
(can_format_as_text_now()), and renamed the existing static backend
field "can_format_as_text" to "can_format_as_text_ever". The latter
will cause compile errors for anyone maintaining a third-party front
end; if any such person is reading this, I apologise to them for the
inconvenience, but I did do it deliberately so that they'd know to
update their front end.

As yet, no checked-in game actually uses this feature; all current
games can still either copy always or copy never.

[originally from svn r8161]
2008-09-06 09:27:56 +00:00
02cd67ecb6 Disallow clicks between squares.
[originally from svn r7400]
2007-03-16 13:32:43 +00:00
8d710851de Minor cleanups (mostly \ns in diagnostic printfs) from James H.
[originally from svn r7363]
2007-03-03 17:25:13 +00:00
9287d95d08 General cleanups patch from James H:
- missing static in filling.c
 - better robustness in execute_move() in filling.c
 - remove side effects in assert statements
 - remove rogue diagnostic in galaxies.c
 - remove // comment in map.c
 - add more stylus-friendly UI to Pattern
 - bias Unequal towards generating inequality clues rather than numeric

[originally from svn r7344]
2007-02-28 21:19:15 +00:00
15f70f527a Dariusz Olszewski's changes to support compiling for PocketPC. This
is mostly done with ifdefs in windows.c; so mkfiles.pl generates a
new makefile (Makefile.wce) and Recipe enables it, but it's hardly
any different from Makefile.vc apart from a few definitions at the
top of the files.

Currently the PocketPC build is not enabled in the build script, but
with any luck I'll be able to do so reasonably soon.

[originally from svn r7337]
2007-02-26 20:35:47 +00:00
472deca37c Patch from James H to fix the occasional generation of puzzles
harder than requested.

[originally from svn r7113]
2007-01-15 20:07:18 +00:00
2f8dba9257 Add James H's new puzzle, `Unequal' (otherwise known as the
Guardian's `Futoshiki').

[originally from svn r7100]
2007-01-13 14:44:50 +00:00