{ "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 }