aboutsummaryrefslogtreecommitdiff
path: root/grid.h (follow)
Commit message (Collapse)AuthorAge
* grid.c: allocate face/edge/dot arrays incrementally.Simon Tatham2023-07-07
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously, the 'faces', 'edges' and 'dots' arrays in a grid structure were arrays of actual grid_face, grid_edge and grid_dot structures, physically containing all the data about the grid. But they also referred to each other by pointers, which meant that they were hard to realloc larger (you'd have to go through and rewrite all the pointers whenever the base of an array moved). And _that_ meant that every grid type had to figure out a reasonably good upper bound on the number of all those things it was going to need, so that it could allocate those arrays the right size to begin with, and not have to grow them painfully later. For some grid types - particularly the new aperiodic ones - that was actually a painful part of the job. So I think enough is enough: counting up how much memory you're going to need before using it is a mug's game, and we should instead realloc on the fly. So now g->faces, g->edges and g->dots have an extra level of indirection. Instead of being arrays of actual structs, they're arrays of pointers, and each struct in them is individually allocated. Once a grid_face has been allocated, it never moves again, even if the array of pointers changes size. The old code had a common idiom of recovering the array index of a particular element by subtracting it from the array base, e.g. writing 'f - g->faces' or 'e - g->edges'. To make that lookup remain possible, I've added an 'index' field to each sub-structure, which is initialised at the point where we decide what array index it will live at. This should involve no functional change, but the code that previously had to figure out max_faces and max_dots up front for each grid type is now completely gone, and nobody has to solve those problems in advance any more.
* Loopy / grid.c: support the new Spectre monotiling.Simon Tatham2023-06-16
| | | | | | | | | | | | | | This uses a tile shape very similar to the hat, but the tiling _structure_ is totally changed so that there aren't any reflected copies of the tile. I'm not sure how much difference this makes to gameplay: the two tilings are very similar for Loopy purposes. But the code was fun to write, and I think the Spectre shape is noticeably prettier, so I'm adding this to the collection anyway. The test programs also generate a pile of SVG images used in the companion article on my website.
* Loopy / grid.c: new grid type, 'Hats'.Simon Tatham2023-03-26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The big mathematical news this month is that a polygon has been discovered that will tile the plane but only aperiodically. Penrose tiles achieve this with two tile types; it's been an open question for decades whether you could do it with only one tile. Now someone has announced the discovery of such a thing, so _obviously_ this mathematically exciting tiling ought to be one of the Loopy grid options! The polygon, named a 'hat' by its discoverers, consists of the union of eight cells of the 'Kites' periodic tiling that Loopy already implements. So all the vertex coordinates of the whole tiling are vertices of the Kites grid, which makes handling the coordinates in an exact manner a lot easier than Penrose tilings. What's _harder_ than Penrose tilings is that, although this tiling can be generated by a vaguely similar system of recursive expansion, the expansion is geometrically distorting, which means you can't easily figure out which tiles can be discarded early to save CPU. Instead I've come up with a completely different system for generating a patch of tiling, by using a hierarchical coordinate system to track a location within many levels of the expansion process without ever simulating the process as a whole. I'm really quite pleased with that technique, and am tempted to try switching the Penrose generator over to it too - except that we'd have to keep the old generator around to stop old game ids being invalidated, and also, I think it would be slightly trickier without an underlying fixed grid and without overlaps in the tile expansion system. However, before coming up with that, I got most of the way through implementing the more obvious system of actually doing the expansions. The result worked, but was very slow (because I changed approach rather than try to implement tree-pruning under distortion). But the code was reusable for two other useful purposes: it generated the lookup tables needed for the production code, and it also generated a lot of useful diagrams. So I've committed it anyway as a supporting program, in a new 'aux' source subdirectory, and in aux/doc is a writeup of the coordinate system's concepts, with all those diagrams. (That's the kind of thing I'd normally put in a huge comment at the top of the file, but doing all those diagrams in ASCII art would be beyond miserable.) From a gameplay perspective: the hat polygon has 13 edges, but one of them has a vertex of the Kites tiling in the middle, and sometimes two other tile boundaries meet at that vertex. I've chosen to represent every hat as having degree 14 for Loopy purposes, because if you only included that extra vertex when it was needed, then people would be forever having to check whether this was a 13-hat or a 14-hat and it would be nightmarish to play. Even so, there's a lot of clicking involved to turn all those fiddly individual edges on or off. This grid is noticeably nicer to play in 'autofollow' mode, by setting LOOPY_AUTOFOLLOW in the environment to either 'fixed' or 'adaptive'. I'm tempted to make 'fixed' the default, except that I think it would confuse players of ordinary square Loopy!
* Limit maximum grid size in LoopyBen Harris2023-01-15
| | | | | | | | | | Every grid shape has its own limit, so this involved adding a new interface between loopy.c and grid.c. The limits are based on ensuring that the co-ordinate system of the grid doesn't overflow INT_MAX and neither do the lengths of the face and dot arrays. Though now I come to look at it I think the actual limits of grid.c are much lower. Hmm.
* New grid type: compass dodecagonalMichael Quevillon2021-04-22
| | | | | | A grid based on dodecagons with square symmetry. In between dodecagons there are 4 triangles around 1 square, which resembles a compass rose. https://en.wikipedia.org/wiki/3-4-3-12_tiling
* Adopt C99 bool in the grid.c API.Simon Tatham2018-11-13
| | | | | More or less trivially: the only affected declaration is the has_incentre flag in struct grid_face.
* New grid type: the trihexagonal tiling, or 'kagome lattice'.Simon Tatham2017-11-18
| | | | | | | | Regular hexagons and equilateral triangles in strict alternation, with two of each interleaved around each vertex. https://en.wikipedia.org/wiki/Trihexagonal_tiling Thanks to Michael Quevillon for the patch.
* Make the code base clean under -Wwrite-strings.Simon Tatham2017-10-01
| | | | | I've also added that warning option and -Werror to the build script, so that I'll find out if I break this property in future.
* New Loopy tiling: 'Great Great Dodecagonal'.Simon Tatham2017-04-24
| | | | | | | | Officially known as the '3-4-6-12 tiling', according to, e.g., https://en.wikipedia.org/wiki/3-4-6-12_tiling . Thanks to Michael Quevillon for contributing this patch (and for choosing a less hard-to-remember name for the tiling :-).
* Giant const patch of doom: add a 'const' to every parameter in everySimon Tatham2013-04-13
| | | | | | | | | | | | | | puzzle backend function which ought to have it, and propagate those consts through to per-puzzle subroutines as needed. I've recently had to do that to a few specific parameters which were being misused by particular puzzles (r9657, r9830), which suggests that it's probably a good idea to do the whole lot pre-emptively before the next such problem shows up. [originally from svn r9832] [r9657 == 3b250baa02a7332510685948bf17576c397b8ceb] [r9830 == 0b93de904a98f119b1a95d3a53029f1ed4bfb9b3]
* From James Harvey (via a period of collaborative polishing), a patchSimon Tatham2011-04-24
| | | | | | | | | | | | | | | | | | to add two kinds of Penrose tiling to the grid types supported by Loopy. This has involved a certain amount of infrastructure work, because of course the whole point of Penrose tilings is that they don't have to be the same every time: so now grid.c has grown the capacity to describe its grids as strings, and reconstitute them from those string descriptions. Hence a Penrose Loopy game description consists of a string identifying a particular piece of Penrose tiling, followed by the normal Loopy clue encoding. All the existing grid types decline to provide a grid description string, so their Loopy game descriptions have not changed encoding. [originally from svn r9159]
* Move most of face_text_pos() into grid.c, leaving in loopy.c only theSimon Tatham2011-04-23
| | | | | | | | | | part that converts from abstract grid coordinates into screen coordinates. This should speed up window-resizing by eliminating pointless reiteration of the complicated part of the algorithm: now when a game_drawstate is renewed, only the conversion into screen coordinates has to be redone. [originally from svn r9157]
* Another patch from Chris Moore implementing two more grid types, bothSimon Tatham2011-02-24
| | | | | | involving dodecagons. [originally from svn r9109]
* Retire the 'middle_face' field in 'struct grid', together with theSimon Tatham2011-02-24
| | | | | | | | | | | overly complicated algorithm that uses it to home in on the grid edge closest to a mouse click. That algorithm is being stressed beyond its limit by the new grid type, and it's unnecessary anyway given that no sensibly sized puzzle grid is going to be big enough to make it prohibitively expensive just to do the trivial approach of iterating over all edges and finding the closest of the eligible ones. [originally from svn r9108]
* Patch from Chris Moore to implement an extra grid type, the 'floret'Simon Tatham2011-02-23
| | | | | | pentagonal tiling. [originally from svn r9107]
* How did I manage to check this in without actually trying to buildSimon Tatham2008-09-07
| | | | | | | | | on Windows at all?! Fix some departures from the C standard, mostly declaring variables after a statement has already been issued in the same block. MSVC is picky about this where gcc is forgiving, and TBH I'd change the latter given the choice. [originally from svn r8166]
* Completely re-engineered version of Loopy, courtesy of LambrosSimon Tatham2008-09-06
Lambrou. Now capable of handling triangular and hexagonal grids as well as square ones, and then a number of semiregular plane tilings and duals of semiregular ones. In fact, most of the solver code supports an _arbitrary_ planar graph (well, provided both the graph and its dual have no self-edges), so it could easily be extended further with only a little more effort. [originally from svn r8162]