import math import random import heapq import pygame from classes.Household import * from classes.Node import * from classes.Trashcan import Trashcan class Garbagetruck: def __init__(self, mult): self.mult = mult self.capacity: int = 20 self.trash: list = [] self.trashweight: int = 0 self.image = pygame.image.load("sprites/smieciara.png").convert_alpha() self.image = pygame.transform.scale(self.image, (mult, mult)) self.position = [3, 3] self.houses: list = [] self.trashcans: list = [] self.state = None self.segregation = {"Papier": "paper", "MetalPlastik": "metals_and_plastics", "Mixed": "mixed", "Bio": "bio_waste", "Szklo": "glass"} self.route = None self.scanner = None self.planner = None self.driver = None self.orientation = 3 # Niech numery będą tak: N - 0, W - 1, S - 2, E - 3 -- po prostu odwrotnie do zegara self.runningtime = 0 self.movesequence = [] self.target = None def getState(self): return self.state def setMovesequence(self, movesequence): self.movesequence = movesequence return self def setTarget(self): for place in self.houses: if place.getFinal(): self.target = place return for place in self.trashcans: if place.getFinal(): self.target = place return def getOrientation(self): return self.orientation def setOrientation(self, orientation): self.orientation = orientation % 4 return self def getRunningtime(self): return self.runningtime def setRunningtime(self, runningtime): self.runningtime = runningtime return self def incrRunningtime(self): self.runningtime += 1 return self def getTrashcans(self): return self.trashcans def setTrashcans(self, others): self.trashcans = others return self def setHouses(self, houses): self.houses = houses return self def getHouses(self): return self.houses def getCapacity(self) -> int: return self.capacity def getTrash(self) -> list: return self.trash def setTrash(self, trash: list) -> None: self.trash = trash for item in trash: self.addTrashweight(item.getWaga) def addTrash(self, trash: Trash) -> None: self.trash.append(trash) self.addTrashweight(trash.getWaga()) def getTrashweight(self) -> int: return self.trashweight def setTrashweight(self, weight: int) -> None: self.trashweight = weight def addTrashweight(self, weight: int) -> None: self.trashweight += weight def getImage(self) -> object: return self.image def setImage(self, image: object) -> None: self.image = image def getPosition(self) -> list: return self.position def setPosition(self, position: list) -> object: self.position = position return self def modPosiotion(self, modX, modY): x = self.getPosition()[0] + modX y = self.getPosition()[1] + modY position = [x, y] self.setPosition(position) def getRoute(self): return self.route def setRoute(self, route) -> None: self.route = route def getScanner(self): return self.scanner def setScanner(self, scanner) -> None: self.route = scanner def getPlanner(self): return self.planner def setPlanner(self, planner) -> None: self.route = planner def getDriver(self): return self.driver def setDriver(self, driver) -> None: self.route = driver def distance(self, object1, object2) -> int: lok1 = object1.getPosition() lok2 = object2.getPosition() dist = abs(lok1[0] - lok2[0]) + abs(lok1[1] - lok2[1]) return dist def selfdistance(self, target): if isinstance(target, (Trashcan, Household)): lok = target.getPosition() own = self.getPosition() dist = abs(lok[0] - own[0]) + abs(lok[1] - own[1]) return dist return math.inf def scanTile(self): self.state = None temp = self.houses[:] temp.extend(self.trashcans[:]) for loc in temp: if tuple(self.position) == loc.getPosition(): self.state = loc return else: self.state = False def printme(self): x, y = self.getPosition() return self.mult*x, self.mult*y def throwGarbage(self, trash): if self.segregation[trash.getTtype()] == self.state.getTrashtype(): self.addTrashweight(trash.getWeight * (-1)) self.trash.remove(trash) def rotateImage(self, arg): self.image = pygame.transform.rotate(self.image, 90*arg) def rotateLeft(self): self.setOrientation(self.getOrientation()+1) self.rotateImage(1) def rotateRight(self): self.setOrientation(self.getOrientation()-1) self.rotateImage(-1) def moveForward(self): ort = self.orientation x, y = self.getPosition() stepX = 0 stepY = 0 if ort == 0 and y != 0: stepY = -1 elif ort == 1 and x != 0: stepX = -1 elif ort == 2 and y != 20: stepY = 1 elif ort == 3 and x != 30: stepX = 1 self.modPosiotion(stepX, stepY) def graphsearch(self): house_positions = [house.getPosition() for house in self.houses] cans_positions = [can.getPosition() for can in self.trashcans] def succ(elem): def virtRotateLeft(state): ort = (state[-1] + 1) % 4 result = state[:] result[-1] = ort return result def virtRotateRight(state): ort = (state[-1] - 1) % 4 result = state[:] result[-1] = ort return result def virtMoveForward(state): ort = state[-1] x, y = state[0], state[1] stepX, stepY = 0, 0 if ort == 0 and y != 0: stepY = -1 elif ort == 1 and x != 0: stepX = -1 elif ort == 2 and y != 20: stepY = 1 elif ort == 3 and x != 30: stepX = 1 x += stepX y += stepY result = [x, y, ort] return result op = elem.getState() forward = {"result": virtMoveForward(op), "action": "F"} left = {"result": virtRotateLeft(op), "action": "L"} right = {"result": virtRotateRight(op), "action": "R"} # print("got children") return [forward, left, right] def heuristic(state): x, y, _ = state target_x, target_y = self.target.getPosition() return abs(target_x - x) + abs(target_y - y) def cost(state): x, y, _ = state if (x, y) in house_positions: return 10 elif (x,y) in cans_positions: return 5 else: return 1 fringe = [] explored = [] target = self.target.getPosition() temp = self.getPosition()[:] temp.append(self.getOrientation()) initial = Node(temp) initial.setCost(0) fringe.append((0, initial)) # (priority, node) while True: if not fringe: return False priority, elem = heapq.heappop(fringe) virtPos = elem.getState()[:-1] dist = abs(virtPos[0] - target[0]) + abs(virtPos[1] - target[1]) if dist == 0: def findWay(node): temp = node movelist = [] while temp: movelist.append(temp.getAction()) temp = temp.getParent() return movelist lista = findWay(elem) result = lista[::-1] result.pop(0) return result explored.append(elem) suc = succ(elem) for wynik in suc: if wynik['result'] not in [item[1].getState() for item in fringe] and wynik['result'] not in [item.getState() for item in explored]: x = Node(wynik["result"]) x.setParent(elem) x.setAction(wynik["action"]) x.setCost(elem.getCost() + cost(x.getState())) priority = x.getCost() + heuristic(x.getState()) heapq.heappush(fringe, (priority, x)) def executeMovement(self): element = self.movesequence.pop(0) if self.movesequence else "" if element == "L": self.rotateLeft() elif element == "R": self.rotateRight() elif element == "F": self.moveForward() def randomTarget(self): wybor1 = random.choice([1,2]) if wybor1 == 1: wybor2 = random.choice(self.houses) else: wybor2 = random.choice(self.trashcans) wybor2.switchFinal() # print(wybor2) def classifyTrash(self): pass # Tutaj jest plan żeby dopiero napisać funkcję jak już będzie klasyfikator # ogólnie to myślałem żeby po prostu zklasyfikować śmieć i zmienić mu trashtype na rozpoznany, żeby śmieciarka go tak posegreowała