From 8b6dd90a7a9c9d59db15209fa85272f2ed3c44be Mon Sep 17 00:00:00 2001 From: Niclas3006 <91843854+Niclas3006@users.noreply.github.com> Date: Sun, 10 May 2026 00:30:05 +0200 Subject: [PATCH] init --- .gitignore | 180 +------------ algorithms.py | 138 ++++++++++ classes.py | 493 +++++++++++++++++++++++++++++++++++ main.py | 130 +++++++++ sprites/CarOnPark.aseprite | Bin 0 -> 476 bytes sprites/CarOnPark.png | Bin 0 -> 276 bytes sprites/Park.aseprite | Bin 0 -> 449 bytes sprites/Park.png | Bin 0 -> 243 bytes sprites/car.aseprite | Bin 0 -> 464 bytes sprites/car.png | Bin 0 -> 277 bytes sprites/emptySprite.aseprite | Bin 0 -> 400 bytes sprites/emptySprite.png | Bin 0 -> 165 bytes 12 files changed, 765 insertions(+), 176 deletions(-) create mode 100644 algorithms.py create mode 100644 classes.py create mode 100644 main.py create mode 100644 sprites/CarOnPark.aseprite create mode 100644 sprites/CarOnPark.png create mode 100644 sprites/Park.aseprite create mode 100644 sprites/Park.png create mode 100644 sprites/car.aseprite create mode 100644 sprites/car.png create mode 100644 sprites/emptySprite.aseprite create mode 100644 sprites/emptySprite.png diff --git a/.gitignore b/.gitignore index 36b13f1..e354f5c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,176 +1,4 @@ -# ---> Python -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ -cover/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -.pybuilder/ -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -# For a library or package, you might want to ignore these files since the code is -# intended to run in multiple environments; otherwise, check them in: -# .python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# UV -# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -#uv.lock - -# poetry -# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control -#poetry.lock - -# pdm -# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. -#pdm.lock -# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it -# in version control. -# https://pdm.fming.dev/latest/usage/project/#working-with-version-control -.pdm.toml -.pdm-python -.pdm-build/ - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -# pytype static type analyzer -.pytype/ - -# Cython debug symbols -cython_debug/ - -# PyCharm -# JetBrains specific template is maintained in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ - -# Ruff stuff: -.ruff_cache/ - -# PyPI configuration file -.pypirc - +/output/ +/venv/ +/.idea/ +*.avi diff --git a/algorithms.py b/algorithms.py new file mode 100644 index 0000000..25f3177 --- /dev/null +++ b/algorithms.py @@ -0,0 +1,138 @@ +from math import log, ceil +from operator import itemgetter +from classes import * + +class SolvingAlgorithm: + def __init__(self,space,gMngr:GarageManager): + self.space:MetricSpace = space + self.garageManager:GarageManager = gMngr + self.amountTraveled = 0 + + def getGarageForCar(self,car:Point): + garages:List[Garage] = list(self.garageManager.garages) + garages = sorted(garages,key=lambda g: self.space.distancefunction.apply(car,g)) + + for g in garages: + if self.garageManager.is_full(g): + continue + else: + g.cars_parked.append(g) + self.amountTraveled += self.space.distancefunction.apply(car,g) + return g + + return None + + +class MST(): + @classmethod + def _helper_getListInPointset(self, pointesets:List[List[Point]] , point:tuple): + for li in pointesets: + if point in li: + return li + return None + + + def __init__(self, points:set, distancefunction: DistanceFunction,space:MetricSpace, powerTWO = False,mst_visualize=True): + self.points = points + self.distancefunction = distancefunction + + all_edges = [] + for i in self.points: + for j in self.points: + if not i == j: + if not (j,i, distancefunction.apply(i,j)) in all_edges: + all_edges.append((i,j, distancefunction.apply(i,j))) + + all_edges = sorted(all_edges,key=itemgetter(2)) + + minimal_edges = [] # edge is represented by (i,j, distance/Weight) + pointSets:List[List[Point]] = [] + for p in self.points: + pointSets.append([p]) + + visualisations =[] + for edge in all_edges: + if len(pointSets) <= 1: break + li0 = MST._helper_getListInPointset(pointSets,edge[0]) + li1 = MST._helper_getListInPointset(pointSets,edge[1]) + + if not( li0 == li1): + minimal_edges.append(edge) + + li_new = li0 + li1 + pointSets.remove(li0) + pointSets.remove(li1) + pointSets.append( li_new) + + if (mst_visualize): + a= frameGenerator.point_to_pixel_center(space,edge[0]) + b= frameGenerator.point_to_pixel_center(space,edge[1]) + data = [ a[0], a[1], b[0], b [1], (23,64,96,100)] + visualisations.append(RenderTask(RenderTaskType.LINE,"mst",data)) + RenderTaskStack.add_single_frame_render(RenderTaskFrame(visualisations.copy())) + + if(powerTWO): + for x in range(len(minimal_edges)): + c_edge = minimal_edges[x] + c_edge = ( c_edge[0], c_edge[1], 2**ceil(log(c_edge[2],2)) ) + minimal_edges[x] = c_edge + + if (mst_visualize): + RenderTaskStack.add_single_frame_render(RenderTaskFrame(visualisations.copy(),True)) + + self.minimalEdges: List[tuple[Point,Point,float]] = minimal_edges + + def _dfs_recursive(self, tree, start, visited =[]): + # due tue MST property, + tour = [] + + for edge in tree:# go throug all edges and recursively walk down all that lead to new places, on return add back edge + if edge[0] == start and edge[1] not in visited: + tour.append(edge) + visited.append(start) # visited only needs to be carried in for a node downwards but not upwards, since this is a MST + data = self._dfs_recursive(tree,edge[1],visited) + tour+= data # add subtree + tour.append((edge[1],edge[0],edge[2])) #append reversed edge + + return tour + + + + def get_dfs_eulerwalk(self,start:Point, level= 0): + directionalEdges = [] + for min_edge in self.minimalEdges: + i,j,dist = min_edge + if dist > 2**level: continue + directionalEdges.append((i,j,dist)) + directionalEdges.append((j,i,dist)) + + # create walk with dfs + walk:List[tuple[Point,Point,float]] = self._dfs_recursive(directionalEdges,start) + + return walk + + + + + + + + + +class AlgorithmA(SolvingAlgorithm): + def __init__(self, space:MetricSpace, gMngr: GarageManager): + super().__init__(space, gMngr) + gar_set = set(gMngr.garages) + self.mst = MST(gar_set,space.distancefunction,space,True) + + def getGarageForCar(self, car: Point): + + return super().getGarageForCar(car) + + + + + + + + diff --git a/classes.py b/classes.py new file mode 100644 index 0000000..70446f5 --- /dev/null +++ b/classes.py @@ -0,0 +1,493 @@ +import typing +import builtins +import math +from enum import Enum +from math import fabs + +from PIL import Image, ImageFilter +import os + +from typing import NamedTuple, List + +DIRECTORY = os.path.dirname(os.path.abspath(__file__))+"/" +PLOT_EMPTY = Image.open(DIRECTORY+"sprites/emptySprite.png").convert("RGBA") +PLOT_GARAGE = Image.open(DIRECTORY+"sprites/Park.png").convert("RGBA") +PLOT_CAR = Image.open(DIRECTORY+"sprites/car.png").convert("RGBA") +PLOT_GARAGE_CAR = Image.open(DIRECTORY+"sprites/CarOnPark.png").convert("RGBA") +OUTPUT_DIR = DIRECTORY + "output/" + +FULL_GARAGE_COLOR = (1,0.5,0.5,1) +full_garage_sprite = PLOT_GARAGE.copy() +r,g,b,a = full_garage_sprite.split() +r = r.point(lambda i: i * FULL_GARAGE_COLOR[0]) +g = g.point(lambda i: i * FULL_GARAGE_COLOR[1]) +b = b.point(lambda i: i * FULL_GARAGE_COLOR[2]) +a = a.point(lambda i: i * FULL_GARAGE_COLOR[3]) +full_garage_sprite = Image.merge("RGBA",(r,g,b,a)) + +class RenderTaskType(Enum): + LINE = 1 # data [x,y,x2,y2,color(r,g,b,a)] + +class RenderTask(): + def __init__(self, type: RenderTaskType, name:str , data :list): + self.type = type + self.name = name + self.data = data + +class RenderTaskFrame: + def __init__(self,tasks:List[RenderTask],become_permanent:bool = False, become_temp:bool = False): + self.tasks:List[RenderTask] = tasks + self.become_permanent:bool = become_permanent + self.become_temp:bool = become_temp + +class RenderTaskStack: + _Tasks:List[RenderTask] = [] + _TempStack:List[RenderTask] = [] + _SingleFrameRenderTaskList: List[RenderTaskFrame] = [] + + @staticmethod + def has_frame(): + return len(RenderTaskStack._SingleFrameRenderTaskList) >0 + + @staticmethod + def clear_all(): + RenderTaskStack._Tasks = [] + RenderTaskStack._TempStack = [] + + @staticmethod + def add_temp(task:RenderTask): + RenderTaskStack._TempStack.append(task) + + @staticmethod + def add_temps(tasks:List[RenderTask]): + RenderTaskStack._TempStack += tasks + + @staticmethod + def clear_temp(): + RenderTaskStack._TempStack = [] + + @staticmethod + def add_permanent( task: RenderTask): + RenderTaskStack._Tasks.append(task) + + @staticmethod + def add_permanents(task: List[RenderTask]): + RenderTaskStack._Tasks+=task + + @staticmethod + def add_single_frame_render(frame: RenderTaskFrame): + RenderTaskStack._SingleFrameRenderTaskList.append(frame) + + @staticmethod + def pop_single_frame_render()->RenderTaskFrame: + return RenderTaskStack._SingleFrameRenderTaskList.pop(0) + + @staticmethod + def get_permanents(): + return RenderTaskStack._Tasks.copy() + + @staticmethod + def get_temps(): + return RenderTaskStack._TempStack.copy() + + + + + + + + +# füge alle kanten in eine set hinzu, sorte dis liste bei distance und pick die kürzesten die nen neuen knoten hinzufügen + + + + + +class Linedrawer(): + @staticmethod + def plotLineLow(x0, y0, x1, y1): + dx = x1 - x0 + dy = y1 - y0 + yi = 1 + if dy < 0: + yi = -1 + dy = -dy + D = (2 * dy) - dx + y = y0 + + points = [] + for x in range( x0,x1): + points.append((x, y+1)) + if D > 0: + y = y + yi + D = D + (2 * (dy - dx)) + else: + D = D + 2*dy + + return points + + @staticmethod + def plotLineHigh(x0, y0, x1, y1): + dx = x1 - x0 + dy = y1 - y0 + xi = 1 + if dx < 0: + xi = -1 + dx = -dx + D = (2 * dx) - dy + x = x0 + points = [] + for y in range(y0, y1): + points.append((x, y+1)) + if D > 0: + x = x + xi + D = D + (2 * (dx - dy)) + else: + D = D + 2*dx + + return points + + @staticmethod + ## bresenhams line algo ######### + def plotLine(x0, y0, x1, y1): + if abs(y1 - y0) < abs(x1 - x0): + if x0 > x1: + return Linedrawer.plotLineLow(x1, y1, x0, y0) + else: + return Linedrawer.plotLineLow(x0, y0, x1, y1) + else: + if y0 > y1: + return Linedrawer.plotLineHigh(x1, y1, x0, y0) + else: + return Linedrawer.plotLineHigh(x0, y0, x1, y1) + + ################# + @staticmethod + def draw_line_between_points(img:Image, x1,y1,x2,y2,color = (255,255,255))-> Image: + if(x1==x2 and y1 == y2): + x1+=10 + x2-=10 + pixels = img.load() # create the pixel map + + print((x1,y1,x2,y2)) + points = Linedrawer.plotLine(x1,y1,x2,y2) + + for pt in points: + if pt[0] >= 0 and pt[0] = 0 and pt[1] list: + if(len(self.points)==0): return None + + point = self.points.pop() + self.points.add(point) + + x_max = point.x + y_max = point.y + x_min = x_max + y_min = y_max + + for p in self.points: + if p.x > x_max: x_max = p.x + if p.y > y_max: y_max = p.y + if p.x < x_min: x_min = p.x + if p.y < y_min: y_min = p.y + + x_dif = x_max-x_min + y_dif = y_max-y_min + + return [x_max,y_max,x_min,y_min, x_dif +1,y_dif+1] + +class GarageManager: + def __init__(self, garages:set, capacities:dict ={}): + self.garages:set[Garage] = garages + + # To delete + self.capacities = capacities + self.garageArrays = [] + self.currentFillLevel = capacities.copy() + + # initialize capacities + for x in self.currentFillLevel.keys(): + self.currentFillLevel[x]=0 + + def is_full(self, garage:Point): + garage_found = False + current_garage:Garage + + for g in self.garages: + if g.x == garage.x and g.y == garage.y: + current_garage = g + garage_found = True + break + + if not garage_found: + raise RuntimeError(" garage not found in is Full check") + + return current_garage.max_capacity <= len(current_garage.cars_parked) + + + + def getCurrentCapacity(self, garage:Point): + """DEPRECATED""" + raise DeprecationWarning() + return self.currentFillLevel.get(garage,-99) + + def getMaxCapacity(self, garage:Point): + raise DeprecationWarning() + return self.capacities.get(garage,-99) + + def addToCapacity(self,garage:Point,amount): + raise DeprecationWarning() + self.currentFillLevel[garage] = self.getCurrentCapacity(garage) + amount + + + +class frameGenerator(): + def __init__(self, space:MetricSpace, garages:GarageManager): + self.space = space + self.garages:GarageManager = garages + self.garagePoints = [] + for g in garages.garages: + self.garagePoints.append(g.get_location()) + self.car_exists :bool = False + self.car:Point = None + + self.space_limits = space.get_max_min_values() + "[ x_max, y_max, x_min, y_min, x_dif, y_dif]" + + self.frame_width = (self.space_limits[4]*34)-2 # plot +2 pixel for road -2 for end + self.frame_height = (self.space_limits[5]*34)-2 # plot +2 pixel for road -2 for end + + self.time = 0 + self.frameNum = 0 + + + def spawnCar(self,point:Point): + if(not self.car_exists): + self.frameNum = 0 + self.time += 1 + self.car = point + self.car_exists= True + + self.renderFrame() + else: + print("ERROR: double cars!!!!") + raise IndexError + + def add_transition(self, point_B:Point): + if(self.car_exists): + x0,y0 =self._point_to_pixel_center(self.car) + x1,y1 =self._point_to_pixel_center(point_B) + rend_task = RenderTask(RenderTaskType.LINE, "transition",[x0,y0,x1,y1, (255,100,100,200)]) + RenderTaskStack.add_single_frame_render(RenderTaskFrame( [rend_task])) + self.renderFrame() + self.car = point_B + self.renderFrame() + self.car = None + self.car_exists= False + + else: + print("ERROR: no cars was driven somewhere!!!!") + raise IndexError + + + def _point_to_pixel(self, point:Point)->tuple: + x = point.x-self.space_limits[2]#xmin + y = point.y-self.space_limits[3]#ymin + + pix_x = x*34 + pix_y = y*34 + + return (pix_x,pix_y) + + @staticmethod + def point_to_pixel_center(space, point: Point) -> tuple: + space_limits = space.get_max_min_values() + x = point.x - space_limits[2] # xmin + y = point.y - space_limits[3] # ymin + + pix_x = x * 34 + 16 + pix_y = y * 34 + 16 + + return (pix_x, pix_y) + + + def _point_to_pixel_center(self, point:Point)->tuple: + x = point.x-self.space_limits[2]#xmin + y = point.y-self.space_limits[3]#ymin + + pix_x = x*34 +16 + pix_y = y*34 +16 + + return (pix_x,pix_y) + + def _insert_Image(self, frame , pix_x,pix_y, image:Image): + img:Image.core.PixelAccess = image.load() + fme:Image.core.PixelAccess = frame.load() + width, height = image.size + for x in range(width): + for y in range(height): + if img[x,y] != (0,0,0,0): + fme[pix_x+x,pix_y+y] = img[x,y] + + + + def renderFrame(self, drawLine = False, LineColor = (200,0,0,200), endPoint:Point = None ): + frame = Image.new("RGBA",(self.frame_width,self.frame_height),(100,100,100,255)) + + for p in self.space.points: + x,y = self._point_to_pixel(p) + + img = PLOT_EMPTY + if((self.car_exists) and (p.get_location() == self.car.get_location()) and (p.get_location() in self.garagePoints)): + img = PLOT_GARAGE_CAR + elif(self.car_exists and p.get_location() == self.car.get_location()): + img = PLOT_CAR + elif(p.get_location() in self.garagePoints): + if self.garages.is_full(p): + img = full_garage_sprite + else: + img = PLOT_GARAGE + + self._insert_Image(frame, x, y,img) + + + + # render temp and permanent + static_overlay = Image.new("RGBA", (self.frame_width, self.frame_height), (0, 0, 0, 0)) + for ta in RenderTaskStack.get_permanents(): + if ta.type == RenderTaskType.LINE: + car_x, car_y = ta.data[0], ta.data[1] + ep_x, ep_y = ta.data[2], ta.data[3] + Linedrawer.draw_line_between_points(static_overlay, car_x, car_y, ep_x, ep_y, ta.data[4]) + + for ta in RenderTaskStack.get_temps(): + if ta.type == RenderTaskType.LINE: + car_x, car_y = ta.data[0], ta.data[1] + ep_x, ep_y = ta.data[2], ta.data[3] + Linedrawer.draw_line_between_points(static_overlay, car_x, car_y, ep_x, ep_y, ta.data[4]) + + frame = Image.alpha_composite(frame, static_overlay) + + # _Tasks:List[RenderTask] = [] + # _TempStack:List[RenderTask] = [] + # _SingleFrameRenderTaskList: List[RenderTaskFrame] = [] + firstInteration:bool = True + frame_src = frame.copy() + while (firstInteration or RenderTaskStack.has_frame()): + frame = frame_src.copy() + passingOverlay = Image.new("RGBA", (self.frame_width, self.frame_height), (0, 0, 0, 0)) + if RenderTaskStack.has_frame(): + framedata:RenderTaskFrame = RenderTaskStack.pop_single_frame_render() + # process task per frame + for ta in framedata.tasks: + if ta.type == RenderTaskType.LINE: + car_x,car_y = ta.data[0],ta.data[1] + ep_x,ep_y = ta.data[2],ta.data[3] + Linedrawer.draw_line_between_points(passingOverlay,car_x,car_y,ep_x,ep_y, ta.data[4]) + + # handle migration + if framedata.become_temp: + RenderTaskStack.add_temps(framedata.tasks) + if framedata.become_permanent: + RenderTaskStack.add_permanents(framedata.tasks) + + #add overlay + frame = Image.alpha_composite(frame,passingOverlay) + + # save + frame.save(OUTPUT_DIR +f"frame-t{self.time:03d}-f{self.frameNum:02d}.png",format="PNG") + + self.frameNum += 1 + firstInteration = False + + + + + + \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..9fa756d --- /dev/null +++ b/main.py @@ -0,0 +1,130 @@ +from math import ceil + +from PIL.ImageChops import offset + +if "clip005.avi".endswith(".png"): + raise RuntimeError; + +import math + +from algorithms import * +from classes import * +import os +import cv2 +import random +import numpy as np + +FRAME_MULTIPLIER_VIDEO = 10 + +def renderTomp4(removeImageSource = True): + img_list_unfiltered = os.listdir(OUTPUT_DIR) + img_list =[] + + for x in img_list_unfiltered: + if (""+x).endswith(".png"): + img_list.append(x) + + # for x in img_list: + # if not x.endswith(".png"): + # print("removed: "+x) + # img_list.remove(x) + # else: + # print("keept: "+x) + # + # print(img_list) + # + img_list.sort() + img_array = [] + size = (100,100) + frameindex = 0 + for filename in img_list: + frameindex += 1 + img = cv2.imread(OUTPUT_DIR + filename) + if(img is None): + print("loadingError: "+filename) + return + height, width, layers = img.shape + size = (width, height) + img_array+=[img]*FRAME_MULTIPLIER_VIDEO + + clipIndex = 0 + while( os.path.exists(OUTPUT_DIR+f"clip{clipIndex:03d}.avi")): + clipIndex +=1 + + out = cv2.VideoWriter(OUTPUT_DIR+f"clip{clipIndex:03d}.avi", cv2.VideoWriter_fourcc(*'DIVX'), 15, size) + + for i in range(len(img_array)): + out.write(img_array[i]) + out.release() + + if not removeImageSource: return + for x in img_list: + os.remove(OUTPUT_DIR + x) + +def createRandomSubspace(points:set,size): + pointslist = list(points) + random.shuffle(pointslist) + return set(pointslist[:size]) + +def createRandomsListSequence(points:set):#, garages:set + pointslist = list(points)*5 + if len(pointslist) < 50: + pointslist = pointslist * int(ceil(50/len(pointslist))+1) + random.shuffle(pointslist) + cars = pointslist[:50] + #gar = list(garages) + + #garageOrder =[] + #for x in range(len(cars)): + # random.shuffle(gar) + # garageOrder.append(gar[0]) + + return cars #(cars,garageOrder) + + +def main(): + # seeded randomness + random.seed(0) + space = MetricSpace.getPopulatedSpace(10,10) + + ammountToKeep = random.randint(20,95) + + points = createRandomSubspace(space.points,ammountToKeep) + func = space.distancefunction + + space = MetricSpace(points,func) + + # generate garages + garagesCount = random.randint(3, 8) + garages_locations = createRandomSubspace(points, garagesCount) + capactiyPerGarage = math.ceil(50.0/garagesCount) + #create Garage capacity + garages: List[Garage] = [] + for x in garages_locations: + garages.append(Garage(x,capactiyPerGarage)) + + gMngr = GarageManager(garages) + + # initiate solving Algorithm + algo : SolvingAlgorithm = SolvingAlgorithm(space,gMngr) + algo : SolvingAlgorithm = AlgorithmA(space,gMngr) + + # sequence = createRandomsListSequence(points.difference(garages),garages) squence without garages + #sequence = createRandomsListSequence(points) + sequence = createRandomsListSequence(garages) # For algo A + + fmg = frameGenerator(space,gMngr) + fmg.renderFrame() + + for car in sequence: + fmg.spawnCar(car) + g = algo.getGarageForCar(car) + fmg.add_transition(g) + + renderTomp4() + + print("Traveled: "+str(algo.amountTraveled)) + + +main() + diff --git a/sprites/CarOnPark.aseprite b/sprites/CarOnPark.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..df20ed9650c2c5186353fac3176345af3807895a GIT binary patch literal 476 zcmcb^$iVPmDIyADL{+>3Ji=OK?VUJqy>lpn*Qq}3)of`pao(;%&q{o63MzO zAe)5&D5?NtC@Gk@YS^S%8uo`--!D|VxghP`;aR^wnaz9}khRaid`g~orhbsOijj?_ zy?u#6LQ{0!!{pij-x zy(Mjv&Mi^9_{zaN=+hyG@bU-jO1 pOa9uw-|s(G{%q5^%KKN)MdxJiZ+0f>tC;tvPJVob?~t2&5&*c&j)?#O literal 0 HcmV?d00001 diff --git a/sprites/CarOnPark.png b/sprites/CarOnPark.png new file mode 100644 index 0000000000000000000000000000000000000000..d18840aed061d3cef5ed14799c68550d4029f3b5 GIT binary patch literal 276 zcmV+v0qg#WP)Px#&PhZ;R9J=Wmr)PHAP9tyX8->$vxly$BSUW@G--BE)|%W`P%MH^DQYBkpa7s+ z<1cdhZ^x+0+}9j$uQyADL{+>3Ji=OK?VUJqy=yUn*Qq}3)of`pao(;%&q{o63MzO zAe)5&D5?NtC@Gk@YS^S%8uo`--!D|VxghP`;aR^wnaz9}khRaid`g~orhbsOijj?_ zy?u#6LQ{0!!{pijqdNXPBA*<{iT^$pzGBP&wd^ETIvs}n^=JmL3 zb;oDUPfeRK)ibV=?+e$1y8_Z%cDXS%C=07N2DMFKR7hJSv0C8rAGWwZhvNV_VBfSo3^DL=x_#4S3j3^P6i1` literal 0 HcmV?d00001 diff --git a/sprites/car.aseprite b/sprites/car.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..524500e170c4a8e7a2b4f71dab7f7a8118053f65 GIT binary patch literal 464 zcmcb>$iVPmDIyADL{+>3Ji=OK?VUJqy-27n*Qq}3)of`pao(;%&q{o63MzO zAe)5&D5?NtC@Gk@YS^S%8uo`--!D|VxghP`;aR^wnaz9}khRaid`g~orhbsOijj?_ zy?u#6LQ{0!!{pijU|NrIY zHxf&NWNw)hZfKY;TXSjGEZd?9r=I^hcPfQ%*4wlRH}cxP)s>zX`1fkv;y*b8d&9pc zZ{2^%{jYSW^UKBeTi0AZ>V94P?<=3c^>@EF6yP!D`G?X~KP}$5`S1On`|qC{ dUpiubl&3lOO|itcL+Q6~KYw+Ob174|004K*iTD5j literal 0 HcmV?d00001 diff --git a/sprites/car.png b/sprites/car.png new file mode 100644 index 0000000000000000000000000000000000000000..d0f10fc2bc7572027077b0c1a5583db1deb569a8 GIT binary patch literal 277 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}=RI8!~5nZZO;)hEIzns%_@f}ce1jB7??b>N^4dy$P0M}ZM!I=>3?V)v+?%y zh>(iqOxk(pFNA1>Cq%Rv=QoHx@5F-ox8)H@&LWY;OXk;vd$@?2>^xLY|H=v literal 0 HcmV?d00001 diff --git a/sprites/emptySprite.aseprite b/sprites/emptySprite.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..fe985ac75665ddce07ba042c18a32208ff271cff GIT binary patch literal 400 zcmbQh$iVPmDIyADL{+>3Ji=OK?VUJqy-QFn*Qq}3)of`pao(;%&q{o63MzO zAe)5&D5?NtC@Gk@YS^S%8uo`--!D|VxghP`;aR^wnaz9}khRaid`g~orhbsOijj?_ zy?u#6LQ{0!!{pij> D0Ssch literal 0 HcmV?d00001 diff --git a/sprites/emptySprite.png b/sprites/emptySprite.png new file mode 100644 index 0000000000000000000000000000000000000000..ac538af5d84bb24ac321e765503b99a83a5c845f GIT binary patch literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}@t!V@ArY-_ zryKGeP!KpQ^zZ-k*AALrmg${+;^WvZvVPk=&D2M6UXxZC{r+}Oe)ZC0zo$L7Hm^Ij z?O1#LevqL^;6dTxEwXp(cHI3SaO}#DH*dwRf9AeDO~g8`BxnOjnWw9t%Q~loCIF@K BJ_!H- literal 0 HcmV?d00001