simon-git: puzzles (master): Simon Tatham

Commits to Tartarus CVS repository. tartarus-commits at lists.tartarus.org
Wed Feb 24 20:05:28 GMT 2016


TL;DR:
  1add03f New centralised loop-finder, using Tarjan's algorithm.
  deff331 Bridges: use the new findloop for loop detection.
  e862d4a Net: use the new findloop for loop detection.
  a2380d2 Slant: use the new findloop for loop detection.
  01844d3 Tracks: use the new findloop for loop detection.
  755c3d5 Tracks: tighten up a small loophole in completion checking.
  2484870 Loopy: revamp loop detection, but not using findloop.
  32643fa Loopy: be friendlier to right-click-less playing style.
  c550092 Pearl: reinstate a conditioned-out assertion.
  adc5474 Pearl: revise loop detection similarly to Loopy.

Repository:     git://git.tartarus.org/simon/puzzles.git
On the web:     http://tartarus.org/~simon-git/gitweb/?p=puzzles.git
Branch updated: master
Committer:      Simon Tatham <anakin at pobox.com>
Date:           2016-02-24 20:05:28

commit 1add03f7b8a502d4453f53f4ea6930d0e71a6bb0
web diff http://tartarus.org/~simon-git/gitweb/?p=puzzles.git;a=commitdiff;h=1add03f7b8a502d4453f53f4ea6930d0e71a6bb0;hp=4a0d9ad39b1fc5e42fea6fb595ca480db0727bcd
Author: Simon Tatham <anakin at pobox.com>
Date:   Wed Feb 24 18:57:03 2016 +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
    bridge.
    
    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.

 findloop.c |  500 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 puzzles.h  |   35 +++++
 2 files changed, 535 insertions(+)

commit deff331e5f8d46215b967b7eaa7f64b13878785a
web diff http://tartarus.org/~simon-git/gitweb/?p=puzzles.git;a=commitdiff;h=deff331e5f8d46215b967b7eaa7f64b13878785a;hp=1add03f7b8a502d4453f53f4ea6930d0e71a6bb0
Author: Simon Tatham <anakin at pobox.com>
Date:   Wed Feb 24 19:01:42 2016 +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.

 bridges.R |    2 +-
 bridges.c |  147 +++++++++++++++++++++++++++----------------------------------
 2 files changed, 66 insertions(+), 83 deletions(-)

commit e862d4a79b934a20d8c4cd283ff8292681b63314
web diff http://tartarus.org/~simon-git/gitweb/?p=puzzles.git;a=commitdiff;h=e862d4a79b934a20d8c4cd283ff8292681b63314;hp=deff331e5f8d46215b967b7eaa7f64b13878785a
Author: Simon Tatham <anakin at pobox.com>
Date:   Wed Feb 24 19:05:43 2016 +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.

 net.R |    2 +-
 net.c |  235 ++++++++++++++---------------------------------------------------
 2 files changed, 52 insertions(+), 185 deletions(-)

commit a2380d277a50b02d9575017559d95d562986488a
web diff http://tartarus.org/~simon-git/gitweb/?p=puzzles.git;a=commitdiff;h=a2380d277a50b02d9575017559d95d562986488a;hp=e862d4a79b934a20d8c4cd283ff8292681b63314
Author: Simon Tatham <anakin at pobox.com>
Date:   Wed Feb 24 19:10:16 2016 +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...

 slant.R |    2 +-
 slant.c |  132 +++++++++++++++++++++++++--------------------------------------
 2 files changed, 54 insertions(+), 80 deletions(-)

commit 01844d39c6c92d5ce417519ef2bdced6346f2549
web diff http://tartarus.org/~simon-git/gitweb/?p=puzzles.git;a=commitdiff;h=01844d39c6c92d5ce417519ef2bdced6346f2549;hp=a2380d277a50b02d9575017559d95d562986488a
Author: Simon Tatham <anakin at pobox.com>
Date:   Wed Feb 24 19:14:31 2016 +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.

 tracks.R |    2 +-
 tracks.c |   71 ++++++++++++++++++++++++++++++++++++++++++++------------------
 2 files changed, 52 insertions(+), 21 deletions(-)

commit 755c3d5277262739e8beb03da3649e7f4d53e915
web diff http://tartarus.org/~simon-git/gitweb/?p=puzzles.git;a=commitdiff;h=755c3d5277262739e8beb03da3649e7f4d53e915;hp=01844d39c6c92d5ce417519ef2bdced6346f2549
Author: Simon Tatham <anakin at pobox.com>
Date:   Wed Feb 24 19:18:30 2016 +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.

 tracks.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

commit 24848706edfdd1db1f97e3681d7ff52bec2fa575
web diff http://tartarus.org/~simon-git/gitweb/?p=puzzles.git;a=commitdiff;h=24848706edfdd1db1f97e3681d7ff52bec2fa575;hp=755c3d5277262739e8beb03da3649e7f4d53e915
Author: Simon Tatham <anakin at pobox.com>
Date:   Wed Feb 24 19:22:57 2016 +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
    stuff.

 loopy.c |  296 ++++++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 177 insertions(+), 119 deletions(-)

commit 32643fab5583c6a0af6fd8373b226198d59d8b99
web diff http://tartarus.org/~simon-git/gitweb/?p=puzzles.git;a=commitdiff;h=32643fab5583c6a0af6fd8373b226198d59d8b99;hp=24848706edfdd1db1f97e3681d7ff52bec2fa575
Author: Simon Tatham <anakin at pobox.com>
Date:   Wed Feb 24 19:27:10 2016 +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
    future.
    
    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.)

 loopy.c |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 54 insertions(+), 4 deletions(-)

commit c5500926bf7458aabb0e11945bfd24038bfeedee
web diff http://tartarus.org/~simon-git/gitweb/?p=puzzles.git;a=commitdiff;h=c5500926bf7458aabb0e11945bfd24038bfeedee;hp=32643fab5583c6a0af6fd8373b226198d59d8b99
Author: Simon Tatham <anakin at pobox.com>
Date:   Wed Feb 24 19:31:54 2016 +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
    it!

 pearl.c |    4 ----
 1 file changed, 4 deletions(-)

commit adc54741f03cf0cc5c639e917afd2442da9e3422
web diff http://tartarus.org/~simon-git/gitweb/?p=puzzles.git;a=commitdiff;h=adc54741f03cf0cc5c639e917afd2442da9e3422;hp=c5500926bf7458aabb0e11945bfd24038bfeedee
Author: Simon Tatham <anakin at pobox.com>
Date:   Wed Feb 24 19:36:41 2016 +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.)

 pearl.c |  176 ++++++++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 112 insertions(+), 64 deletions(-)



More information about the tartarus-commits mailing list