21 Commits

Author SHA1 Message Date
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
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
08915945e6 Adopt C99 bool in the shared Latin-square API.
latin_check now returns bool, and latin_solver_diff_set takes a bool
'extreme' flag. Should be non-disruptive.
2018-11-13 21:48:24 +00:00
e53c097fb7 latin.c: remove a rogue array overrun.
Oops! This was left over from an early development version of commits
4408476b7 and 000ebc507, in which I initially arranged for each
adjacency list to be terminated with the sentinel value -1 instead of
separately storing an array of the lists' lengths.

I later changed the representation to make randomising the algorithm
easier (it's much easier to shuffle an array uniformly at random if
you _don't_ have to faff endlessly to work out its length). But this
write of a no-longer- needed sentinel value in the client code must
have survived the rewrite by mistake, and also somehow evaded all my
pre-commit testing with valgrind and asan.

A user reported that the Towers Javascript version was crashing on
startup, and I think this is the cause, because it seems to fix it for
me.
2018-04-28 12:02:43 +01:00
000ebc5078 Use the new matching() for latin.c.
The new client code is a lot smaller and nicer, because we can throw
away the col[] and num[] permutations entirely.

Of course, this also means that every puzzle that incorporated latin.c
now has to link against matching.c instead of maxflow.c - but since I
centralised that secondary dependency into Recipe a few commits ago,
it's trivial to switch them all over at once.
2018-04-22 16:45:59 +01:00
2270ee116d latin.c: dump every solution found during recursion.
In solver_show_working mode, we were logging all the deductions,
guesswork and backtracking, but not printing out the actual solution
(if any) reached at the end of each branch of the tree.
2018-02-26 20:49:14 +00: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
58e0d0bc2d New puzzle from James Harvey: 'Singles', an implementation of
Hitori. One infrastructure change in the process: latin.c has
acquired a utility function to generate a latin rectangle rather
than a full square.

[originally from svn r8828]
2010-01-11 21:21:07 +00:00
771f5446a8 Retire the YTRANS and YUNTRANS macros in latin.[ch]. They were
introduced to mimic similar macros in solo.c, in case Solo ever
moved over to being based on the latin.c solver framework; but even
Solo has long since lost those macros, so latin.c has no need to
keep them.

[originally from svn r8827]
2010-01-11 20:32:55 +00:00
13d7ff6ae5 Add a facility in the latin.c solver diagnostics to allow a puzzle
to call the digit values by custom names.

[originally from svn r8811]
2010-01-05 23:40:40 +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
3c3368d07f I've never trusted common variables. Take those bare ints out of
latin.h and put them in latin.c with 'extern' declarations in the
header.

[originally from svn r8794]
2009-12-27 10:01:18 +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
f5dedef552 Adam D. Lopresto and Phil Bordelon independently point out a
signedness mismatch.

[originally from svn r7350]
2007-03-01 07:39:05 +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
aa6fb75072 Forgot to shuffle the num[] array! That was probably introducing
some really subtle probabilistic bias in the generated latin squares.

[originally from svn r7302]
2007-02-19 19:38:00 +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
7a41702606 Phil Bordelon points out that the Unequal difficulty settings
documentation is a bit odd, and also offers a signedness fix in
latin.c.

[originally from svn r7112]
2007-01-15 20:04:11 +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