mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 08:01:30 -07:00
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:
7
Recipe
7
Recipe
@ -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
2
list.c
@ -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);
|
||||||
|
22
midend.c
22
midend.c
@ -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;
|
||||||
|
31
puzzles.but
31
puzzles.but
@ -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.
|
||||||
|
@ -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
1147
untangle.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user