{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Generating maps"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## A*maze*ing maps with game assets\n",
"\n",
"Our journey begins here...\n",
"\n",
"https://www.kenney.nl/assets/cartography-pack"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true,
"tags": []
},
"outputs": [],
"source": [
"!wget \"https://www.kenney.nl/content/3-assets/26-cartography-pack/cartographypack.zip\"\n",
"!mkdir cartographypack\n",
"!unzip cartographypack.zip -d cartographypack"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!ls cartographypack/PNG/Default/path*"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from glob import glob\n",
"import os\n",
"from IPython.display import display, HTML\n",
"\n",
"html = \"\"\n",
"\n",
"for img_path in glob(\"cartographypack/PNG/Default/path*\"):\n",
"\n",
" html += f''\n",
"\n",
"display(HTML(html))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from random import choice\n",
"\n",
"pieces = glob(\"cartographypack/PNG/Default/path*\")\n",
"html = \"\"\n",
"\n",
"for i in range(100):\n",
" piece = choice(pieces)\n",
" html += f''\n",
" \n",
"display(HTML(html))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Stepping away from random.choice(): writing an algorithm to generate patterns"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"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.\n",
"\n",
"### moving through the canvas\n",
"\n",
"Each character on our \"canvas\" has a specific position and thus is connected to a `x` and `y` coordinate.\n",
"\n",
"How can we do that?\n",
"\n",
"We will use a `list-of-lists`... or in other words: \n",
"\n",
"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**). \n",
"\n",
"To make this `list-of-lists`, we will use a `loop-in-a-loop`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"width = 10\n",
"height = 10\n",
"\n",
"canvas = []\n",
"\n",
"for y in range(height):\n",
" \n",
" row = []\n",
"\n",
" for x in range(width):\n",
" row.append(x)\n",
" \n",
" canvas.append(row)\n",
" \n",
"print(canvas)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's print the canvas row for row, to make it easier to see it as a x-y canvas:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for row in canvas:\n",
" print(row)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"And let's bring it back into an plain text pattern: turn this `list-of-lists` into a `multiline string`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# canvas is our list-of-lists\n",
"# canvas_string is the plain text version that we want to create\n",
"\n",
"canvas_string = ''\n",
"\n",
"for row in canvas:\n",
" row_string = ''\n",
" for character in row:\n",
" row_string += str(character)\n",
" canvas_string += row_string + \"\\n\"\n",
"\n",
"print(canvas_string)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's save this as a function that we can reuse later!"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def plain(canvas):\n",
" canvas_string = ''\n",
" for row in canvas:\n",
" row_string = \"\".join(row)\n",
" canvas_string += row_string + \"\\n\"\n",
"\n",
" return canvas_string"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now, we can work with the `x` and `y` axes of the canvas, by *slicing* the `canvas`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"canvas[0][0]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"canvas[1][9]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### My first algorithm"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let's write a short algorithm, to generate a map.\n",
"\n",
"We will start by writing the **rules** of our algorithm.\n",
"\n",
"Let's first think of these rules without writing them in code. \n",
"\n",
"How would you like to generate a pattern?\n",
"\n",
"For example: \n",
"\n",
"**Characters**\n",
"\n",
"* `.` is used as background\n",
"* `░` as light shade\n",
"* `▒` as darker shade\n",
"\n",
"**Rules** \n",
"\n",
"* `░` always appears in horizontal ánd vertical blocks of 3\n",
"\n",
"```\n",
".....\n",
"..░..\n",
".░░░.\n",
"..░..\n",
".....\n",
"```\n",
"\n",
"* `▒` surrounds the blobs of light shade on the left side of each light shadow \n",
"\n",
"```\n",
".....\n",
".▒░..\n",
"▒░░░.\n",
".▒░..\n",
".....\n",
"```\n",
"\n",
"Let's try this!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First we create a new canvas and fill it with `.`'s."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"width = 100\n",
"height = 25\n",
"\n",
"canvas = []\n",
"for y in range(height):\n",
" row = []\n",
" for x in range(width):\n",
" row.append('.')\n",
" canvas.append(row)\n",
"\n",
"print(plain(canvas))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let's add the light shade..."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from random import randrange\n",
"\n",
"light_shade = '░'\n",
"\n",
"for y in range(height):\n",
" for x in range(width):\n",
" \n",
" # To work with a degree of chance, \n",
" # we \"roll the dice\" and only add a ░\n",
" # when the number is lower then 5\n",
" random_number = randrange(0, 100, 1)\n",
" if random_number < 3: \n",
" \n",
" # If so, then we add a ░\n",
" canvas[y][x] = light_shade\n",
" \n",
" # Check is there is a character on the left, right, \n",
" # top and bottom AT ALL, before adding them...\n",
" if x - 1 >= 0:\n",
" canvas[y][x - 1] = light_shade\n",
" if x + 1 < width:\n",
" canvas[y][x + 1] = light_shade\n",
" if y - 1 >= 0:\n",
" canvas[y - 1][x] = light_shade\n",
" if y + 1 < height:\n",
" canvas[y + 1][x] = light_shade\n",
" \n",
" else:\n",
" continue\n",
" \n",
"print(plain(canvas))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let's add the darker shade..."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from random import randrange\n",
"\n",
"light_shade = '░'\n",
"darker_shade = '▒'\n",
"\n",
"for y in range(height):\n",
" for x in range(width):\n",
" \n",
" # First we check if the current character is a light shade\n",
" if canvas[y][x] == light_shade:\n",
" \n",
" # 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\n",
" \n",
" # Check is there is a left character AT ALL\n",
" if x - 1 >= 0:\n",
" # If so, then we check if the left character is a '.'\n",
" if canvas[y][x - 1] == '.':\n",
" # If so, then we replace it with a dark shade\n",
" canvas[y][x - 1] = '▒'\n",
" \n",
" else:\n",
" continue\n",
" \n",
"print(plain(canvas))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "raw",
"metadata": {},
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Could we make a maze generator with the cartographypack now?\n",
"\n",
":---)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}