explanation of the general code structure. beware that the games implemented
earlier (like nurikabe) can deviate from this explanation. adhering games
include hashiwokakero and yajilin.

every game has the same code structure, with the following functions:

[gamename]() - entry point for game
autosolver() - special solver mode
processkeydown(), processmousemotion(), processmousedown() - get input
- remember to create a control scheme variable for (almost) each game!
showverify() - show connectedness, show different regions in different colours
hint() - hint system
levelnhint() - call hints for levels n=1,2,3,4,5
- for level 5 (or possibly other levels) hints that modify the board: use
  domove() and undo() with visible=0 instead of writing directly to m[][]
  and creating total backups. initially fill the board with NOVALUE, and for
  each alternative fill lev5m[][] with values from m[][] that aren't UNFILLED.
  see mine for an example. NB, don't look at yajilin, it doesn't have regular
  UNFILLED, so UNFILLED is used instead of NOVALUE there.
- use addmovetoqueue to let the hint system add a move
executemovequeue(), executeonemovefromqueue(), movequeueisempty(),
  addmovetoqueue() - add and execute moves in hint system
domove() - add a move to the undo stack, then perform move
applymove() - perform a move, including updating touched[] and st[]
undo() - undo the topmost move on the undo stack
verifyboard() - check if the board is solved, unfinished or illegal
updatetoscreen() - draw all board changes to screen (uses functions like
  drawgrid(), updatecell() etc). if we need space for other stuff than the
  actual board, send larger values than x,y to updatescale (see picross
  and mine)
loadpuzzle() - load puzzle from disk into data structures

variables:

x,y - map size
visit[][], qs, qe, q[] - bfs stuff
m[][], mn[][] (and possible more) - board 
st[][] - internal helper array (counts etc)
touched[][] - indicate that a cell should be redrawn

how to add scoring:

- before event loop, add resetscore()
- after getevent, add displayscore(x,y)
- whenever game is won, add finalizetime() and displayscore(x,y) before messagebox
- in hint(), add usedhint=1 at top
- in processkeydown, add usedundo=1 to if(key==undokey)
- when a move is performed by the user, add normalmove=1, numclicks++
  (preferably to if(up), otherwise to all instances of domove trigged by
  the user)
