From 840b9e7afc534153eaec6729baf2ec2356ad00a2 Mon Sep 17 00:00:00 2001 From: s444417 Date: Sun, 3 May 2020 01:19:34 +0200 Subject: [PATCH] =?UTF-8?q?przeniesiono=20generowanie=20tooltip=C3=B3w=20d?= =?UTF-8?q?o=20ImageCache,=20lepsza=20synchronizacja=20pobierania=20zam?= =?UTF-8?q?=C3=B3wienia=20od=20stolika?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kelner/main.py | 10 ++++---- kelner/src/algorithms/AStar/FinderTest.py | 29 +++++++++++++++++++++ kelner/src/components/Table.py | 28 ++++++++++++++------ kelner/src/components/Waiter.py | 27 +++++++++----------- kelner/src/managers/DrawableCollection.py | 18 ++----------- kelner/src/managers/ImageCache.py | 21 ++++++++++++++- kelner/src/managers/TableManager.py | 4 +-- kelner/src/managers/WaiterManager.py | 31 ++++++++++++----------- 8 files changed, 106 insertions(+), 62 deletions(-) diff --git a/kelner/main.py b/kelner/main.py index 604fa4f..199f2f8 100644 --- a/kelner/main.py +++ b/kelner/main.py @@ -27,9 +27,9 @@ menuManager = MenuManager() # initialize waiter component waiter1 = Waiter(0, 0, 0, GridCountX - 1, 0, GridCountY - 1, CellSize, PaintOffset) -waiter2 = Waiter(0, 1, 0, GridCountX - 1, 0, GridCountY - 1, CellSize, PaintOffset) -waiter3 = Waiter(0, 2, 0, GridCountX - 1, 0, GridCountY - 1, CellSize, PaintOffset) -waiter4 = Waiter(0, 3, 0, GridCountX - 1, 0, GridCountY - 1, CellSize, PaintOffset) +waiter2 = Waiter(0, GridCountY - 1, 0, GridCountX - 1, 0, GridCountY - 1, CellSize, PaintOffset) +waiter3 = Waiter(GridCountX - 1, 0, 0, GridCountX - 1, 0, GridCountY - 1, CellSize, PaintOffset) +waiter4 = Waiter(GridCountX - 1, GridCountY - 1, 0, GridCountX - 1, 0, GridCountY - 1, CellSize, PaintOffset) # adds waiter to drawable collection drawableManager.add(waiter1) @@ -38,8 +38,8 @@ drawableManager.add(waiter3) drawableManager.add(waiter4) # initialize a number of tables given in range -for i in range(1, 40): - table = Table(0, GridCountX - 1, 0, GridCountY - 1, CellSize, PaintOffset) +for i in range(0, 40): + table = Table(1, GridCountX - 2, 1, GridCountY - 2, CellSize, PaintOffset) if drawableManager.generatePosition(table): drawableManager.add(table) diff --git a/kelner/src/algorithms/AStar/FinderTest.py b/kelner/src/algorithms/AStar/FinderTest.py index 945681a..86dc5fb 100644 --- a/kelner/src/algorithms/AStar/FinderTest.py +++ b/kelner/src/algorithms/AStar/FinderTest.py @@ -49,6 +49,7 @@ class FinderTest(Finder): self._set(x, y, 1) +""" cols = 20 rows = 20 table = [[0] * cols for i in range(rows)] @@ -58,3 +59,31 @@ originXY = finder.getRandomBorderTuple() targetXY = finder.getRandomBorderTuple() result = finder.getPath(originXY, targetXY, True) finder.print(result) +""" + +table = [[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0], + [0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0], + [0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1], + [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], + [1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], + [0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0], + [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0], + [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0], + [1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0], + [1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0], + [0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0], + [1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1], + [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1], + [0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1], + [1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0]] + +finder = FinderTest(table) +originXY = ( 6, 19) +targetXY = (13, 0) +result = finder.getPath(originXY, targetXY, True) +finder.print(result) diff --git a/kelner/src/components/Table.py b/kelner/src/components/Table.py index da5d328..bde2e96 100644 --- a/kelner/src/components/Table.py +++ b/kelner/src/components/Table.py @@ -1,5 +1,6 @@ import random from enum import Enum +from threading import Lock from kelner.src.components.Drawable import Drawable from kelner.src.managers.ImageCache import ImageCache, Images @@ -14,14 +15,16 @@ class Status(Enum): class Table(Drawable): - def __init__(self, minX, maxX, minY, maxY, ratio, offset): + def __init__(self, minX, maxX, minY, maxY, cellSize, offset): # call base class constructor - super().__init__(0, 0, minX, maxX, minY, maxY, ratio, offset) + super().__init__(0, 0, minX, maxX, minY, maxY, cellSize, offset) self.__status = Status.NotReady self.__order = [] self.__guests = self.__getRandomGuests() + self.__tableLock = Lock() - def __getRandomGuests(self): + @staticmethod + def __getRandomGuests(): possibleGuests = [Images.Guest1, Images.Guest2, Images.Guest3] guests = [] guestCount = random.randint(1, len(possibleGuests)) @@ -29,14 +32,23 @@ class Table(Drawable): guests.insert(0, possibleGuests[random.randint(0, len(possibleGuests) - 1)]) return guests + # waiter collects orders from table + def getOrder(self): + order = None + if self.__tableLock.acquire(False): + try: + if self.isStatus(Status.Ready) and self.hasOrder(): + order = self.__order + self.setOrder([]) + finally: + self.__tableLock.release() + return order + def setOrder(self, order): self.__order = order - def getOrder(self): - return self.__order - - def delOrder(self): - self.setOrder([]) + def hasOrder(self): + return [] != self.__order def isStatus(self, status): return status == self.__status diff --git a/kelner/src/components/Waiter.py b/kelner/src/components/Waiter.py index e08788b..445e69a 100644 --- a/kelner/src/components/Waiter.py +++ b/kelner/src/components/Waiter.py @@ -1,10 +1,8 @@ import random - -import pygame - from kelner.src.components.Drawable import Drawable from kelner.src.managers.ImageCache import ImageCache, Images + class Direction: LeftUp = (-1,-1) Up = ( 0,-1) @@ -18,9 +16,9 @@ class Direction: class Waiter(Drawable): - def __init__(self, x, y, minX, maxX, minY, maxY, ratio, offset): + def __init__(self, x, y, minX, maxX, minY, maxY, cellSize, offset): # call base class constructor - super().__init__(x, y, minX, maxX, minY, maxY, ratio, offset) + super().__init__(x, y, minX, maxX, minY, maxY, cellSize, offset) self.__dx = Direction.Down[0] self.__dy = Direction.Down[1] self.__acceptedOrders = [] @@ -104,8 +102,8 @@ class Waiter(Drawable): return (0, oldDirectionXY[1]) if abs(dx) > abs(dy) else (oldDirectionXY[0], 0) # accepts orders from the table and stores them in queue - def addOrder(self, table): - self.__acceptedOrders += [(table, table.getOrder())] + def addOrder(self, table, order): + self.__acceptedOrders += [(table, order)] def isPathEmpty(self): return self.__currentPath == [] @@ -149,15 +147,14 @@ class Waiter(Drawable): imageToolTip = ImageCache.getInstance().getImage(Images.ToolTip, toolTipWidth, toolTipHeight) screen.blit(imageToolTip, (self.__xBase + toolTipXOffset, self.__yBase + toolTipYOffset)) - - font = pygame.font.SysFont('comicsansms', 24, True) - imageText = font.render(str(len(self.__acceptedOrders)), True, (204, 0, 0)) + text = str(len(self.__acceptedOrders)) + color = (204, 0, 0) + height = int(0.95 * toolTipHeight) + imageText = ImageCache.getInstance().getTextImage(text, color, height) size = imageText.get_size() - ratio = 0.9 * toolTipHeight - textWidth = int((ratio / size[1]) * size[0]) - textHeight = int(ratio) - imageText = pygame.transform.scale(imageText, (textWidth, textHeight)) + textWidth = size[0] + textHeight = size[1] textXOffset = toolTipXOffset + int((toolTipWidth - textWidth) / 2) - textYOffset = toolTipYOffset + int(0.05 * toolTipHeight) + textYOffset = toolTipYOffset + int((toolTipHeight - textHeight) / 2) screen.blit(imageText, (self.__xBase + textXOffset, self.__yBase + textYOffset)) diff --git a/kelner/src/managers/DrawableCollection.py b/kelner/src/managers/DrawableCollection.py index 445880f..05d5216 100644 --- a/kelner/src/managers/DrawableCollection.py +++ b/kelner/src/managers/DrawableCollection.py @@ -16,7 +16,6 @@ class DrawableCollection: self.__mustRepaint = True self.__drawables = [] self.__waiterLock = Lock() - self.__tableLock = Lock() # adds drawable objects to the collection def add(self, drawable): @@ -27,8 +26,8 @@ class DrawableCollection: isPositionUnique = False attempt = 0 while not isPositionUnique: - x = random.randint(drawable.getMinX() + 1, drawable.getMaxX() - 1) - y = random.randint(drawable.getMinY() + 1, drawable.getMaxY() - 1) + x = random.randint(drawable.getMinX(), drawable.getMaxX()) + y = random.randint(drawable.getMinY(), drawable.getMaxY()) isPositionUnique = True for item in self.__drawables: if abs(item.getX() - x) <= self.__MinDistanceX and abs(item.getY() - y) <= self.__MinDistanceY: @@ -93,19 +92,6 @@ class DrawableCollection: nearestTables.append(table) return nearestTables - # waiter collects orders from table - def collectOrder(self, waiter, table): - result = False - self.__tableLock.acquire() - try: - if table.isStatus(Status.Ready) and table.getOrder() != []: - waiter.addOrder(table) - table.delOrder() - result = True - finally: - self.__tableLock.release() - return result - def moveWaiter(self, someWaiter, x, y): isPositionAvailable = True waiters = self.getWaiters() diff --git a/kelner/src/managers/ImageCache.py b/kelner/src/managers/ImageCache.py index 014ae56..dc1815f 100644 --- a/kelner/src/managers/ImageCache.py +++ b/kelner/src/managers/ImageCache.py @@ -38,6 +38,7 @@ class ImageCache: raise Exception("This class is a singleton!") else: ImageCache.__instance = self + self.__font = None self.__images = {} self.__paths = {Images.Background: './images/Backgroud.png', Images.WaiterLeftUp: './images/kelner_full_LU.png', @@ -57,10 +58,28 @@ class ImageCache: Images.Guest3: './images/wiking_rudy2.png', Images.ToolTip: './images/tooltip.png'} + def __getFont(self): + if self.__font is None: + self.__font = font = pygame.font.SysFont('comicsansms', 24, True) + return self.__font + def getImage(self, imageKind, width, height): - key = str(imageKind.value) + ':' + str(width) + ':' + str(height) + key = imageKind.name + ':' + str(width) + 'x' + str(height) image = self.__images.get(key, None) if image is None: image = pygame.transform.scale((pygame.image.load(self.__paths[imageKind])), (width, height)) self.__images[key] = image return image + + def getTextImage(self, text, color, height): + key = text + ':' + str(color) + 'x' + str(height) + image = self.__images.get(key, None) + if image is None: + font = self.__getFont() + image = font.render(text, False, color) + size = image.get_size() + width = int((height / size[1]) * size[0]) + height = int(height) + image = pygame.transform.scale(image, (width, height)) + self.__images[key] = image + return image diff --git a/kelner/src/managers/TableManager.py b/kelner/src/managers/TableManager.py index 1eb38cc..c824a00 100644 --- a/kelner/src/managers/TableManager.py +++ b/kelner/src/managers/TableManager.py @@ -20,9 +20,9 @@ class TableManager (threading.Thread): if tables: tableIndex = random.randint(0, len(tables) - 1) table = tables[tableIndex] - time.sleep(1) - table.setStatus(Status.Ready) + time.sleep(3) table.setOrder(self.__menuManager.generateOrder()) + table.setStatus(Status.Ready) self.__drawableManager.forceRepaint() def stop(self): diff --git a/kelner/src/managers/WaiterManager.py b/kelner/src/managers/WaiterManager.py index e1b8b64..056f00a 100644 --- a/kelner/src/managers/WaiterManager.py +++ b/kelner/src/managers/WaiterManager.py @@ -3,7 +3,6 @@ import time import sys from kelner.src.components.Table import Status from kelner.src.algorithms.AStar.Finder import Finder -from kelner.src.algorithms.BFS.BFS import BFS # creates new thread @@ -22,19 +21,18 @@ class WaiterManager (threading.Thread): if tables: reservedPlaces = self.__drawableManager.getReservedPlaces(waiter) finder = Finder(reservedPlaces) - # bfs = BFS(reservedPlaces) origin = (waiter.getX(), waiter.getY()) for table in tables: - targets = finder.getNeighbours((table.getX(), table.getY()), False) - for target in targets: - if target is not None: - # path = bfs.find_path(origin, target) - path = finder.getPath(origin, target, True) - if path: - result = len(path) - if result < distance: - distance = result - nearestTargetPath = path + if table.hasOrder(): + targets = finder.getNeighbours((table.getX(), table.getY()), False) + for target in targets: + if target is not None: + path = finder.getPath(origin, target, True) + if path: + result = len(path) + if result < distance: + distance = result + nearestTargetPath = path return nearestTargetPath def __changeWaiterDirection(self, waiter, x, y): @@ -70,7 +68,10 @@ class WaiterManager (threading.Thread): if lessTurnsTable is not None: tables.remove(lessTurnsTable) self.__changeWaiterDirection(waiter, lessTurnsTable.getX(), lessTurnsTable.getY()) - if self.__drawableManager.collectOrder(waiter, lessTurnsTable): + + order = lessTurnsTable.getOrder() + if order is not None: + waiter.addOrder(lessTurnsTable, order) time.sleep(2) lessTurnsTable.setStatus(Status.Waiting) self.__drawableManager.forceRepaint() @@ -89,8 +90,8 @@ class WaiterManager (threading.Thread): self.__changeWaiterDirection(waiter, step[0], step[1]) self.__moveWaiter(waiter, step[0], step[1]) - if waiter.isPathEmpty(): - self.__collectOrder(waiter) + if waiter.isPathEmpty(): + self.__collectOrder(waiter) def stop(self): self.__runThread = False