mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 08:01:30 -07:00
Initial checkin of my Minesweeper clone, which uses a solver during
grid generation to arrange a mine layout that never requires guessing. [originally from svn r5859]
This commit is contained in:
4
Recipe
4
Recipe
@ -17,8 +17,10 @@ WINDOWS = windows user32.lib gdi32.lib comctl32.lib
|
|||||||
COMMON = midend misc malloc random version
|
COMMON = midend misc malloc random version
|
||||||
NET = net tree234
|
NET = net tree234
|
||||||
NETSLIDE = netslide tree234
|
NETSLIDE = netslide tree234
|
||||||
|
MINES = mines tree234
|
||||||
|
|
||||||
ALL = list NET NETSLIDE cube fifteen sixteen rect pattern solo twiddle
|
ALL = list NET NETSLIDE cube fifteen sixteen rect pattern solo twiddle
|
||||||
|
+ MINES
|
||||||
|
|
||||||
net : [X] gtk COMMON NET
|
net : [X] gtk COMMON NET
|
||||||
netslide : [X] gtk COMMON NETSLIDE
|
netslide : [X] gtk COMMON NETSLIDE
|
||||||
@ -29,6 +31,7 @@ rect : [X] gtk COMMON rect
|
|||||||
pattern : [X] gtk COMMON pattern
|
pattern : [X] gtk COMMON pattern
|
||||||
solo : [X] gtk COMMON solo
|
solo : [X] gtk COMMON solo
|
||||||
twiddle : [X] gtk COMMON twiddle
|
twiddle : [X] gtk COMMON twiddle
|
||||||
|
mines : [X] gtk COMMON MINES
|
||||||
|
|
||||||
# The Windows Net shouldn't be called `net.exe' since Windows
|
# The Windows Net shouldn't be called `net.exe' since Windows
|
||||||
# already has a reasonably important utility program by that name!
|
# already has a reasonably important utility program by that name!
|
||||||
@ -41,6 +44,7 @@ rect : [G] WINDOWS COMMON rect
|
|||||||
pattern : [G] WINDOWS COMMON pattern
|
pattern : [G] WINDOWS COMMON pattern
|
||||||
solo : [G] WINDOWS COMMON solo
|
solo : [G] WINDOWS COMMON solo
|
||||||
twiddle : [G] WINDOWS COMMON twiddle
|
twiddle : [G] WINDOWS COMMON twiddle
|
||||||
|
mines : [G] WINDOWS COMMON MINES
|
||||||
|
|
||||||
# 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
|
||||||
|
2
list.c
2
list.c
@ -19,6 +19,7 @@ echo -e '};\n\nconst int gamecount = lenof(gamelist);'
|
|||||||
|
|
||||||
extern const game cube;
|
extern const game cube;
|
||||||
extern const game fifteen;
|
extern const game fifteen;
|
||||||
|
extern const game mines;
|
||||||
extern const game net;
|
extern const game net;
|
||||||
extern const game netslide;
|
extern const game netslide;
|
||||||
extern const game pattern;
|
extern const game pattern;
|
||||||
@ -30,6 +31,7 @@ extern const game twiddle;
|
|||||||
const game *gamelist[] = {
|
const game *gamelist[] = {
|
||||||
&cube,
|
&cube,
|
||||||
&fifteen,
|
&fifteen,
|
||||||
|
&mines,
|
||||||
&net,
|
&net,
|
||||||
&netslide,
|
&netslide,
|
||||||
&pattern,
|
&pattern,
|
||||||
|
72
puzzles.but
72
puzzles.but
@ -829,6 +829,78 @@ for you. Be prepared to wait, especially if you have also configured
|
|||||||
a large puzzle size.
|
a large puzzle size.
|
||||||
|
|
||||||
|
|
||||||
|
\C{mines} \i{Mines}
|
||||||
|
|
||||||
|
\cfg{winhelp-topic}{games.mines}
|
||||||
|
|
||||||
|
You have a grid of covered squares, some of which contain mines, but
|
||||||
|
you don't know which. Your job is to uncover every square which does
|
||||||
|
\e{not} contain a mine. If you uncover a square containing a mine,
|
||||||
|
you lose. If you uncover a square which does not contain a mine, you
|
||||||
|
are told how many mines are contained within the eight surrounding
|
||||||
|
squares.
|
||||||
|
|
||||||
|
This game needs no introduction; popularised by Windows, it is
|
||||||
|
perhaps the single best known desktop puzzle game in existence.
|
||||||
|
|
||||||
|
This version of it has an unusual property. By default, it will
|
||||||
|
generate its mine positions in such a way as to ensure that you
|
||||||
|
never need to \e{guess} where a mine is: you will always be able to
|
||||||
|
deduce it somehow. So you will never, as can happen in other
|
||||||
|
versions, get to the last four squares and discover that there are
|
||||||
|
two mines left but you have no way of knowing for sure where they
|
||||||
|
are.
|
||||||
|
|
||||||
|
\H{mines-controls} \I{controls, for Mines}Mines controls
|
||||||
|
|
||||||
|
This game is played with the mouse.
|
||||||
|
|
||||||
|
If you left-click in a covered square, it will be uncovered.
|
||||||
|
|
||||||
|
If you right-click in a covered square, it will place a flag which
|
||||||
|
indicates that the square is believed to be a mine. Left-clicking in
|
||||||
|
a marked square will not uncover it, for safety. You can right-click
|
||||||
|
again to remove a mark placed in error.
|
||||||
|
|
||||||
|
If you left-click in an \e{uncovered} square, it will \q{clear
|
||||||
|
around} the square. This means: if the square has exactly as many
|
||||||
|
flags surrounding it as it should have mines, then all the covered
|
||||||
|
squares next to it which are \e{not} flagged will be uncovered. So
|
||||||
|
once you think you know the location of all the mines around a
|
||||||
|
square, you can use this function as a shortcut to avoid having to
|
||||||
|
click on each of the remaining squares one by one.
|
||||||
|
|
||||||
|
If you uncover a square which has \e{no} mines in the surrounding
|
||||||
|
eight squares, then it is obviously safe to uncover those squares in
|
||||||
|
turn, and so on if any of them also has no surrounding mines. This
|
||||||
|
will be done for you automatically; so sometimes when you uncover a
|
||||||
|
square, a whole new area will open up to be explored.
|
||||||
|
|
||||||
|
(All the actions described in \k{common-actions} are also available.
|
||||||
|
Even Undo is available, although you might consider it cheating to
|
||||||
|
use it!)
|
||||||
|
|
||||||
|
\H{mines-parameters} \I{parameters, for Mines}Mines parameters
|
||||||
|
|
||||||
|
The options available from the \q{Custom...} option on the \q{Type}
|
||||||
|
menu are:
|
||||||
|
|
||||||
|
\dt \e{Width}, \e{Height}
|
||||||
|
|
||||||
|
\dd Size of grid in squares.
|
||||||
|
|
||||||
|
\dt \e{Mines}
|
||||||
|
|
||||||
|
\dd Number of mines in the grid.
|
||||||
|
|
||||||
|
\dt \e{Ensure solubility}
|
||||||
|
|
||||||
|
\dd When this option is enabled (as it is by default), Mines will
|
||||||
|
ensure that the entire grid can be fully deduced starting from the
|
||||||
|
initial open space. If you prefer the riskier grids generated by
|
||||||
|
other implementations, you can switch off this option.
|
||||||
|
|
||||||
|
|
||||||
\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.
|
||||||
|
12
puzzles.h
12
puzzles.h
@ -176,6 +176,18 @@ random_state *random_init(char *seed, int len);
|
|||||||
unsigned long random_bits(random_state *state, int bits);
|
unsigned long random_bits(random_state *state, int bits);
|
||||||
unsigned long random_upto(random_state *state, unsigned long limit);
|
unsigned long random_upto(random_state *state, unsigned long limit);
|
||||||
void random_free(random_state *state);
|
void random_free(random_state *state);
|
||||||
|
/* random.c also exports SHA, which occasionally comes in useful. */
|
||||||
|
typedef unsigned long uint32;
|
||||||
|
typedef struct {
|
||||||
|
uint32 h[5];
|
||||||
|
unsigned char block[64];
|
||||||
|
int blkused;
|
||||||
|
uint32 lenhi, lenlo;
|
||||||
|
} SHA_State;
|
||||||
|
void SHA_Init(SHA_State *s);
|
||||||
|
void SHA_Bytes(SHA_State *s, void *p, int len);
|
||||||
|
void SHA_Final(SHA_State *s, unsigned char *output);
|
||||||
|
void SHA_Simple(void *p, int len, unsigned char *output);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Data structure containing the function calls and data specific
|
* Data structure containing the function calls and data specific
|
||||||
|
17
random.c
17
random.c
@ -15,15 +15,6 @@
|
|||||||
|
|
||||||
#include "puzzles.h"
|
#include "puzzles.h"
|
||||||
|
|
||||||
typedef unsigned long uint32;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32 h[5];
|
|
||||||
unsigned char block[64];
|
|
||||||
int blkused;
|
|
||||||
uint32 lenhi, lenlo;
|
|
||||||
} SHA_State;
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
* Core SHA algorithm: processes 16-word blocks into a message digest.
|
* Core SHA algorithm: processes 16-word blocks into a message digest.
|
||||||
*/
|
*/
|
||||||
@ -108,14 +99,14 @@ static void SHATransform(uint32 * digest, uint32 * block)
|
|||||||
* the end, and pass those blocks to the core SHA algorithm.
|
* the end, and pass those blocks to the core SHA algorithm.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void SHA_Init(SHA_State * s)
|
void SHA_Init(SHA_State * s)
|
||||||
{
|
{
|
||||||
SHA_Core_Init(s->h);
|
SHA_Core_Init(s->h);
|
||||||
s->blkused = 0;
|
s->blkused = 0;
|
||||||
s->lenhi = s->lenlo = 0;
|
s->lenhi = s->lenlo = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SHA_Bytes(SHA_State * s, void *p, int len)
|
void SHA_Bytes(SHA_State * s, void *p, int len)
|
||||||
{
|
{
|
||||||
unsigned char *q = (unsigned char *) p;
|
unsigned char *q = (unsigned char *) p;
|
||||||
uint32 wordblock[16];
|
uint32 wordblock[16];
|
||||||
@ -158,7 +149,7 @@ static void SHA_Bytes(SHA_State * s, void *p, int len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SHA_Final(SHA_State * s, unsigned char *output)
|
void SHA_Final(SHA_State * s, unsigned char *output)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int pad;
|
int pad;
|
||||||
@ -196,7 +187,7 @@ static void SHA_Final(SHA_State * s, unsigned char *output)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SHA_Simple(void *p, int len, unsigned char *output)
|
void SHA_Simple(void *p, int len, unsigned char *output)
|
||||||
{
|
{
|
||||||
SHA_State s;
|
SHA_State s;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user