mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 08:01:30 -07:00
Add James H's new puzzle, `Unequal' (otherwise known as the
Guardian's `Futoshiki'). [originally from svn r7100]
This commit is contained in:
114
latin.h
Normal file
114
latin.h
Normal file
@ -0,0 +1,114 @@
|
||||
#ifndef LATIN_H
|
||||
#define LATIN_H
|
||||
|
||||
#include "puzzles.h"
|
||||
|
||||
typedef unsigned char digit;
|
||||
|
||||
/* --- Solver structures, definitions --- */
|
||||
|
||||
#ifdef STANDALONE_SOLVER
|
||||
int solver_show_working, solver_recurse_depth;
|
||||
#endif
|
||||
|
||||
struct latin_solver {
|
||||
int o; /* order of latin square */
|
||||
unsigned char *cube; /* o^3, indexed by x, y, and digit:
|
||||
TRUE in that position indicates a possibility */
|
||||
digit *grid; /* o^2, indexed by x and y: for final deductions */
|
||||
|
||||
unsigned char *row; /* o^2: row[y*cr+n-1] TRUE if n is in row y */
|
||||
unsigned char *col; /* o^2: col[x*cr+n-1] TRUE if n is in col x */
|
||||
};
|
||||
#define cubepos(x,y,n) (((x)*solver->o+(y))*solver->o+(n)-1)
|
||||
#define cube(x,y,n) (solver->cube[cubepos(x,y,n)])
|
||||
|
||||
#define gridpos(x,y) ((y)*solver->o+(x))
|
||||
#define grid(x,y) (solver->grid[gridpos(x,y)])
|
||||
|
||||
/* A solo solver using this code would need these defined. See solo.c. */
|
||||
#ifndef YTRANS
|
||||
#define YTRANS(y) (y)
|
||||
#endif
|
||||
#ifndef YUNTRANS
|
||||
#define YUNTRANS(y) (y)
|
||||
#endif
|
||||
|
||||
|
||||
/* --- Solver individual strategies --- */
|
||||
|
||||
/* Place a value at a specific location. */
|
||||
void latin_solver_place(struct latin_solver *solver, int x, int y, int n);
|
||||
|
||||
/* Positional elimination. */
|
||||
int latin_solver_elim(struct latin_solver *solver, int start, int step
|
||||
#ifdef STANDALONE_SOLVER
|
||||
, char *fmt, ...
|
||||
#endif
|
||||
);
|
||||
|
||||
struct latin_solver_scratch; /* private to latin.c */
|
||||
/* Set elimination */
|
||||
int latin_solver_set(struct latin_solver *solver,
|
||||
struct latin_solver_scratch *scratch,
|
||||
int start, int step1, int step2
|
||||
#ifdef STANDALONE_SOLVER
|
||||
, char *fmt, ...
|
||||
#endif
|
||||
);
|
||||
|
||||
/* Forcing chains */
|
||||
int latin_solver_forcing(struct latin_solver *solver,
|
||||
struct latin_solver_scratch *scratch);
|
||||
|
||||
|
||||
/* --- Solver allocation --- */
|
||||
|
||||
/* Fills in (and allocates members for) a latin_solver struct.
|
||||
* Will allocate members of snew, but not snew itself
|
||||
* (allowing 'struct latin_solver' to be the first element in a larger
|
||||
* struct, for example). */
|
||||
void latin_solver_alloc(struct latin_solver *solver, digit *grid, int o);
|
||||
void latin_solver_free(struct latin_solver *solver);
|
||||
|
||||
/* Allocates scratch space (for _set and _forcing) */
|
||||
struct latin_solver_scratch *
|
||||
latin_solver_new_scratch(struct latin_solver *solver);
|
||||
void latin_solver_free_scratch(struct latin_solver_scratch *scratch);
|
||||
|
||||
|
||||
/* --- Solver guts --- */
|
||||
|
||||
/* Looped positional elimination */
|
||||
int latin_solver_diff_simple(struct latin_solver *solver);
|
||||
|
||||
/* Looped set elimination; *extreme is set if it used
|
||||
* the more difficult single-number elimination. */
|
||||
int latin_solver_diff_set(struct latin_solver *solver,
|
||||
struct latin_solver_scratch *scratch,
|
||||
int *extreme);
|
||||
|
||||
typedef int (latin_solver_callback)(digit *, int, int, void*);
|
||||
/* Use to provide a standard way of dealing with solvers which can recurse;
|
||||
* pass in your enumeration for 'recursive diff' and your solver
|
||||
* callback. Returns #solutions (0 == already solved). */
|
||||
int latin_solver_recurse(struct latin_solver *solver, int recdiff,
|
||||
latin_solver_callback cb, void *ctx);
|
||||
|
||||
/* Individual puzzles should use their enumerations for their
|
||||
* own difficulty levels, ensuring they don't clash with these. */
|
||||
enum { diff_impossible = 10, diff_ambiguous, diff_unfinished };
|
||||
int latin_solver(digit *grid, int order, int maxdiff, void *unused);
|
||||
|
||||
void latin_solver_debug(unsigned char *cube, int o);
|
||||
|
||||
/* --- Generation and checking --- */
|
||||
|
||||
digit *latin_generate_quick(int o, random_state *rs);
|
||||
digit *latin_generate(int o, random_state *rs);
|
||||
|
||||
int latin_check(digit *sq, int order); /* !0 => not a latin square */
|
||||
|
||||
void latin_debug(digit *sq, int order);
|
||||
|
||||
#endif
|
69
puzzles.but
69
puzzles.but
@ -2073,6 +2073,75 @@ possible islands; low expansion factors can create lots of
|
||||
tightly-packed islands.
|
||||
|
||||
|
||||
\C{unequal} \i{Unequal}
|
||||
|
||||
\cfg{winhelp-topic}{games.unequal}
|
||||
|
||||
You have a square grid; each square may contain a digit from 1 to
|
||||
the size of the grid, and some squares have greater-signs between
|
||||
them. Your aim is to fully populate the grid with numbers such that:
|
||||
|
||||
\b Each row contains only one occurrence of each digit
|
||||
|
||||
\b Each column contains only one occurrence of each digit
|
||||
|
||||
\b All the greater-than signs are satisfied.
|
||||
|
||||
In 'Trivial' mode, there are no greater-than signs; the puzzle is
|
||||
to solve the latin square only.
|
||||
|
||||
At the time of writing, this puzzle is appearing in the Guardian
|
||||
weekly under the name 'Futoshiki'.
|
||||
|
||||
Unequal was contributed to this collection by James Harvey.
|
||||
|
||||
\H{unequal-controls} \i{Unequal controls}
|
||||
|
||||
\IM{Unequal controls} controls, for Unequal
|
||||
|
||||
Unequal shares much of its control system with Solo.
|
||||
|
||||
To play Unequal, simply click the mouse in any empty square and then
|
||||
type a digit or letter on the keyboard to fill that square. If you
|
||||
make a mistake, click the mouse in the incorrect square and press
|
||||
Space to clear it again (or use the Undo feature).
|
||||
|
||||
If you \e{right}-click in a square and then type a number, that
|
||||
number will be entered in the square as a \q{pencil mark}. You can
|
||||
have pencil marks for multiple numbers in the same square.
|
||||
|
||||
The game pays no attention to pencil marks, so exactly what you use
|
||||
them for is up to you: you can use them as reminders that a
|
||||
particular square needs to be re-examined once you know more about a
|
||||
particular number, or you can use them as lists of the possible
|
||||
numbers in a given square, or anything else you feel like.
|
||||
|
||||
To erase a single pencil mark, right-click in the square and type
|
||||
the same number again.
|
||||
|
||||
All pencil marks in a square are erased when you left-click and type
|
||||
a number, or when you left-click and press space. Right-clicking and
|
||||
pressing space will also erase pencil marks.
|
||||
|
||||
(All the actions described in \k{common-actions} are also available.)
|
||||
|
||||
\H{unequal-parameters} \I{parameters, for Unequal}Unequal parameters
|
||||
|
||||
These parameters are available from the \q{Custom...} option on the
|
||||
\q{Type} menu.
|
||||
|
||||
\dt \e{Size (s*s)}
|
||||
|
||||
\dd Size of grid.
|
||||
|
||||
\dt \e{Difficulty}
|
||||
|
||||
\dd Controls the difficulty of the generated puzzle. At Trivial level,
|
||||
there are no greater-than signs (the puzzle is to solve the latin
|
||||
square only); at Tricky level, some recursion may be required (but the
|
||||
solutions should always be unique).
|
||||
|
||||
|
||||
\A{licence} \I{MIT licence}\ii{Licence}
|
||||
|
||||
This software is \i{copyright} 2004-2007 Simon Tatham.
|
||||
|
23
unequal.R
Normal file
23
unequal.R
Normal file
@ -0,0 +1,23 @@
|
||||
# -*- makefile -*-
|
||||
|
||||
UNEQUAL = unequal latin tree234 maxflow
|
||||
|
||||
unequal : [X] GTK COMMON UNEQUAL
|
||||
|
||||
unequal : [G] WINDOWS COMMON UNEQUAL
|
||||
|
||||
unequalsolver : [U] unequal[STANDALONE_SOLVER] latin[STANDALONE_SOLVER] tree234 maxflow STANDALONE
|
||||
unequalsolver : [C] unequal[STANDALONE_SOLVER] latin[STANDALONE_SOLVER] tree234 maxflow STANDALONE
|
||||
|
||||
latincheck : [U] latin[STANDALONE_LATIN_TEST] tree234 maxflow STANDALONE
|
||||
latincheck : [C] latin[STANDALONE_LATIN_TEST] tree234 maxflow STANDALONE
|
||||
|
||||
ALL += UNEQUAL
|
||||
|
||||
!begin gtk
|
||||
GAMES += unequal
|
||||
!end
|
||||
|
||||
!begin >list.c
|
||||
A(unequal) \
|
||||
!end
|
Reference in New Issue
Block a user