aboutsummaryrefslogtreecommitdiff
path: root/net.c (follow)
Commit message (Collapse)AuthorAge
* James H points out a rogue fprintf in Net's print routine.Simon Tatham2005-08-22
| | | | [originally from svn r6202]
* Retire redundant print_line_width() in Net: a relic from a failedSimon Tatham2005-08-20
| | | | | | printing strategy, irrelevant to the one which worked. [originally from svn r6194]
* Substantial infrastructure upheaval. I've separated the drawing APISimon Tatham2005-08-18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | as seen by the back ends from the one implemented by the front end, and shoved a piece of middleware (drawing.c) in between to permit interchange of multiple kinds of the latter. I've also added a number of functions to the drawing API to permit printing as well as on-screen drawing, and retired print.py in favour of integrated printing done by means of that API. The immediate visible change is that print.py is dead, and each puzzle now does its own printing: where you would previously have typed `print.py solo 2x3', you now type `solo --print 2x3' and it should work in much the same way. Advantages of the new mechanism available right now: - Map is now printable, because the new print function can make use of the output from the existing game ID decoder rather than me having to replicate all those fiddly algorithms in Python. - the new print functions can cope with non-initial game states, which means each puzzle supporting --print also supports --with-solutions. - there's also a --scale option permitting users to adjust the size of the printed puzzles. Advantages which will be available at some point: - the new API should permit me to implement native printing mechanisms on Windows and OS X. [originally from svn r6190]
* New puzzle: `Slant', picked from the Japanese-language section ofSimon Tatham2005-08-02
| | | | | | | | | | | nikoli.co.jp (which has quite a few puzzles that they don't seem to have bothered to translate into English). Minor structural change: the disjoint set forest code used in the Net solver has come in handy again, so I've moved it out into its own module dsf.c. [originally from svn r6155]
* game_timing_state() now has access to the game_ui. This means thatSimon Tatham2005-07-10
| | | | | | | | | | | | 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]
* Some patches from James H:Simon Tatham2005-07-06
| | | | | | | | | | | | | | - reinstate the initialisation of ds->w and ds->h in guess.c, which I'd accidentally removed during game_size() refactoring - reorganise Net's interpret_move() so that my uncommitted patch for drag-based UI (which he uses on the Palm port) will apply more easily - the interpret_move() changes make it easy to have a single move type which rotates a tile by 180 degrees, so this is now provided via the `F' key (but there's no spare button available to provide it via the mouse). [originally from svn r6070]
* Add a `full' parameter to validate_params(), analogous to the one inJacob Nevins2005-07-05
| | | | | | | | | | | 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]
* Refactored the game_size() interface, which was getting reallySimon Tatham2005-07-05
| | | | | | | | | | | | | 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]
* draw_polygon() and draw_circle() have always had a portabilitySimon Tatham2005-07-03
| | | | | | | | | | | | | | | | | | | 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]
* New {en,de}code_ui functions should be static. Oops.Simon Tatham2005-06-28
| | | | [originally from svn r6031]
* More serialisation changes: the game_aux_info structure has now beenSimon Tatham2005-06-28
| | | | | | | | | | | | 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]
* Move a rogue declaration to the top of its block.Simon Tatham2005-06-28
| | | | [originally from svn r6027]
* Another function pair required for serialisation; these ones saveSimon Tatham2005-06-28
| | | | | | | | | | | 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]
* Re-architecting of the game backend interface. make_move() has beenSimon Tatham2005-06-27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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]
* Infrastructure change which I've been thinking about for a while:Simon Tatham2005-06-17
| | | | | | | the back end function solve_game() now takes the _current_ game_state in addition to the initial one. [originally from svn r5969]
* Another James Harvey patch. This one introduces a new button codeSimon Tatham2005-06-07
| | | | | | | | | | | called `CURSOR_SELECT', intended for platforms which have a fire button to go with their cursor keys. (Apparently some Palms do.) CURSOR_SELECT is not bound to anything on any of the current three platforms, and therefore no game may rely on it being available. This checkin adds it in Net as a synonym for 'a', the keyboard-based rotate-left command. [originally from svn r5915]
* All the games in this collection have always defined their graphicsSimon Tatham2005-06-07
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | in terms of a constant TILE_SIZE (or equivalent). Here's a surprisingly small patch which switches this constant into a run-time variable. The only observable behaviour change should be on Windows, which physically does not permit the creation of windows larger than the screen; if you try to create a puzzle (Net makes this plausible) large enough to encounter this restriction, the Windows front end should automatically re-adjust the puzzle's tile size so that it does fit within the available space. On GTK, I haven't done this, on the grounds that X _does_ permit windows larger than the screen, and many X window managers already provide the means to navigate around such a window. Gareth said he'd rather navigate around a huge Net window than have it shrunk to fit on one screen. I'm uncertain that this makes sense for all puzzles - Pattern in particular strikes me as something that might be better off shrunk to fit - so I may have to change policy later or make it configurable. On OS X, I also haven't done automatic shrinkage to fit on one screen, largely because I didn't have the courage to address the question of multiple monitors and what that means for the entire concept :-) [originally from svn r5913]
* Introduce a new game backend function (there seem to have been a lotSimon Tatham2005-06-06
| | | | | | | | | | | | | | | | | | | of these recently) whose job is to update a game_ui to be consistent with a new game_state. This is called by midend.c in every situation where the current game_state changes _other_ than as a result of make_move (Undo, Redo, Restart, Solve). The introduction of this function allows a game_ui to contain information about selections or highlights within a game_state which simply wouldn't make sense when transferred to another game_state. In particular, I've used it to fix a subtle bug in Solo whereby, although you couldn't right-click to pencil-mode highlight a filled square, you could _get_ a pencil-mode highlight in a filled square if you used Undo and Redo. (Undo to before the square was filled, right-click to highlight it, then Redo. Alternatively, left-click and clear the square, right-click to highlight it, then Undo.) [originally from svn r5912]
* James Harvey requested that puzzles not use DEBUG as a preprocessorSimon Tatham2005-06-04
| | | | | | | | | symbol for enabling diagnostics, presumably because in his Palm port it means something else as well. He sent this patch to switch Net and Netslide over to using GENERATION_DIAGNOSTICS, in the fashion of the newer games. [originally from svn r5908]
* Fix various departures from C found by `gcc -ansi -pedantic'. ISimon Tatham2005-06-02
| | | | | | | haven't checked in Makefile changes to enable this, but I'll at least fix the specific problems it found when enabled as a one-off. [originally from svn r5902]
* Miscellaneous fixes from James Harvey's PalmOS porting work:Simon Tatham2005-06-01
| | | | | | | | | | | | | | | | | | | | - fixed numerous memory leaks (not Palm-specific) - corrected a couple of 32-bit-int assumptions (vital for Palm but generally a good thing anyway) - lifted a few function pointer types into explicit typedefs (neutral for me but convenient for the source-munging Perl scripts he uses to deal with Palm code segment rules) - lifted a few function-level static arrays into global static arrays (neutral for me but apparently works round a Palm tools bug) - a couple more presets in Rectangles (so that Palm, or any other slow platform which can't handle the larger sizes easily, can still have some variety available) - in Solo, arranged a means of sharing scratch space between calls to nsolve to prevent a lot of redundant malloc/frees (gives a 10% speed increase even on existing platforms) [originally from svn r5897]
* Better mouse button handling in Mines:Simon Tatham2005-05-31
| | | | | | | | | | | | | - middle button now also triggers the clear-around-square action - a special-case handler in midend_process_key() arranges that the left button always trumps the right button if both are pressed together, meaning that Windows Minesweeper players used to pressing L+R to clear around a square should still be able to do so without any strange behaviour. (The latter touches all game backends, yet again, to add a field to the game structure which is zero in everything except Mines.) [originally from svn r5888]
* Move definition of PI into puzzles.h. If nothing else, the definition in cube.cJacob Nevins2005-05-31
| | | | | | had a typo :) [originally from svn r5878]
* Mouse-based interface for Cube: you left-click anywhere on the gridSimon Tatham2005-05-31
| | | | | | | | | | | | | | | 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]
* Added an `interactive' flag to new_game_desc(), which toggles MinesSimon Tatham2005-05-30
| | | | | | | | | 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]
* First cut at a game timer. Yet another backend function whichSimon Tatham2005-05-30
| | | | | | | | | | | | | | | 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]
* Mines now follows the conventional approach of offering a completelySimon Tatham2005-05-30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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]
* Infrastructure change: game_anim_length and game_flash_length nowSimon Tatham2005-05-30
| | | | | | | | | both get passed a pointer to the game_ui. This means that if they need to note down information for the redraw function about what _type_ of flash or animation is required, they now have somewhere to do so. [originally from svn r5858]
* Sorted out the barriers/corners trouble left by r5844. No wonderSimon Tatham2005-05-26
| | | | | | | | | | | | | | | | | | | | Jacob wasn't able to find a satisfactory fix: the whole area was a horrid mess. Fortunately, the reason it was a horrid mess was because the Net drawing routines predated the introduction of clip() in the frontend interface, and it turns out that clip() makes it possible to do all this more easily and better. So, a complete rearchitecting of barrier corners: the corner flags in the `barriers' array are now gone (and good riddance), and corner information is computed on the fly so as to take into account the moving grid edges. In the process I've also updated the corner mechanism so that a barrier `corner' (really endpoint) is drawn at the end of _every_ barrier, not just where two meet. This has changed the appearance of a single isolated barrier, to what I would have wanted it to look like in the first place but achieving it without clip() was just too fiddly. [originally from svn r5846] [r5844 == 865e8ad6ca3d83ad2a585ceeb1809e9f68c18a20]
* Add origin-shifting (Shift+cursors) and source-shifting (Ctrl+cursors) to Net.Jacob Nevins2005-05-26
| | | | | | | | | | | | (Adding modifier+cursors handling has had minor knock-on effects on the other puzzles, so that they can continue to ignore modifiers.) (An unfortunate side effect of this is some artifacts in exterior barrier drawing; notably, a disconnected corner can now appear at the corner of the grid under some circumstances. I haven't found a satisfactory way round this yet.) [originally from svn r5844]
* Net hangs if you ask it for a 2xn or nx2 wrapping puzzle with aSimon Tatham2005-05-23
| | | | | | | | | | | unique solution. This, it turns out, is because there is literally no such thing. Protective constraint added to validate_params(), with a proof in a comment alongside. If you really want a 2xn or nx2 wrapping puzzle, you can still have one if you turn uniqueness off. [originally from svn r5835]
* Another tweak to the solver to make it handle blank tiles correctly.Simon Tatham2005-05-22
| | | | | | | | The previous checkin stopped it choking on them, but it didn't actually manage to _deduce_ that all the edges bordering them had to be closed. Now it does better. [originally from svn r5829]
* Special case in dead-end checking which prevents the solver fallingSimon Tatham2005-05-22
| | | | | | | | | | | | over on a grid containing a 0 (completely blank) tile. This can't happen in self-generated grids, but can happen if you type in a grid from another Net implementation. Previously, the solver would notice (technically correctly!) that a completely blank tile connects to no other tiles and thus forms an isolated subgraph, and would therefore complain that no orientation of that tile could possibly yield a valid solution... [originally from svn r5828]
* The Net solver now makes use of barrier information when applied toSimon Tatham2005-05-22
| | | | | | a typed-in grid. [originally from svn r5827]
* Cleanups:Simon Tatham2005-05-21
| | | | | | | | | - fix documentation of Net's unique solution option (should have tested before last checkin) - make unique solutions optional in Rectangles too (same reasons) - tidy up various issues in parameter encoding in both games. [originally from svn r5818]
* Solution uniqueness for Net. Can be disabled on request (but isSimon Tatham2005-05-21
| | | | | | | | enabled by default), since ambiguous sections in grids can present additional interesting challenges. I think uniqueness is a better default, though. [originally from svn r5816]
* Null-terminate generated Net/Netslide descriptive game IDs.Jacob Nevins2005-05-17
| | | | [originally from svn r5794]
* The game IDs for Net (and Netslide) have always been random seedsSimon Tatham2005-05-16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | rather than literal grid descriptions, which has always faintly annoyed me because it makes it impossible to type in a grid from another source. However, Gareth pointed out that short random-seed game descriptions are useful, because you can read one out to someone else without having to master the technology of cross- machine cut and paste, or you can have two people enter the same random seed simultaneously in order to race against each other to complete the same puzzle. So both types of game ID seem to have their uses. Therefore, here's a reorganisation of the whole game ID concept. There are now two types of game ID: one has a parameter string then a hash then a piece of arbitrary random seed text, and the other has a parameter string then a colon then a literal game description. For most games, the latter is identical to the game IDs that were previously valid; for Net and Netslide, old game IDs must be translated into new ones by turning the colon into a hash, and there's a new descriptive game ID format. Random seed IDs are not guaranteed to be portable between software versions (this is a major reason why I added version reporting yesterday). Descriptive game IDs have a longer lifespan. As an added bonus, I've removed the sections of documentation dealing with game parameter encodings not shown in the game ID (Rectangles expansion factor, Solo symmetry and difficulty settings etc), because _all_ parameters must be specified in a random seed ID and therefore users can easily find out the appropriate parameter string for any settings they have configured. [originally from svn r5788]
* Added an automatic `Solve' feature to most games. This is useful forSimon Tatham2005-05-02
| | | | | | | | | | | | | | | | various things: - if you haven't fully understood what a game is about, it gives you an immediate example of a puzzle plus its solution so you can understand it - in some games it's useful to compare your solution with the real one and see where you made a mistake - in the rearrangement games (Fifteen, Sixteen, Twiddle) it's handy to be able to get your hands on a pristine grid quickly so you can practise or experiment with manoeuvres on it - it provides a good way of debugging the games if you think you've encountered an unsolvable grid! [originally from svn r5731]
* Introduce the concept of a `game_aux_info' structure. This isSimon Tatham2005-05-02
| | | | | | | | | | constructed at the same time as an internally generated game seed, so that it can preserve any interesting information known by the program at generation time but not physically contained within the text of the game seed itself. (Such as, for example, the solution.) Currently not used for anything yet, but it will be. [originally from svn r5729]
* Introduced a new function in every game which formats a game_stateSimon Tatham2005-05-01
| | | | | | | | as text. This is used by front ends to implement copy-to-clipboard. Currently the function does nothing (and is disabled) in every game except Solo, but it's a start. [originally from svn r5724]
* I can never remember what that `TRUE' means in the game structureSimon Tatham2005-05-01
| | | | | | | | | definitions, so let's move it so that it's just next to the functions it relates to. This also opens the way for me to add more booleans next to other functions without getting confused as to which is which. [originally from svn r5723]
* Rather than each game backend file exporting a whole load ofSimon Tatham2005-01-17
| | | | | | | | | | functions and a couple of variables, now each one exports a single structure containing a load of function pointers and said variables. This should make it easy to support platforms on which it's sensible to compile all the puzzles into a single monolithic application. The two existing platforms are still one-binary-per-game. [originally from svn r5126]
* Add a `jumble' key (`J') to Net, which scrambles the positions of all unlockedJacob Nevins2004-12-22
| | | | | | | | | | tiles randomly. (Rachel asked for this; it's been being tested for a good few months now, and Simon didn't care either way, so in it goes :) As part of this, the front end can now be asked to provide a random random seed (IYSWIM). [originally from svn r5019]
* Net's redraw function now uses the `dir' argument to determine whether it'sJacob Nevins2004-08-16
| | | | | | redrawing an undo. Seems to work. [originally from svn r4470]
* After discussion with Simon, the game redraw functions are now passed a newJacob Nevins2004-08-16
| | | | | | | | | argument `dir' which tells them whether this redraw is due to an undo, rather than have them second-guess it from game state. Note that none of the actual games yet take advantage of this; so it hasn't been tested in anger (although it has been inspected by debugging). [originally from svn r4469]
* UI nit: make cursor visible upon use of A/S/D keyboard controls.Jacob Nevins2004-08-16
| | | | [originally from svn r4467]
* Added a help file, mostly thanks to Jacob.Simon Tatham2004-08-16
| | | | [originally from svn r4460]
* Introduce routines in each game module to encode a set of gameSimon Tatham2004-05-19
| | | | | | | | | | | | parameters as a string, and decode it again. This is used in midend.c to prepend the game parameters to the game seed, so that copying out of the Specific box is sufficient to completely specify the game you were playing. Throughout development of these games I have referred to `seed' internally, and `game ID' externally. Now there's a measurable difference between them! :-) [originally from svn r4231]
* Now we have the UI abstraction, use it to implement keyboard controlSimon Tatham2004-05-11
| | | | | | in Net. [originally from svn r4214]