1
0
forked from s444417/ProjektAI

Merge branch 'mikolaj_branch' of s444417/ProjektAI into master

This commit is contained in:
Mikołaj Krzymiński 2020-05-02 23:22:33 +00:00 committed by Gogs
commit 5ea5322cbc
8 changed files with 106 additions and 62 deletions

View File

@ -27,9 +27,9 @@ menuManager = MenuManager()
# initialize waiter component # initialize waiter component
waiter1 = Waiter(0, 0, 0, GridCountX - 1, 0, GridCountY - 1, CellSize, PaintOffset) waiter1 = Waiter(0, 0, 0, GridCountX - 1, 0, GridCountY - 1, CellSize, PaintOffset)
waiter2 = Waiter(0, 1, 0, GridCountX - 1, 0, GridCountY - 1, CellSize, PaintOffset) waiter2 = Waiter(0, GridCountY - 1, 0, GridCountX - 1, 0, GridCountY - 1, CellSize, PaintOffset)
waiter3 = Waiter(0, 2, 0, GridCountX - 1, 0, GridCountY - 1, CellSize, PaintOffset) waiter3 = Waiter(GridCountX - 1, 0, 0, GridCountX - 1, 0, GridCountY - 1, CellSize, PaintOffset)
waiter4 = Waiter(0, 3, 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 # adds waiter to drawable collection
drawableManager.add(waiter1) drawableManager.add(waiter1)
@ -38,8 +38,8 @@ drawableManager.add(waiter3)
drawableManager.add(waiter4) drawableManager.add(waiter4)
# initialize a number of tables given in range # initialize a number of tables given in range
for i in range(1, 40): for i in range(0, 40):
table = Table(0, GridCountX - 1, 0, GridCountY - 1, CellSize, PaintOffset) table = Table(1, GridCountX - 2, 1, GridCountY - 2, CellSize, PaintOffset)
if drawableManager.generatePosition(table): if drawableManager.generatePosition(table):
drawableManager.add(table) drawableManager.add(table)

View File

@ -49,6 +49,7 @@ class FinderTest(Finder):
self._set(x, y, 1) self._set(x, y, 1)
"""
cols = 20 cols = 20
rows = 20 rows = 20
table = [[0] * cols for i in range(rows)] table = [[0] * cols for i in range(rows)]
@ -58,3 +59,31 @@ originXY = finder.getRandomBorderTuple()
targetXY = finder.getRandomBorderTuple() targetXY = finder.getRandomBorderTuple()
result = finder.getPath(originXY, targetXY, True) result = finder.getPath(originXY, targetXY, True)
finder.print(result) 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)

View File

@ -1,5 +1,6 @@
import random import random
from enum import Enum from enum import Enum
from threading import Lock
from kelner.src.components.Drawable import Drawable from kelner.src.components.Drawable import Drawable
from kelner.src.managers.ImageCache import ImageCache, Images from kelner.src.managers.ImageCache import ImageCache, Images
@ -14,14 +15,16 @@ class Status(Enum):
class Table(Drawable): 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 # 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.__status = Status.NotReady
self.__order = [] self.__order = []
self.__guests = self.__getRandomGuests() self.__guests = self.__getRandomGuests()
self.__tableLock = Lock()
def __getRandomGuests(self): @staticmethod
def __getRandomGuests():
possibleGuests = [Images.Guest1, Images.Guest2, Images.Guest3] possibleGuests = [Images.Guest1, Images.Guest2, Images.Guest3]
guests = [] guests = []
guestCount = random.randint(1, len(possibleGuests)) guestCount = random.randint(1, len(possibleGuests))
@ -29,14 +32,23 @@ class Table(Drawable):
guests.insert(0, possibleGuests[random.randint(0, len(possibleGuests) - 1)]) guests.insert(0, possibleGuests[random.randint(0, len(possibleGuests) - 1)])
return guests 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): def setOrder(self, order):
self.__order = order self.__order = order
def getOrder(self): def hasOrder(self):
return self.__order return [] != self.__order
def delOrder(self):
self.setOrder([])
def isStatus(self, status): def isStatus(self, status):
return status == self.__status return status == self.__status

View File

@ -1,10 +1,8 @@
import random import random
import pygame
from kelner.src.components.Drawable import Drawable from kelner.src.components.Drawable import Drawable
from kelner.src.managers.ImageCache import ImageCache, Images from kelner.src.managers.ImageCache import ImageCache, Images
class Direction: class Direction:
LeftUp = (-1,-1) LeftUp = (-1,-1)
Up = ( 0,-1) Up = ( 0,-1)
@ -18,9 +16,9 @@ class Direction:
class Waiter(Drawable): 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 # 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.__dx = Direction.Down[0]
self.__dy = Direction.Down[1] self.__dy = Direction.Down[1]
self.__acceptedOrders = [] self.__acceptedOrders = []
@ -104,8 +102,8 @@ class Waiter(Drawable):
return (0, oldDirectionXY[1]) if abs(dx) > abs(dy) else (oldDirectionXY[0], 0) return (0, oldDirectionXY[1]) if abs(dx) > abs(dy) else (oldDirectionXY[0], 0)
# accepts orders from the table and stores them in queue # accepts orders from the table and stores them in queue
def addOrder(self, table): def addOrder(self, table, order):
self.__acceptedOrders += [(table, table.getOrder())] self.__acceptedOrders += [(table, order)]
def isPathEmpty(self): def isPathEmpty(self):
return self.__currentPath == [] return self.__currentPath == []
@ -149,15 +147,14 @@ class Waiter(Drawable):
imageToolTip = ImageCache.getInstance().getImage(Images.ToolTip, toolTipWidth, toolTipHeight) imageToolTip = ImageCache.getInstance().getImage(Images.ToolTip, toolTipWidth, toolTipHeight)
screen.blit(imageToolTip, (self.__xBase + toolTipXOffset, self.__yBase + toolTipYOffset)) screen.blit(imageToolTip, (self.__xBase + toolTipXOffset, self.__yBase + toolTipYOffset))
text = str(len(self.__acceptedOrders))
font = pygame.font.SysFont('comicsansms', 24, True) color = (204, 0, 0)
imageText = font.render(str(len(self.__acceptedOrders)), True, (204, 0, 0)) height = int(0.95 * toolTipHeight)
imageText = ImageCache.getInstance().getTextImage(text, color, height)
size = imageText.get_size() size = imageText.get_size()
ratio = 0.9 * toolTipHeight textWidth = size[0]
textWidth = int((ratio / size[1]) * size[0]) textHeight = size[1]
textHeight = int(ratio)
imageText = pygame.transform.scale(imageText, (textWidth, textHeight))
textXOffset = toolTipXOffset + int((toolTipWidth - textWidth) / 2) 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)) screen.blit(imageText, (self.__xBase + textXOffset, self.__yBase + textYOffset))

View File

@ -16,7 +16,6 @@ class DrawableCollection:
self.__mustRepaint = True self.__mustRepaint = True
self.__drawables = [] self.__drawables = []
self.__waiterLock = Lock() self.__waiterLock = Lock()
self.__tableLock = Lock()
# adds drawable objects to the collection # adds drawable objects to the collection
def add(self, drawable): def add(self, drawable):
@ -27,8 +26,8 @@ class DrawableCollection:
isPositionUnique = False isPositionUnique = False
attempt = 0 attempt = 0
while not isPositionUnique: while not isPositionUnique:
x = random.randint(drawable.getMinX() + 1, drawable.getMaxX() - 1) x = random.randint(drawable.getMinX(), drawable.getMaxX())
y = random.randint(drawable.getMinY() + 1, drawable.getMaxY() - 1) y = random.randint(drawable.getMinY(), drawable.getMaxY())
isPositionUnique = True isPositionUnique = True
for item in self.__drawables: for item in self.__drawables:
if abs(item.getX() - x) <= self.__MinDistanceX and abs(item.getY() - y) <= self.__MinDistanceY: if abs(item.getX() - x) <= self.__MinDistanceX and abs(item.getY() - y) <= self.__MinDistanceY:
@ -93,19 +92,6 @@ class DrawableCollection:
nearestTables.append(table) nearestTables.append(table)
return nearestTables 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): def moveWaiter(self, someWaiter, x, y):
isPositionAvailable = True isPositionAvailable = True
waiters = self.getWaiters() waiters = self.getWaiters()

View File

@ -38,6 +38,7 @@ class ImageCache:
raise Exception("This class is a singleton!") raise Exception("This class is a singleton!")
else: else:
ImageCache.__instance = self ImageCache.__instance = self
self.__font = None
self.__images = {} self.__images = {}
self.__paths = {Images.Background: './images/Backgroud.png', self.__paths = {Images.Background: './images/Backgroud.png',
Images.WaiterLeftUp: './images/kelner_full_LU.png', Images.WaiterLeftUp: './images/kelner_full_LU.png',
@ -57,10 +58,28 @@ class ImageCache:
Images.Guest3: './images/wiking_rudy2.png', Images.Guest3: './images/wiking_rudy2.png',
Images.ToolTip: './images/tooltip.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): 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) image = self.__images.get(key, None)
if image is None: if image is None:
image = pygame.transform.scale((pygame.image.load(self.__paths[imageKind])), (width, height)) image = pygame.transform.scale((pygame.image.load(self.__paths[imageKind])), (width, height))
self.__images[key] = image self.__images[key] = image
return 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

View File

@ -20,9 +20,9 @@ class TableManager (threading.Thread):
if tables: if tables:
tableIndex = random.randint(0, len(tables) - 1) tableIndex = random.randint(0, len(tables) - 1)
table = tables[tableIndex] table = tables[tableIndex]
time.sleep(1) time.sleep(3)
table.setStatus(Status.Ready)
table.setOrder(self.__menuManager.generateOrder()) table.setOrder(self.__menuManager.generateOrder())
table.setStatus(Status.Ready)
self.__drawableManager.forceRepaint() self.__drawableManager.forceRepaint()
def stop(self): def stop(self):

View File

@ -3,7 +3,6 @@ import time
import sys import sys
from kelner.src.components.Table import Status from kelner.src.components.Table import Status
from kelner.src.algorithms.AStar.Finder import Finder from kelner.src.algorithms.AStar.Finder import Finder
from kelner.src.algorithms.BFS.BFS import BFS
# creates new thread # creates new thread
@ -22,19 +21,18 @@ class WaiterManager (threading.Thread):
if tables: if tables:
reservedPlaces = self.__drawableManager.getReservedPlaces(waiter) reservedPlaces = self.__drawableManager.getReservedPlaces(waiter)
finder = Finder(reservedPlaces) finder = Finder(reservedPlaces)
# bfs = BFS(reservedPlaces)
origin = (waiter.getX(), waiter.getY()) origin = (waiter.getX(), waiter.getY())
for table in tables: for table in tables:
targets = finder.getNeighbours((table.getX(), table.getY()), False) if table.hasOrder():
for target in targets: targets = finder.getNeighbours((table.getX(), table.getY()), False)
if target is not None: for target in targets:
# path = bfs.find_path(origin, target) if target is not None:
path = finder.getPath(origin, target, True) path = finder.getPath(origin, target, True)
if path: if path:
result = len(path) result = len(path)
if result < distance: if result < distance:
distance = result distance = result
nearestTargetPath = path nearestTargetPath = path
return nearestTargetPath return nearestTargetPath
def __changeWaiterDirection(self, waiter, x, y): def __changeWaiterDirection(self, waiter, x, y):
@ -70,7 +68,10 @@ class WaiterManager (threading.Thread):
if lessTurnsTable is not None: if lessTurnsTable is not None:
tables.remove(lessTurnsTable) tables.remove(lessTurnsTable)
self.__changeWaiterDirection(waiter, lessTurnsTable.getX(), lessTurnsTable.getY()) 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) time.sleep(2)
lessTurnsTable.setStatus(Status.Waiting) lessTurnsTable.setStatus(Status.Waiting)
self.__drawableManager.forceRepaint() self.__drawableManager.forceRepaint()
@ -89,8 +90,8 @@ class WaiterManager (threading.Thread):
self.__changeWaiterDirection(waiter, step[0], step[1]) self.__changeWaiterDirection(waiter, step[0], step[1])
self.__moveWaiter(waiter, step[0], step[1]) self.__moveWaiter(waiter, step[0], step[1])
if waiter.isPathEmpty(): if waiter.isPathEmpty():
self.__collectOrder(waiter) self.__collectOrder(waiter)
def stop(self): def stop(self):
self.__runThread = False self.__runThread = False