robossembler.org/docs/models/generation/generation.ipynb

263 lines
14 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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