7 Commits

Author SHA1 Message Date
07029044b7 Mosaic: fix uninitialised field in dup_game().
not_completed_clues wasn't being copied from the previous game state,
and was left uninitialised, so that its value was indeterminate.
2022-01-27 18:29:21 +00:00
534384e5de Mosaic: fix inconsistently drawn keyboard cursor.
Every call to draw_cell() was drawing a region including the whole
border of the cell, so that the calls overlapped. So if the cursor
moved left or up, then a COL_CURSOR outline would be drawn around the
new cell, and then a COL_GRID outline would be drawn around the old
cell, overwriting part of the cursor border.

I've fixed this in the rigorous way, by making draw_cell() calls cover
disjoint areas of the puzzle canvas, and using clip() to enforce that.
So now the single DRAWFLAG_CURSOR is replaced by a system of four
flags, indicating that the cell being drawn is the actual cursor
position, or the cell below it (hence containing the cursor's bottom
border), or to its right (needing the left border), or below _and_ to
the right (you still need the single pixel at the cursor's bottom
right corner!).

Also, to ensure the cursor edges are drawn even on the bottom or right
grid boundaries, draw_cell() is called for a set of virtual cells
beyond the actual grid bounds, with additional flags telling it not to
draw an actual puzzle cell there, just the relevant pieces of border.
2022-01-27 18:25:14 +00:00
efbb2e3a31 Mosaic: fix encoding of aggressiveness in game params.
The default setting for 'aggressiveness' is true. But the extra suffix
to specify it in the full version of the encoded game params was being
set if aggressiveness _was_ true, not if it was false. Result: round
trip encode/decode of a non-aggressive configuration fails, because
the encoded string has no aggressiveness suffix, and the decoder
interprets that as going back into aggressive mode.

Pulled out the default setting into a #define which is checked
consistently in both locations.
2022-01-08 14:27:16 +00:00
091bef1a82 Mosaic: implement game_status. 2021-04-26 18:05:09 +01:00
f2f39af2d3 Mosaic: use signed char for clue values.
Negative numbers are used as a sentinel for an absent clue, so we have
to use a type that's guaranteed to have some negative numbers. char is
unsigned on some platforms. So now Mosaic runs apparently correctly on
Raspbian, for example.
2021-04-26 18:05:00 +01:00
c0da615a93 Centralise initial clearing of the puzzle window.
I don't know how I've never thought of this before! Pretty much every
game in this collection has to have a mechanism for noticing when
game_redraw is called for the first time on a new drawstate, and if
so, start by covering the whole window with a filled rectangle of the
background colour. This is a pain for implementers, and also awkward
because the drawstate often has to _work out_ its own pixel size (or
else remember it from when its size method was called).

The backends all do that so that the frontends don't have to guarantee
anything about the initial window contents. But that's a silly
tradeoff to begin with (there are way more backends than frontends, so
this _adds_ work rather than saving it), and also, in this code base
there's a standard way to handle things you don't want to have to do
in every backend _or_ every frontend: do them just once in the midend!

So now that rectangle-drawing operation happens in midend_redraw, and
I've been able to remove it from almost every puzzle. (A couple of
puzzles have other approaches: Slant didn't have a rectangle-draw
because it handles even the game borders using its per-tile redraw
function, and Untangle clears the whole window on every redraw
_anyway_ because it would just be too confusing not to.)

In some cases I've also been able to remove the 'started' flag from
the drawstate. But in many cases that has to stay because it also
triggers drawing of static display furniture other than the
background.
2021-04-25 13:07:59 +01:00
0377184510 New puzzle: 'Mosaic'.
This is similar in concept to Minesweeper, in that each clue tells you
the number of things (in this case, just 'black squares') in the
surrounding 3x3 grid section.

But unlike Minesweeper, there's no separation between squares that can
contain clues, and squares that can contain the things you're looking
for - a clue square may or may not itself be coloured black, and if
so, its clue counts itself.

So there's also no hidden information: the clues can all be shown up
front, and the difficulty arises from the game generator choosing
which squares to provide clues for at all.

Contributed by a new author, Didi Kohen. Currently only has one
difficulty level, but harder ones would be possible to add later.
2021-04-25 09:59:15 +01:00