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

2
list.c
View File

@ -32,6 +32,7 @@ extern const game samegame;
extern const game sixteen;
extern const game solo;
extern const game twiddle;
extern const game untangle;
const game *gamelist[] = {
&cube,
@ -49,6 +50,7 @@ const game *gamelist[] = {
&sixteen,
&solo,
&twiddle,
&untangle,
};
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 =
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;
game_state *s;
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' ||
button == '\x1A' || button == '\x1F') {
midend_stop_anim(me);
special = special(me->states[me->statepos-1].movetype);
gotspecial = TRUE;
type = me->states[me->statepos-1].movetype;
gottype = TRUE;
if (!midend_undo(me))
goto done;
} 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)
special = special(me->states[me->statepos-1].movetype);
if (!gottype)
type = me->states[me->statepos-1].movetype;
/*
* See if this move requires an animation.
*/
if (special) {
if (special(type) && !(type == SOLVE &&
(me->ourgame->mouse_priorities & SOLVE_ANIMATES))) {
anim_time = 0;
} else {
anim_time = me->ourgame->anim_length(oldstate,
@ -1117,8 +1118,17 @@ char *midend_solve(midend_data *me)
me->ourgame->changed_state(me->ui,
me->states[me->statepos-2].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;
midend_finish_move(me);
}
midend_redraw(me);
midend_set_timer(me);
return NULL;

View File

@ -1243,6 +1243,37 @@ additional challenge for an advanced player. Turning off this option
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}
This software is \i{copyright} 2004-2005 Simon Tatham.

View File

@ -62,6 +62,10 @@ enum {
/* Bit flags indicating mouse button priorities */
#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) )
typedef struct frontend frontend;

1147
untangle.c Normal file

File diff suppressed because it is too large Load Diff