{ "cells": [ { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2 2\n", "2 2\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Traceback (most recent call last):\n", " File \"C:\\ProgramData\\Anaconda3\\lib\\site-packages\\matplotlib\\cbook\\__init__.py\", line 388, in process\n", " proxy(*args, **kwargs)\n", " File \"C:\\ProgramData\\Anaconda3\\lib\\site-packages\\matplotlib\\cbook\\__init__.py\", line 228, in __call__\n", " return mtd(*args, **kwargs)\n", " File \"C:\\ProgramData\\Anaconda3\\lib\\site-packages\\matplotlib\\animation.py\", line 1308, in _handle_resize\n", " self._init_draw()\n", " File \"C:\\ProgramData\\Anaconda3\\lib\\site-packages\\matplotlib\\animation.py\", line 1750, in _init_draw\n", " self._draw_frame(next(self.new_frame_seq()))\n", " File \"C:\\ProgramData\\Anaconda3\\lib\\site-packages\\matplotlib\\animation.py\", line 1772, in _draw_frame\n", " self._drawn_artists = self._func(framedata, *self._args)\n", " File \"\", line 268, in updatefig\n", " im1=plt.imshow(Zm, cmap=plt.get_cmap('magma').with_extremes(bad='#101020'))\n", "AttributeError: 'ListedColormap' object has no attribute 'with_extremes'\n", "Traceback (most recent call last):\n", " File \"C:\\ProgramData\\Anaconda3\\lib\\site-packages\\matplotlib\\cbook\\__init__.py\", line 388, in process\n", " proxy(*args, **kwargs)\n", " File \"C:\\ProgramData\\Anaconda3\\lib\\site-packages\\matplotlib\\cbook\\__init__.py\", line 228, in __call__\n", " return mtd(*args, **kwargs)\n", " File \"C:\\ProgramData\\Anaconda3\\lib\\site-packages\\matplotlib\\animation.py\", line 1308, in _handle_resize\n", " self._init_draw()\n", " File \"C:\\ProgramData\\Anaconda3\\lib\\site-packages\\matplotlib\\animation.py\", line 1750, in _init_draw\n", " self._draw_frame(next(self.new_frame_seq()))\n", " File \"C:\\ProgramData\\Anaconda3\\lib\\site-packages\\matplotlib\\animation.py\", line 1772, in _draw_frame\n", " self._drawn_artists = self._func(framedata, *self._args)\n", " File \"\", line 268, in updatefig\n", " im1=plt.imshow(Zm, cmap=plt.get_cmap('magma').with_extremes(bad='#101020'))\n", "AttributeError: 'ListedColormap' object has no attribute 'with_extremes'\n" ] } ], "source": [ "%matplotlib tk\n", "import time, math\n", "from random import random\n", "import numpy as np\n", "from IPython import display\n", "from IPython.display import clear_output\n", "from PIL import Image\n", "import matplotlib.pyplot as plt\n", "import matplotlib.animation as animation\n", "\n", "# Генерация карт по картинке\n", "\n", "Terrain=np.sign(np.array(Image.open(\"test.png\"))[:,:,0])\n", "ShowTerrain=Terrain*1.0\n", "Flow=Store=TransportActivity=Conc=Terrain*0.0\n", "Dir=Terrain*0\n", "\n", "# Генерация случайных препятствий\n", "\n", "#for i in range(100):\n", "# Terrain[int(random()*Live.shape[0]-2),int(random()*Live.shape[1]-2)]=0\n", "\n", "# Настройка параметров клетки\n", " \n", "START_COMPLETENESS = 1\n", "#GROW_COMPLETENESS = 7\n", "REP_COMPLETENESS = 20\n", "#MAX_COMPLETENESS = 100\n", "\n", "# Настройка параметров распространеняи сигнала об активном строительстве \n", "\n", "INCOMPLETENESS_SIGNAL_EMISSION_RATIO = 0.1\n", "INCOMPLETENESS_SIGNAL_DIFFUSION_RATIO = 0.45\n", "INCOMPLETENESS_SIGNAL_DECAY_RATIO = 0.9\n", "INCOMPLETENESS_SIGNAL_THRESHOLD = 1\n", "\n", "# Настройка бобмбардировки \n", " \n", "BOMB_MIN=0\n", "BOMB_START=60000\n", "BOMB_MAX=1\n", "BOMB_SIZE=2\n", "b=BOMB_MIN\n", "\n", "# Выбор способа отображения цифровыми клавишами 0-5\n", "\n", "def on_press(event):\n", " global DISPLAY\n", " global ax\n", " global plt\n", " DISPLAY=int(event.key)\n", " if DISPLAY==0:\n", " ax.set_title('Terrain') \n", " elif DISPLAY==1:\n", " ax.set_title('Incompleteness Signal Concentration')\n", " elif DISPLAY==2:\n", " ax.set_title('Incompleteness Signal Direction')\n", " elif DISPLAY==3:\n", " ax.set_title('Transport Direction')\n", " elif DISPLAY==4:\n", " ax.set_title('Storage')\n", " elif DISPLAY==5:\n", " ax.set_title('Transport Activity')\n", " plt.draw()\n", "\n", "# Настройка графического отображения\n", "\n", "fig=plt.figure()#(figsize=(7, 5))\n", "ax=fig.add_subplot(1, 1, 1)\n", "im1=plt.imshow(ShowTerrain, cmap=plt.get_cmap('bone'), animated=True)\n", "fig.canvas.mpl_connect('key_press_event', on_press)\n", "DISPLAY=0\n", "ax.set_title('Terrain') \n", "writer = animation.writers['ffmpeg'](fps=15, metadata=dict(artist='Me'), bitrate=1800)\n", "framecounter=0\n", "\n", "# Словарь для хранения клеток по координатам\n", "\n", "cells={}\n", " \n", "class Cell():\n", " def __init__(self,x,y):\n", " self.x=x\n", " self.y=y\n", " self.productivity=1\n", " self.transportivity=10\n", " self.completeness=START_COMPLETENESS\n", " self.conc=0\n", " self.flow=0\n", " self.storage=0\n", " cells[(self.x,self.y)] = self\n", " self.refresh()\n", " def refresh(self):\n", " if self.completeness<1:\n", " self.destroy()\n", " addconc=(REP_COMPLETENESS-self.completeness)*INCOMPLETENESS_SIGNAL_EMISSION_RATIO\n", " if self.completeness>=REP_COMPLETENESS:\n", " addconc=0\n", " self.conc+=addconc\n", " self.conc*=INCOMPLETENESS_SIGNAL_DECAY_RATIO\n", " def destroy(self):\n", " del cells[(self.x,self.y)]\n", "\n", "# Создаем первоначальную клетку\n", " \n", "a=Cell(20,20)\n", "a.completeness=REP_COMPLETENESS\n", "a.refresh()\n", "\n", "# Расчеты в каждом кадре\n", "\n", "def updatefig(*args):\n", " global b,TransportActivity,ShowTerrain,Store,framecounter\n", " \n", " # Очистка карт для визуализации\n", " \n", " TransportActivity=Terrain*0.0\n", " ShowTerrain=Terrain*1\n", " Store=Terrain*0.0\n", " Conc=Terrain*0.0\n", " \n", " clist=list(cells.values())\n", " for c in clist: # Расчеты для каждой клетки\n", " c.refresh()\n", " \n", " # Отображение различных параметров клетки \n", " Store[c.x,c.y]=c.storage\n", " ShowTerrain[c.x,c.y]=c.completeness\n", " Conc[c.x,c.y]=c.conc\n", " \n", " if c.completeness>=REP_COMPLETENESS: # Если клетка зрелая, то:\n", " c.storage+=c.productivity # Производство объектов на склад\n", " \n", " # Составляем список соседних участков с учетом границ карты\n", " \n", " neighbors=[]\n", " if c.x>0:\n", " neighbors.append((c.x-1,c.y))\n", " if c.x0:\n", " neighbors.append((c.x,c.y-1))\n", " if c.yconcmax:\n", " cneed=f\n", " needer=int((nx-c.x)+2*(ny-c.y)+3)\n", " if needer==5:\n", " needer=3\n", " concmax=f.conc\n", " \n", " # Диффузия сигнала роста\n", " \n", " aconc=(c.conc+f.conc)/2\n", " dconc=(aconc-c.conc)*INCOMPLETENESS_SIGNAL_DIFFUSION_RATIO \n", " c.conc+=dconc\n", " f.conc-=dconc\n", "\n", " # Выявление наиболее готовой недостроенной соседней клетки\n", " \n", " if f.completeness0:\n", " if candidatemax<1:\n", " candidate=(nx,ny)\n", " candidatemax=1\n", " \n", " # Отображение на картах направления транспорта и градиента сигнала роста\n", " \n", " if concmax>0:\n", " Dir[c.x,c.y]=needer\n", " Flow[c.x,c.y]=math.atan2(fx,fy)\n", " \n", " \n", " if candidatemax>0: # Если есть недостроенные или пустые участки\n", " if candidatemax==1: # Если есть только пустые\n", " cneed=Cell(candidate[0],candidate[1]) # Создать клетку\n", " else: # Иначе\n", " cneed=cells[(candidate[0],candidate[1])] # Помогаем строящейся клетке\n", " \n", " # Транспорт объектов в соседние клетки\n", " \n", " if cneed:\n", " \n", " # Установим объем грузоперевозок в зависимости от концентрации сигнала роста\n", " # и ограничим его минимум и максимум\n", " \n", " kgr=(cneed.conc)/INCOMPLETENESS_SIGNAL_THRESHOLD\n", " if kgr<0:\n", " kgr=0\n", " if kgr>1:\n", " kgr=1\n", " \n", " # Если запасы не меньше, чем планируемый экспорт,\n", " # то отправим сколько планировали\n", " \n", " if c.storage>=c.transportivity*kgr:\n", " cneed.completeness+=c.transportivity*kgr # Передача\n", " TransportActivity[c.x,c.y]+=c.transportivity*kgr # Отображение на карте перевозок\n", " c.storage-=c.transportivity*kgr # Удаление со склада\n", "\n", " # Иначе отправим сколько можем\n", " \n", " else:\n", " cneed.completeness+=c.storage # Передача \n", " TransportActivity[c.x,c.y]+=c.storage # Отображение на карте перевозок \n", " c.storage=0 # Удаление со склада\n", " \n", " # Если получатель принял больше чем нужно для строительства, \n", " # излишки у него складируются\n", " # (на следующем ходу он может передать их дальше)\n", " \n", " if cneed.completeness>REP_COMPLETENESS:\n", " cneed.storage+=cneed.completeness-REP_COMPLETENESS\n", " cneed.completeness=REP_COMPLETENESS\n", " cneed.refresh()\n", " \n", " # Бомбардировка\n", " \n", " if len(cells)>BOMB_START:\n", " b=BOMB_MAX\n", " for i in range(b): \n", " sx=int(random()*Terrain.shape[0])\n", " sy=int(random()*Terrain.shape[1])\n", " for xi in range(sx,sx+BOMB_SIZE):\n", " for yi in range(sy,sy+BOMB_SIZE):\n", " if (xi,yi) in cells.keys():\n", " cells[(xi,yi)].destroy()\n", "\n", " # Вывод текстом номера кадра и числа клеток (чтобы следить за процессом при записи анимации в файл) \n", " \n", " framecounter+=1\n", " clear_output(wait=True)\n", " print(framecounter,len(cells)) \n", " \n", " # Отображение выбранной карты\n", " \n", " if DISPLAY==0:\n", " im1=plt.imshow(ShowTerrain, cmap=plt.get_cmap('bone'))\n", " elif DISPLAY==1:\n", " Zm = np.ma.masked_where(Terrain == 0, Conc)\n", " im1=plt.imshow(Zm, cmap=plt.get_cmap('magma').with_extremes(bad='#101020'))\n", " elif DISPLAY==2:\n", " Zm = np.ma.masked_where(TransportActivity<0.1, Flow)\n", " im1=plt.imshow(Zm, cmap=plt.get_cmap('hsv').with_extremes(bad='k'))\n", " elif DISPLAY==3:\n", " Zm = np.ma.masked_where(TransportActivity<0.1, Dir)\n", " im1=plt.imshow(Zm, cmap=plt.get_cmap('brg').with_extremes(bad='k'))\n", " elif DISPLAY==4:\n", " im1=plt.imshow(Store, cmap=plt.get_cmap('gist_stern'))\n", " elif DISPLAY==5:\n", " Zm = np.ma.masked_where(Terrain == 0, TransportActivity)\n", " im1=plt.imshow(Zm, cmap=plt.get_cmap('hot').with_extremes(bad='#101020'))\n", " return im1,\n", "\n", "# Настройка анимации\n", "ani = animation.FuncAnimation(fig, updatefig, frames=600, interval=3, blit=True)\n", "plt.show()\n", "#ani.save('im0.mp4', writer=writer) # Сохранить анимацию в файле" ] }, { "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.6.5" } }, "nbformat": 4, "nbformat_minor": 1 }