{
 "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'<img src=\"{ img_path }\" style=\"float:left;\">'\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'<img src=\"{ piece }\" style=\"float:left;\">'\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
}
