263 lines
14 KiB
Text
263 lines
14 KiB
Text
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"%matplotlib tk\n",
|
||
"import time, math\n",
|
||
"from random import random\n",
|
||
"import numpy as np\n",
|
||
"from IPython import display\n",
|
||
"from PIL import Image\n",
|
||
"import matplotlib.pyplot as plt\n",
|
||
"import matplotlib.animation as animation\n",
|
||
"writer = animation.writers['ffmpeg'](fps=30, metadata=dict(artist='Me'), bitrate=1800)\n",
|
||
"\n",
|
||
"# Коды элементов\n",
|
||
"\n",
|
||
"BAD = 0\n",
|
||
"GOOD = 1\n",
|
||
"BASIC_FLOOR = 2\n",
|
||
"FENCE_PORT = 3\n",
|
||
"CORNER_PORT = 4\n",
|
||
"STORAGE_PORT = 5\n",
|
||
"GATE_LEAF_PORT = 6\n",
|
||
"GATE_PORT = 7\n",
|
||
"TRACK = 8\n",
|
||
"MACHINE_PORT = 9\n",
|
||
"WORK_PORT = 10\n",
|
||
"MM_PORT = 11\n",
|
||
"POWER_PORT = 12\n",
|
||
"UTIL_PORT = 13\n",
|
||
"PLANNER_PORT = 14\n",
|
||
"MINE_PORT = 15\n",
|
||
"\n",
|
||
"#Словарь, где хранятся ссылки на клетки по координатам\n",
|
||
"\n",
|
||
"cells={}\n",
|
||
"\n",
|
||
"class FloorElement():\n",
|
||
" def __init__(self,parent,x,y,element_type):\n",
|
||
" self.x=x\n",
|
||
" self.y=y\n",
|
||
" self.element_type=element_type\n",
|
||
" self.parent=parent\n",
|
||
" self.parent.floor[(self.x,self.y)]=self\n",
|
||
"\n",
|
||
"class Cell():\n",
|
||
" def __init__(self,x,y):\n",
|
||
" self.x=x\n",
|
||
" self.y=y\n",
|
||
" cells[(self.x,self.y)] = self\n",
|
||
" self.floor={}\n",
|
||
" self.content={}\n",
|
||
" self.generate()\n",
|
||
" def destroy(self):\n",
|
||
" del cells[(self.x,self.y)] \n",
|
||
" def generate(self):\n",
|
||
"\n",
|
||
" # Настройка параметров клетки\n",
|
||
" self.max_machine_size=20 # Максимальное число блоков в машине \n",
|
||
" self.work_machine_number_max=30 # Максимальное число рабочих машин\n",
|
||
" self.planners_max=3 # Максимальное число планировщиков\n",
|
||
" self.utils_max=3 # Максимальное число утилизаторов\n",
|
||
" self.powers_max=4 # Максимальное число электростанций\n",
|
||
" self.mines_max=4 # Максимальное число шахт\n",
|
||
" self.storage_number_max_without_mm=500 # Максимальная емкость склада\n",
|
||
" self.mm_max=50 # Максимальное число мобильных манипуляторов (ММ)\n",
|
||
" \n",
|
||
" self.work_machine_number_rep=12 # Число рабочих машин, достаточное для репликации\n",
|
||
" self.storage_number_rep_without_mm=200 # Емкость склада, достаточная для репликации\n",
|
||
" self.work_machine_number_grow=6 # Число рабочих машин, достаточное для автономного роста\n",
|
||
" self.storage_number_grow_without_mm=100 # Емкость склада, достаточная для автономного роста\n",
|
||
" self.storage_free=15 # Число складских ячеек в резерве\n",
|
||
" self.machine_free=2 # Число машиномест в резерве \n",
|
||
"\n",
|
||
" # Найти общее количество машин (включая служебные) и общую емкость склада (включая места для ММ)\n",
|
||
" \n",
|
||
" self.machine_number_max=self.work_machine_number_max+self.planners_max+self.utils_max+self.powers_max+self.mines_max\n",
|
||
" self.storage_number_max=self.mm_max+self.storage_number_max_without_mm\n",
|
||
"\n",
|
||
" # Подобрать прямоугольную форму машины, по возможности близкую к квадратной, содержащую количество\n",
|
||
" # блоков не меньше заданного и хорошо стыкуемую с соседями, дорожками и складской зоной\n",
|
||
" # Определить ширину и высоту машины, фактическое количество в ней блоков и занимаемую ей площадь\n",
|
||
" \n",
|
||
" self.machine_height=round(math.sqrt(self.max_machine_size),0)//3*3+1\n",
|
||
" self.machine_width=self.max_machine_size//self.machine_height\n",
|
||
" if self.machine_width*self.machine_height<self.max_machine_size:\n",
|
||
" self.machine_width=self.machine_width+1\n",
|
||
" self.fact_machine_size=self.machine_height*self.machine_width\n",
|
||
" self.fact_machine_area=(self.machine_height+5)*(self.machine_width+5)\n",
|
||
"\n",
|
||
" # Подобрать прямоугольную форму рабочей зоны, по возможности близкую к квадратной, содержащую \n",
|
||
" # количество машин не меньше заданного и хорошо стыкуемую с дорожками и складскими зонами\n",
|
||
" # Определить ширину и высоту рабочей зоны, фактическое количество машин и занимаемую ей площадь\n",
|
||
" \n",
|
||
" self.machine_coloumns=round(math.sqrt(self.machine_number_max),0)\n",
|
||
" self.machine_rows=self.machine_coloumns\n",
|
||
" if self.machine_coloumns*self.machine_rows<self.machine_number_max:\n",
|
||
" self.machine_rows+=1\n",
|
||
" if self.machine_width%2==0:\n",
|
||
" if self.machine_coloumns%2==1:\n",
|
||
" if self.machine_coloumns%2==1:\n",
|
||
" self.machine_coloumns+=1\n",
|
||
" else:\n",
|
||
" self.machine_coloumns,self.machine_rows=self.machine_rows,self.machine_coloumns\n",
|
||
" self.siderows=self.machine_rows*(1+(self.machine_height-1)/6)\n",
|
||
" if self.siderows!=int(self.siderows):\n",
|
||
" self.machine_rows+=1\n",
|
||
" self.siderows=self.machine_rows*(1+(self.machine_height-1)/6) \n",
|
||
" self.fact_machine_number=self.machine_coloumns*self.machine_rows\n",
|
||
"\n",
|
||
" # Рассчитать размер территории, занимаемой клеткой\n",
|
||
" \n",
|
||
" self.fact_machine_block_area=self.fact_machine_number*self.fact_machine_area\n",
|
||
" self.storage_desired_area=self.storage_number_max*5.5\n",
|
||
" self.total_desired_area=self.storage_desired_area+self.fact_machine_block_area\n",
|
||
" self.presize=(int(math.sqrt(self.total_desired_area)))\n",
|
||
" self.presize=(1+self.presize//6)*6\n",
|
||
" if (self.presize-(self.siderows*6))%12!=0:\n",
|
||
" self.presize+=6\n",
|
||
" self.realsize=self.presize+5\n",
|
||
"\n",
|
||
" # Создать территорию\n",
|
||
" \n",
|
||
" self.Terrain=np.ones((self.realsize,self.realsize))\n",
|
||
" #Terrain=np.sign(np.array(Image.open(\"intest.png\"))[:,:,0])\n",
|
||
"\n",
|
||
" # Создать карту, заполненную элементами пола\n",
|
||
" \n",
|
||
" self.Map=self.Terrain*BASIC_FLOOR\n",
|
||
"\n",
|
||
" # Создать забор\n",
|
||
" \n",
|
||
" self.Map[0]=self.Map[-1]=self.Map[:,0]=self.Map[:,-1]=FENCE_PORT\n",
|
||
"\n",
|
||
" # Создать углы\n",
|
||
" \n",
|
||
" self.Map[0,0]=self.Map[0,-1]=self.Map[-1,0]=self.Map[-1,-1]=CORNER_PORT\n",
|
||
"\n",
|
||
" # Создать трассу по периметру клетки\n",
|
||
" \n",
|
||
" self.Map[2:-2,2:-2]=TRACK\n",
|
||
" self.Map[3:-3,3:-3]=BASIC_FLOOR\n",
|
||
"\n",
|
||
" # Создать ворота, порты ворот, складские места\n",
|
||
" \n",
|
||
" for y in range(4,self.presize+2,6):\n",
|
||
" self.Map[y-2,2:-3]=TRACK\n",
|
||
" self.Map[y,0]=self.Map[y+2,0]=self.Map[y,-1]=self.Map[y+2,-1]=GATE_LEAF_PORT\n",
|
||
" self.Map[0,y]=self.Map[0,y+2]=self.Map[-1,y]=self.Map[-1,y+2]=GATE_LEAF_PORT\n",
|
||
" self.Map[y+1,0]=self.Map[y+1,-1]=self.Map[0,y+1]=self.Map[-1,y+1]=GATE_PORT\n",
|
||
" self.Map[y+1,1]=self.Map[y+1,-2]=self.Map[1,y+1]=self.Map[-2,y+1]=TRACK\n",
|
||
" for x in range(4,self.presize+2,2):\n",
|
||
" self.Map[y,x]=self.Map[y+2,x]=STORAGE_PORT\n",
|
||
" \n",
|
||
" # Создать машинную зону \n",
|
||
" \n",
|
||
" self.center=int(self.realsize/2)\n",
|
||
" self.mxstart=int(self.center-(self.machine_coloumns*(self.machine_width+5))/2)\n",
|
||
" self.mystart=int(self.center-(self.siderows*3))\n",
|
||
" self.mxstop=int(self.center+(self.machine_coloumns*(self.machine_width+5))/2)\n",
|
||
" if self.mxstart%2!=0:\n",
|
||
" self.mxstart-=1\n",
|
||
" self.mxstop-=1\n",
|
||
" self.mystop=int(self.center+(self.siderows*3))\n",
|
||
" \n",
|
||
" self.Map[self.mystart+1:self.mystop-1,self.mxstart:self.mxstop]=BASIC_FLOOR\n",
|
||
" self.Map[2:-2,self.mxstart]=self.Map[2:-2,self.mxstop]=TRACK\n",
|
||
"\n",
|
||
" special_machines_list=([PLANNER_PORT]*self.planners_max+[POWER_PORT]*self.powers_max+\n",
|
||
" [UTIL_PORT]*self.utils_max+[MINE_PORT]*self.mines_max)\n",
|
||
" \n",
|
||
" for y in range(self.mystart,self.mystop,int(self.machine_height)+5):\n",
|
||
" self.Map[y,self.mxstart:self.mxstop]=TRACK\n",
|
||
" for x in range(self.mxstart,self.mxstop,int(self.machine_width)+5):\n",
|
||
" kind=MACHINE_PORT\n",
|
||
" if len(special_machines_list)>0:\n",
|
||
" kind = special_machines_list.pop(0)\n",
|
||
" self.Map[3+y:3+y+int(self.machine_height),3+x:3+x+int(self.machine_width)]=kind\n",
|
||
" for sy in range(3+y,3+y+int(self.machine_height),2):\n",
|
||
" self.Map[sy,2+x]=WORK_PORT\n",
|
||
" for sx in range(4+x,3+x+int(self.machine_width),2):\n",
|
||
" self.Map[2+y,sx]=WORK_PORT\n",
|
||
" zystart=3+y\n",
|
||
" if self.Map[2+y,2+x+int(self.machine_width)]==WORK_PORT:\n",
|
||
" zystart+=1\n",
|
||
" for zy in range(zystart,3+y+int(self.machine_height),2):\n",
|
||
" self.Map[zy,3+x+int(self.machine_width)]=WORK_PORT\n",
|
||
" zxstart=3+x\n",
|
||
" if self.Map[2+y+int(self.machine_height),2+x]==WORK_PORT:\n",
|
||
" zxstart+=1\n",
|
||
" for zx in range(zxstart,3+x+int(self.machine_width),2):\n",
|
||
" self.Map[3+y+int(self.machine_height),zx]=WORK_PORT\n",
|
||
"\n",
|
||
" # Создать дополнительные вертикальные трассы возле машинной зоны \n",
|
||
" \n",
|
||
" for x in range(self.mxstart,self.mxstop,int(self.machine_width)+5):\n",
|
||
" if self.Map[4,x] == STORAGE_PORT:\n",
|
||
" self.Map[2:-3,x]=TRACK\n",
|
||
" else:\n",
|
||
" self.Map[self.mystart:self.mystop,x]=TRACK\n",
|
||
"\n",
|
||
" # Создать порты мобильных манипуляторов\n",
|
||
" \n",
|
||
" mm_counter=self.mm_max\n",
|
||
" for y in range(self.realsize):\n",
|
||
" for x in range(self.realsize):\n",
|
||
" if mm_counter>0:\n",
|
||
" if self.Map[y,x]==STORAGE_PORT:\n",
|
||
" self.Map[y,x]=MM_PORT\n",
|
||
" mm_counter-=1\n",
|
||
" if self.Map[y-2,x]==TRACK:\n",
|
||
" self.Map[y-1,x]=TRACK\n",
|
||
" elif self.Map[y+2,x]==TRACK:\n",
|
||
" self.Map[y+1,x]=TRACK\n",
|
||
"\n",
|
||
" # Зарегистрировать элементы карты\n",
|
||
" \n",
|
||
" for y in range(self.realsize):\n",
|
||
" for x in range(self.realsize):\n",
|
||
" if self.Map[y,x]>1: \n",
|
||
" FloorElement(self,x,y,self.Map[y,x])\n",
|
||
" \n",
|
||
"# Создать клетку \n",
|
||
" \n",
|
||
"c=Cell(20,20)\n",
|
||
"\n",
|
||
"# Показать клетку\n",
|
||
"\n",
|
||
"fig=plt.figure(figsize=(7, 5))\n",
|
||
"ax=fig.add_subplot(1, 1, 1)\n",
|
||
"im1=plt.imshow(c.Map, cmap=plt.get_cmap('bone'))\n",
|
||
"ax.set_title('Map MS:'+str(c.max_machine_size)+' MN:'+str(c.work_machine_number_max)+\n",
|
||
" ' SN:'+str(c.storage_number_max_without_mm)+' MM:'+str(c.mm_max)) \n",
|
||
"plt.show()"
|
||
]
|
||
}
|
||
],
|
||
"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
|
||
}
|