11 KiB
Generating maps¶
Amazeing maps with game assets¶
Our journey begins here...
!wget "https://www.kenney.nl/content/3-assets/26-cartography-pack/cartographypack.zip" !mkdir cartographypack !unzip cartographypack.zip -d cartographypack
!ls cartographypack/PNG/Default/path*
from glob import glob import os from IPython.display import display, HTML html = "" for img_path in glob("cartographypack/PNG/Default/path*"): html += f'<img src="{ img_path }" style="float:left;">' display(HTML(html))
from random import choice pieces = glob("cartographypack/PNG/Default/path*") html = "" for i in range(100): piece = choice(pieces) html += f'<img src="{ piece }" style="float:left;">' display(HTML(html))
Stepping away from random.choice(): writing an algorithm to generate patterns¶
In order to generate patterns in a non-random way, we might want to move around through our canvas in a non-linear way, to make the patterns a bit more complex.
moving through the canvas¶
Each character on our "canvas" has a specific position and thus is connected to a x
and y
coordinate.
How can we do that?
We will use a list-of-lists
... or in other words:
we make one big list, that contains a # of rows (the y
axis, or height of the canvas), with a # of characters (the x
axis, or width of the canvas).
To make this list-of-lists
, we will use a loop-in-a-loop
:
width = 10 height = 10 canvas = [] for y in range(height): row = [] for x in range(width): row.append(x) canvas.append(row) print(canvas)
Let's print the canvas row for row, to make it easier to see it as a x-y canvas:
for row in canvas: print(row)
And let's bring it back into an plain text pattern: turn this list-of-lists
into a multiline string
:
# canvas is our list-of-lists # canvas_string is the plain text version that we want to create canvas_string = '' for row in canvas: row_string = '' for character in row: row_string += str(character) canvas_string += row_string + "\n" print(canvas_string)
Let's save this as a function that we can reuse later!
def plain(canvas): canvas_string = '' for row in canvas: row_string = "".join(row) canvas_string += row_string + "\n" return canvas_string
Now, we can work with the x
and y
axes of the canvas, by slicing the canvas
:
canvas[0][0]
canvas[1][9]
My first algorithm¶
Now let's write a short algorithm, to generate a map.
We will start by writing the rules of our algorithm.
Let's first think of these rules without writing them in code.
How would you like to generate a pattern?
For example:
Characters
.
is used as background░
as light shade▒
as darker shade
Rules
░
always appears in horizontal ánd vertical blocks of 3
.....
..░..
.░░░.
..░..
.....
▒
surrounds the blobs of light shade on the left side of each light shadow
.....
.▒░..
▒░░░.
.▒░..
.....
Let's try this!
First we create a new canvas and fill it with .
's.
width = 100 height = 25 canvas = [] for y in range(height): row = [] for x in range(width): row.append('.') canvas.append(row) print(plain(canvas))
Now let's add the light shade...
from random import randrange light_shade = '░' for y in range(height): for x in range(width): # To work with a degree of chance, # we "roll the dice" and only add a ░ # when the number is lower then 5 random_number = randrange(0, 100, 1) if random_number < 3: # If so, then we add a ░ canvas[y][x] = light_shade # Check is there is a character on the left, right, # top and bottom AT ALL, before adding them... if x - 1 >= 0: canvas[y][x - 1] = light_shade if x + 1 < width: canvas[y][x + 1] = light_shade if y - 1 >= 0: canvas[y - 1][x] = light_shade if y + 1 < height: canvas[y + 1][x] = light_shade else: continue print(plain(canvas))
Now let's add the darker shade...
from random import randrange light_shade = '░' darker_shade = '▒' for y in range(height): for x in range(width): # First we check if the current character is a light shade if canvas[y][x] == light_shade: # If that is the case, we need to look around, to see if we need to place a shade on the left, right, top or bottom # Check is there is a left character AT ALL if x - 1 >= 0: # If so, then we check if the left character is a '.' if canvas[y][x - 1] == '.': # If so, then we replace it with a dark shade canvas[y][x - 1] = '▒' else: continue print(plain(canvas))
Could we make a maze generator with the cartographypack now?¶
:---)