whether the timer is currently going is no longer solely dependent
on the current game_state: it can be dependent on more persistent
information stored in the game_ui. In particular, Mines now freezes
the timer permanently once you complete a grid for the first time,
so that you can then backtrack through your solution process without
destroying the information about how long it took you the first time
through.
[originally from svn r6088]
by the midend every time the game state changed _other_ than as a
result of make_move(), on the basis that when the game state changed
due to make_move() the game backend had probably noticed anyway.
However, when make_move() split up, this became more fiddly: if the
game_ui had to be updated based on some property of the final game
state, then execute_move() couldn't do it because it didn't have a
pointer to the game_ui, but it was fiddly to do it in
interpret_move() because that didn't directly have a copy of the
finished game state to examine. Same Game (the only game to be
affected) had to deal with this by actually having interpret_move()
_call_ execute_move() to construct a temporary new game state,
update the UI, and then throw it away.
So now, game_changed_state() is called _every_ time the current game
state changes, which means that if anything needs doing to the
game_ui as a result of examining the new game state, it can be done
there and save a lot of effort.
[originally from svn r6087]
encode_params(). This is necessary for cases where generation-time parameters
that are normally omitted from descriptive IDs can place restrictions on other
parameters; in particular, when the default value of a relevant generation-time
parameter is not the one used to generate the descriptive ID, validation could
reject self-generated IDs (e.g., Net `5x2w:56182ae7c2', and some cases in
`Pegs').
[originally from svn r6068]
unpleasant and requiring lots of special cases to be taken care of
by every single game. The new interface exposes an integer `tile
size' or `scale' parameter to the midend and provides two much
simpler routines: one which computes the pixel window size given a
game_params and a tile size, and one which is given a tile size and
must set up a drawstate appropriately. All the rest of the
complexity is handled in the midend, mostly by binary search, so
grubby special cases only have to be dealt with once.
[originally from svn r6059]
constraint: because some front ends interpret `draw filled shape' to
mean `including its boundary' while others interpret it to mean `not
including its boundary' (and X seems to vacillate between the two
opinions as it moves around the shape!), you MUST NOT draw a filled
shape only. You can fill in one colour and outline in another, you
can fill or outline in the same colour, or you can just outline, but
just filling is a no-no.
This leads to a _lot_ of double calls to these functions, so I've
changed the interface. draw_circle() and draw_polygon() now each
take two colour arguments, a fill colour (which can be -1 for none)
and an outline colour (which must be valid). This should simplify
code in the game back ends, while also reducing the possibility for
coding error.
[originally from svn r6047]
- most game_size() functions now work in doubles internally and
round to nearest, meaning that they have less tendency to try to
alter a size they returned happily from a previous call
- couple of fiddly fixes (memory leaks, precautionary casts in
printf argument lists)
- midend_deserialise() now constructs an appropriate drawstate,
which I can't think how I overlooked myself since I _thought_ I
went through the entire midend structure field by field!
[originally from svn r6041]
retired, and replaced with a simple string. Most of the games which
use it simply encode the string in the same way that the Solve move
will also be encoded, i.e. solve_game() simply returns
dupstr(aux_info). Again, this is a better approach than writing
separate game_aux_info serialise/deserialise functions because doing
it this way is self-testing (the strings are created and parsed
during the course of any Solve operation at all).
[originally from svn r6029]
and restore anything vitally important in the game_ui. Most of the
game_ui is expected to be stuff about cursor positions and currently
active mouse drags, so it absolutely _doesn't_ want to be preserved
over a serialisation; but one or two things would be disorienting or
outright wrong to reset, such as the Net origin position and the
Mines death counter.
[originally from svn r6026]
split into two functions. The first, interpret_move(), takes all the
arguments that make_move() used to get and may have the usual side
effects of modifying the game_ui, but instead of returning a
modified game_state it instead returns a string description of the
move to be made. This string description is then passed to a second
function, execute_move(), together with an input game_state, which
is responsible for actually producing the new state. (solve_game()
also returns a string to be passed to execute_move().)
The point of this is to work towards being able to serialise the
whole of a game midend into a byte stream such as a disk file, which
will eventually support save and load functions in the desktop
puzzles, as well as restoring half-finished games after a quit and
restart in James Harvey's Palm port. Making each game supply a
convert-to-string function for its game_state format would have been
an unreliable way to do this, since those functions would not have
been used in normal play, so they'd only have been tested when you
actually tried to save and load - a recipe for latent bugs if ever I
heard one. This way, you won't even be able to _make_ a move if
execute_move() doesn't work properly, which means that if you can
play a game at all I can have pretty high confidence that
serialising it will work first time.
This is only the groundwork; there will be more checkins to come on
this theme. But the major upheaval should now be done, and as far as
I can tell everything's still working normally.
[originally from svn r6024]
redrawn as non-black on undo. Introduce a new flag TILE_IMPOSSIBLE,
so that information about those black markers is cached in the
drawstate and we know when we have to erase them.
In the process I've removed the game_state argument completely from
the subfunction tile_redraw(), which gives me some confidence that
it isn't getting any _more_ privileged information out of it.
[originally from svn r5979]