For a while now, I've been looking for a method to randomly generate a map of fake (but realistic-looking) countries. Since I haven't had much success yet (even after asking about it online once already), I thought I'd ask this community now.
Here are the principles that I want the final map to follow:
- Borders should be somewhat crinkly (fractal dimension around 1.1).
- Countries should be somewhat disparate in size (ratio of areas of largest and smallest countries perhaps around 1.5-3; I'm not as sure about the specifics of this one, but I can definitely tell when it looks wrong).
- Countries should be relatively contiguous and isthmus-free.
Code: Select all
import golly as g # starts from initial pattern NUMITERATIONS=int(g.getstring("How many iterations?","4")) DENSITY=int(g.getstring("How dense is the soup (in %)?","25")) MARGIN=int(g.getstring("How wide are the margins?","16")) g.setrule("B5678/S45678") g.autoupdate(True) for i in range(NUMITERATIONS): VIOLINIST=g.getrect() CELLIST=g.getcells(VIOLINIST) g.new("") g.setstep(4) g.select([-MARGIN,-MARGIN,2*(VIOLINIST+MARGIN),2*(VIOLINIST+MARGIN)]) g.randfill(DENSITY) g.fit() # eliminate chance islands CHANGES="" while True: # run to stabilization THISHASH=g.hash(g.getselrect()) while True: g.step() NEXTHASH=g.hash(g.getselrect()) if THISHASH==NEXTHASH: break THISHASH=NEXTHASH # check for chance islands if g.empty(): g.reset() break else: # futility check (very rare but can happen) if CHANGES==g.getcells(g.getselrect()): break CHANGES=g.getcells(g.getselrect()) g.reset() g.putcells(CHANGES,0,0,1,0,0,1,"xor") # xor-paste in original pattern at double scale g.putcells(CELLIST,-2*VIOLINIST,-2*VIOLINIST,2,0,0,2,"xor") g.putcells(CELLIST,-2*VIOLINIST,1-2*VIOLINIST,2,0,0,2,"xor") g.putcells(CELLIST,1-2*VIOLINIST,-2*VIOLINIST,2,0,0,2,"xor") g.putcells(CELLIST,1-2*VIOLINIST,1-2*VIOLINIST,2,0,0,2,"xor") # run to stabilization THISHASH=g.hash(g.getselrect()) while True: g.step() NEXTHASH=g.hash(g.getselrect()) if THISHASH==NEXTHASH: break THISHASH=NEXTHASH g.select()
However, I haven't been as successful with multiple countries fitting together. Here are some types of rules that I've tried:
- Multi-state rules where each individual cellstate follows B5678/S45678: size of countries becomes way too disparate with few states; simulation gets way too slow with many states.
- Rules where seeds form and grow but resist merging (e.g. B15-knqr6a78/S4-nwz5-kr678): this creates a rather large size disparity between regions.
- Rules where cells naturally settle into a skeleton-like structure (e.g. R20,C0,M1,S167..646,B604..877,NM): while the countries-to-be are placed rather well, their borders are too smooth, and there's even a slight chance of border failure.
- Rules based on crystallographic defects (e.g. B2ce3cn4acknwy5aekry6akn7e/S1e2aei3ciny4jknqry5-cjny6k7c, possibly interesting in its own right): while the result is four-colorable (colors correspond to parities of x- and y-coordinates), it's not very realistic, due to two adjacent regions of the same color effectively being considered as one.
- Multi-state rules where each individual cellstate follows the same explosive rule: this has problems similar to the ones in the other multi-state rule, except that the problem with too many cellstates is that the seeds won't grow.
- Voronoi diagrams: these create a pretty good starting point, but their borders are always completely and unrealistically straight.
- Mudcracks: modeling these is only easy via the real thing (which takes a while), and suffers from the straight-borders problem.
- DFS maze-generation algorithm from multiple starting points: this frequently generates one-cell-thick isthmuses.
- Prim's algorithm from multiple starting points: many countries generated this way seem to be long and skinny.
- Kruskal's algorithm from multiple starting points: borders seem to be a bit too crinkly.