Rather than revealing the entire mine layout when you die, we now
only reveal the one mine that killed you. You can then Undo and
continue playing, without having spoiled the rest of the grid for
yourself. The number of times you've died is counted in the status
line (and is not reduced by Undo :-).
Amusingly, I think this in itself is quite a good way of dealing
with ambiguous sections in a Minesweeper grid: they no longer
_completely_ spoil your enjoyment of the game, because you can still
play the remainder of the grid even if you haven't got a completely
clean sweep. Just my luck that I should invent the idea when I've
already arranged for ambiguous sections to be absent :-)
[originally from svn r5886]
the Mines unique grid generator fails at high mine densities it is
_almost always_ for the same reason, and it also turns out that this
reason is one which can be addressed. So here's an enhancement to
mineperturb() which enables Mines to generate a grid at (as far as I
can tell) any mine density you like, up to and including w*h-9
mines. At densities of 1 in 2 or thereabouts the grids start to look
rather strange, but it can at least generate them without hanging.
[originally from svn r5885]
function rather less uniform-looking than I'd intended. I _thought_
it looked a bit fishy, but had assumed it was just the human
tendency to see patterns where none exist. Now fixed, and some real
test vectors confirm that this time the obfuscation function is
actually what I intended it to be.
This means that all masked game IDs generated before this revision
are now invalid. That's a shame, but the game is only a day old and
I think I can reasonably justify it as teething trouble.
[originally from svn r5883]
and it moves the polyhedron in the general direction of the mouse
pointer. (I had this in my initial throwaway Python implementation
of this game, but never reimplemented it in this version. It's
harder with triangles, but not too much harder.)
Since the logical-to-physical coordinate mapping in Cube is
dynamically computed, this has involved an interface change which
touches all puzzles: make_move() is now passed a pointer to the
game_drawstate, which it may of course completely ignore if it
wishes.
[originally from svn r5877]
background colour for covered and uncovered squares in Mines, since
otherwise you have to distinguish them by the edge highlights alone.
So here one is; it's not _very_ different (it just looked odd if it
was any darker than this), but anyone who wants a bigger difference
can reconfigure it using the MINES_COLOUR_1 environment variable.
[originally from svn r5876]
between on the one hand generating indeterminate game descriptions
awaiting the initial click, and on the other hand generating
concrete ones which have had their initial click. This makes `mines
--generate' do something useful.
[originally from svn r5869]
indicates whether a particular game state should have the timer
going (for Mines the initial indeterminate state does not have this
property, and neither does a dead or won state); a midend function
that optionally (on request from the game) prepends a timer to the
front of the status bar text; some complicated midend timing code.
It's not great. It's ugly; it's probably slightly inaccurate; it's
got no provision for anyone but the game author decreeing whether a
game is timed or not. But Mines can't be taken seriously without a
timer, so it's a start.
[originally from svn r5866]
blank grid until you make the first click; to ensure solubility, it
does not generate the mine layout until that click, and then ensures
it is solvable starting from that position.
This has involved three infrastructure changes:
- random.c now offers functions to encode and decode an entire
random_state as a string
- each puzzle's new_game() is now passed a pointer to the midend
itself, which most of them ignore
- there's a function in the midend which a game can call back to
_rewrite_ its current game description.
So Mines now has two entirely separate forms of game ID. One
contains the generation-time parameters (n and unique) plus an
encoding of a random_state; the other actually encodes the grid once
it's been generated, and also contains the initial click position.
When called with the latter, new_game() does plausibly normal stuff.
When called with the former, it notes down all the details and waits
until the first square is opened, and _then_ does the grid
generation and updates the game description in the midend. So if,
_after_ your first click, you decide you want to share this
particular puzzle with someone else, you can do that fine.
Also in this checkin, the mine layout is no longer _copied_ between
all the game_states on the undo chain. Instead, it's in a separate
structure and all game_states share a pointer to it - and the
structure is reference-counted to ensure deallocation.
[originally from svn r5862]