New puzzle: `Untangle', cloned (with the addition of random grid

generation) from a simple but rather fun Flash game I saw this
morning.

Small infrastructure change for this puzzle: while most game
backends find the midend's assumption that Solve moves are never
animated to be a convenience absolving them of having to handle the
special case themselves, this one actually needs Solve to be
animated. Rather than break that convenience for the other puzzles,
I've introduced a flag bit (which I've shoved in mouse_priorities
for the moment, shamefully without changing its name).

[originally from svn r6097]
This commit is contained in:
Simon Tatham
2005-07-16 19:51:53 +00:00
parent c5edffdd2c
commit a8a903db47
6 changed files with 1207 additions and 10 deletions

7
Recipe
View File

@ -20,9 +20,10 @@ NETSLIDE = netslide tree234
MINES = mines tree234 MINES = mines tree234
FLIP = flip tree234 FLIP = flip tree234
PEGS = pegs tree234 PEGS = pegs tree234
UNTANGLE = untangle tree234
ALL = list NET NETSLIDE cube fifteen sixteen rect pattern solo twiddle ALL = list NET NETSLIDE cube fifteen sixteen rect pattern solo twiddle
+ MINES samegame FLIP guess PEGS dominosa + MINES samegame FLIP guess PEGS dominosa UNTANGLE
net : [X] gtk COMMON NET net : [X] gtk COMMON NET
netslide : [X] gtk COMMON NETSLIDE netslide : [X] gtk COMMON NETSLIDE
@ -39,6 +40,7 @@ flip : [X] gtk COMMON FLIP
guess : [X] gtk COMMON guess guess : [X] gtk COMMON guess
pegs : [X] gtk COMMON PEGS pegs : [X] gtk COMMON PEGS
dominosa : [X] gtk COMMON dominosa dominosa : [X] gtk COMMON dominosa
untangle : [X] gtk COMMON UNTANGLE
# Auxiliary command-line programs. # Auxiliary command-line programs.
solosolver : [U] solo[STANDALONE_SOLVER] malloc solosolver : [U] solo[STANDALONE_SOLVER] malloc
@ -66,6 +68,7 @@ flip : [G] WINDOWS COMMON FLIP
guess : [G] WINDOWS COMMON guess guess : [G] WINDOWS COMMON guess
pegs : [G] WINDOWS COMMON PEGS pegs : [G] WINDOWS COMMON PEGS
dominosa : [G] WINDOWS COMMON dominosa dominosa : [G] WINDOWS COMMON dominosa
untangle : [G] WINDOWS COMMON UNTANGLE
# Mac OS X unified application containing all the puzzles. # Mac OS X unified application containing all the puzzles.
Puzzles : [MX] osx osx.icns osx-info.plist COMMON ALL Puzzles : [MX] osx osx.icns osx-info.plist COMMON ALL
@ -157,7 +160,7 @@ FORCE:
install: install:
for i in cube net netslide fifteen sixteen twiddle \ for i in cube net netslide fifteen sixteen twiddle \
pattern rect solo mines samegame flip guess \ pattern rect solo mines samegame flip guess \
pegs dominosa; do \ pegs dominosa untangle; do \
$(INSTALL_PROGRAM) -m 755 $$i $(DESTDIR)$(gamesdir)/$$i; \ $(INSTALL_PROGRAM) -m 755 $$i $(DESTDIR)$(gamesdir)/$$i; \
done done
!end !end

2
list.c
View File

@ -32,6 +32,7 @@ extern const game samegame;
extern const game sixteen; extern const game sixteen;
extern const game solo; extern const game solo;
extern const game twiddle; extern const game twiddle;
extern const game untangle;
const game *gamelist[] = { const game *gamelist[] = {
&cube, &cube,
@ -49,6 +50,7 @@ const game *gamelist[] = {
&sixteen, &sixteen,
&solo, &solo,
&twiddle, &twiddle,
&untangle,
}; };
const int gamecount = lenof(gamelist); const int gamecount = lenof(gamelist);

View File

@ -432,7 +432,7 @@ static int midend_really_process_key(midend_data *me, int x, int y, int button)
{ {
game_state *oldstate = game_state *oldstate =
me->ourgame->dup_game(me->states[me->statepos - 1].state); me->ourgame->dup_game(me->states[me->statepos - 1].state);
int special = FALSE, gotspecial = FALSE, ret = 1; int type = MOVE, gottype = FALSE, ret = 1;
float anim_time; float anim_time;
game_state *s; game_state *s;
char *movestr; char *movestr;
@ -450,8 +450,8 @@ static int midend_really_process_key(midend_data *me, int x, int y, int button)
} else if (button == 'u' || button == 'u' || } else if (button == 'u' || button == 'u' ||
button == '\x1A' || button == '\x1F') { button == '\x1A' || button == '\x1F') {
midend_stop_anim(me); midend_stop_anim(me);
special = special(me->states[me->statepos-1].movetype); type = me->states[me->statepos-1].movetype;
gotspecial = TRUE; gottype = TRUE;
if (!midend_undo(me)) if (!midend_undo(me))
goto done; goto done;
} else if (button == 'r' || button == 'R' || } else if (button == 'r' || button == 'R' ||
@ -501,13 +501,14 @@ static int midend_really_process_key(midend_data *me, int x, int y, int button)
} }
} }
if (!gotspecial) if (!gottype)
special = special(me->states[me->statepos-1].movetype); type = me->states[me->statepos-1].movetype;
/* /*
* See if this move requires an animation. * See if this move requires an animation.
*/ */
if (special) { if (special(type) && !(type == SOLVE &&
(me->ourgame->mouse_priorities & SOLVE_ANIMATES))) {
anim_time = 0; anim_time = 0;
} else { } else {
anim_time = me->ourgame->anim_length(oldstate, anim_time = me->ourgame->anim_length(oldstate,
@ -1117,8 +1118,17 @@ char *midend_solve(midend_data *me)
me->ourgame->changed_state(me->ui, me->ourgame->changed_state(me->ui,
me->states[me->statepos-2].state, me->states[me->statepos-2].state,
me->states[me->statepos-1].state); me->states[me->statepos-1].state);
me->dir = +1;
if (me->ourgame->mouse_priorities & SOLVE_ANIMATES) {
me->oldstate = me->ourgame->dup_game(me->states[me->statepos-2].state);
me->anim_time =
me->ourgame->anim_length(me->states[me->statepos-2].state,
me->states[me->statepos-1].state,
+1, me->ui);
} else {
me->anim_time = 0.0; me->anim_time = 0.0;
midend_finish_move(me); midend_finish_move(me);
}
midend_redraw(me); midend_redraw(me);
midend_set_timer(me); midend_set_timer(me);
return NULL; return NULL;

View File

@ -1243,6 +1243,37 @@ additional challenge for an advanced player. Turning off this option
can also speed up puzzle generation. can also speed up puzzle generation.
\C{untangle} \i{Untangle}
\cfg{winhelp-topic}{games.untangle}
You are given a number of points, some of which have lines drawn
between them. You can move the points about arbitrarily; your aim is
to position the points so that no line crosses another.
I originally saw this in the form of a Flash game called \i{Planarity}
\k{Planarity}, written by John Tantalo.
\B{Planarity} \W{http://home.cwru.edu/~jnt5/Planarity}\cw{http://home.cwru.edu/~jnt5/Planarity}
\H{untangle-controls} \i{Untangle controls}
\IM{Untangle controls} controls, for Untangle
To move a point, click on it with the left mouse button and drag it
into a new position.
\H{untangle-parameters} \I{parameters, for Untangle}Untangle parameters
There is only one parameter available from the \q{Custom...} option
on the \q{Type} menu:
\dt \e{Number of points}
\dd Controls the size of the puzzle, by specifying the number of
points in the generated graph.
\A{licence} \I{MIT licence}\ii{Licence} \A{licence} \I{MIT licence}\ii{Licence}
This software is \i{copyright} 2004-2005 Simon Tatham. This software is \i{copyright} 2004-2005 Simon Tatham.

View File

@ -62,6 +62,10 @@ enum {
/* Bit flags indicating mouse button priorities */ /* Bit flags indicating mouse button priorities */
#define BUTTON_BEATS(x,y) ( 1 << (((x)-LEFT_BUTTON)*3+(y)-LEFT_BUTTON) ) #define BUTTON_BEATS(x,y) ( 1 << (((x)-LEFT_BUTTON)*3+(y)-LEFT_BUTTON) )
/* Another random flag that goes in the mouse priorities section for want
* of a better place to put it */
#define SOLVE_ANIMATES ( 1 << 9 )
#define IGNOREARG(x) ( (x) = (x) ) #define IGNOREARG(x) ( (x) = (x) )
typedef struct frontend frontend; typedef struct frontend frontend;

1147
untangle.c Normal file

File diff suppressed because it is too large Load Diff