368 lines
17 KiB
Text
368 lines
17 KiB
Text
{
|
||
"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 \"<ipython-input-3-63ec1324f14b>\", 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 \"<ipython-input-3-63ec1324f14b>\", 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.x<Terrain.shape[0]-1:\n",
|
||
" neighbors.append((c.x+1,c.y))\n",
|
||
" if c.y>0:\n",
|
||
" neighbors.append((c.x,c.y-1))\n",
|
||
" if c.y<Terrain.shape[1]-1:\n",
|
||
" neighbors.append((c.x,c.y+1)) \n",
|
||
"\n",
|
||
" candidatemax=0\n",
|
||
" concmax=0\n",
|
||
" fx=0\n",
|
||
" fy=0\n",
|
||
" cneed=None\n",
|
||
" \n",
|
||
" for (nx,ny) in neighbors: # Для каждого участка из списка соседей\n",
|
||
" if (nx,ny) in cells.keys(): # Если на нем есть клетка \n",
|
||
" \n",
|
||
" # Расчет градиента сигнала роста\n",
|
||
" \n",
|
||
" f=cells[(nx,ny)]\n",
|
||
" vconc=f.conc-c.conc\n",
|
||
" fx+=vconc*(nx-c.x)\n",
|
||
" fy+=vconc*(ny-c.y)\n",
|
||
" \n",
|
||
" # Выявление соседа с наибольшей концентрацией сигнала роста\n",
|
||
" \n",
|
||
" if f.conc>concmax:\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.completeness<REP_COMPLETENESS: \n",
|
||
" if candidatemax<f.completeness:\n",
|
||
" candidatemax=f.completeness\n",
|
||
" candidate=(nx,ny)\n",
|
||
" \n",
|
||
" # Если на участке нет клетки, проверяем можно ли там построить новую\n",
|
||
" # Постройка новых клеток имеет меньший приоритет, чем достройка начатых\n",
|
||
" \n",
|
||
" else: \n",
|
||
" if Terrain[nx,ny]>0:\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
|
||
}
|