Merge branch 'mikolaj_branch' of s444417/ProjektAI into master
@ -2,7 +2,7 @@
|
|||||||
<module type="PYTHON_MODULE" version="4">
|
<module type="PYTHON_MODULE" version="4">
|
||||||
<component name="NewModuleRootManager">
|
<component name="NewModuleRootManager">
|
||||||
<content url="file://$MODULE_DIR$" />
|
<content url="file://$MODULE_DIR$" />
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="jdk" jdkName="Python 3.7 (WaiterMaster)" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
<component name="TestRunnerService">
|
<component name="TestRunnerService">
|
||||||
|
@ -3,4 +3,5 @@
|
|||||||
<component name="JavaScriptSettings">
|
<component name="JavaScriptSettings">
|
||||||
<option name="languageLevel" value="ES6" />
|
<option name="languageLevel" value="ES6" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (WaiterMaster)" project-jdk-type="Python SDK" />
|
||||||
</project>
|
</project>
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 706 B After Width: | Height: | Size: 657 B |
Before Width: | Height: | Size: 988 B After Width: | Height: | Size: 832 B |
Before Width: | Height: | Size: 979 B After Width: | Height: | Size: 833 B |
Before Width: | Height: | Size: 977 B After Width: | Height: | Size: 832 B |
@ -1,60 +1,64 @@
|
|||||||
import pygame
|
import pygame
|
||||||
from src.components.GridBoard import GridBoard
|
from kelner.src.components.GridBoard import GridBoard
|
||||||
from src.managers.DrawableCollection import DrawableCollection
|
from kelner.src.components.Waiter import Waiter
|
||||||
from src.managers.MenuManager import MenuManager
|
from kelner.src.components.Table import Table
|
||||||
from src.components.Waiter import Waiter
|
from kelner.src.managers.DrawableCollection import DrawableCollection
|
||||||
from src.components.Table import Table
|
from kelner.src.managers.MenuManager import MenuManager
|
||||||
from src.managers.TaskManager import TaskManager
|
from kelner.src.managers.TableManager import TableManager
|
||||||
|
from kelner.src.managers.WaiterManager import WaiterManager
|
||||||
|
|
||||||
#create screen consts
|
# create screen consts
|
||||||
CellSize = 100 #pixel size of 1 square cell in the grid
|
Scale = 2 # scale for all images used within project
|
||||||
GridCountX = 15 #number of columns in grid
|
CellSize = round(50 * Scale) # pixel size of 1 square cell in the grid
|
||||||
GridCountY = 9 #number of rows in grid
|
PaintOffset = CellSize # pixel size of paint offset for all drawables
|
||||||
ScreenWidth = CellSize * GridCountX #screen width in pixels
|
GridCountX = 15 # number of columns in grid
|
||||||
ScreenHeight = CellSize * GridCountY #screen height in pixels
|
GridCountY = 9 # number of rows in grid
|
||||||
Offset = 50
|
ScreenWidth = CellSize * GridCountX + 2 * PaintOffset # screen width in pixels
|
||||||
|
ScreenHeight = CellSize * GridCountY + 2 * PaintOffset # screen height in pixels
|
||||||
|
|
||||||
#initialize background
|
# initialize background
|
||||||
gridBoard = GridBoard(ScreenWidth+200, ScreenHeight+200, CellSize)
|
gridBoard = GridBoard(ScreenWidth, ScreenHeight)
|
||||||
|
|
||||||
#initialize drawable objects manager
|
# initialize drawable objects manager
|
||||||
drawableManager = DrawableCollection()
|
drawableManager = DrawableCollection()
|
||||||
|
|
||||||
#initialize menu manager
|
# initialize menu manager
|
||||||
menuManager = MenuManager()
|
menuManager = MenuManager()
|
||||||
|
|
||||||
#initialize waiter component
|
# initialize waiter component
|
||||||
waiter = Waiter(0, 0, 0, GridCountX - 1, 0, GridCountY - 1, CellSize)
|
waiter = Waiter(0, 0, 0, GridCountX - 1, 0, GridCountY - 1, CellSize, PaintOffset)
|
||||||
|
|
||||||
#adds waiter to drawable collection
|
# adds waiter to drawable collection
|
||||||
drawableManager.add(waiter)
|
drawableManager.add(waiter)
|
||||||
|
|
||||||
#initialize a number of tables given in range
|
# initialize a number of tables given in range
|
||||||
for i in range(1, 20):
|
for i in range(1, 45):
|
||||||
table = Table(0, GridCountX - 1, 0, GridCountY - 1, CellSize)
|
table = Table(0, GridCountX - 1, 0, GridCountY - 1, CellSize, PaintOffset)
|
||||||
drawableManager.generatePosition(table)
|
drawableManager.generatePosition(table)
|
||||||
drawableManager.add(table)
|
drawableManager.add(table)
|
||||||
|
|
||||||
#main loop
|
# new thread controlling tables
|
||||||
|
tableTask = TableManager(drawableManager, menuManager)
|
||||||
|
tableTask.start()
|
||||||
|
|
||||||
#object that controlls repainting of changed objects
|
# new thread controlling waiter
|
||||||
doRepaint = [True]
|
waiterTask = WaiterManager(drawableManager)
|
||||||
|
waiterTask.start()
|
||||||
#new thread
|
|
||||||
task = TaskManager(drawableManager, menuManager, doRepaint)
|
|
||||||
task.start()
|
|
||||||
|
|
||||||
|
# main loop
|
||||||
running = True
|
running = True
|
||||||
while running:
|
while running:
|
||||||
|
|
||||||
for event in pygame.event.get():
|
for event in pygame.event.get():
|
||||||
if event.type == pygame.QUIT:
|
if event.type == pygame.QUIT:
|
||||||
|
tableTask.stop()
|
||||||
|
waiterTask.stop()
|
||||||
running = False
|
running = False
|
||||||
|
|
||||||
#handles keyboard events
|
# handles keyboard events
|
||||||
if event.type == pygame.KEYDOWN:
|
if event.type == pygame.KEYDOWN:
|
||||||
if event.key == pygame.K_LEFT:
|
if event.key == pygame.K_LEFT:
|
||||||
#checks if new waiter's position to the left is not occupied by other object
|
# checks if new waiter's position to the left is not occupied by other object
|
||||||
if drawableManager.isPositionAvailable(waiter.getX() - 1, waiter.getY()):
|
if drawableManager.isPositionAvailable(waiter.getX() - 1, waiter.getY()):
|
||||||
waiter.moveLeft()
|
waiter.moveLeft()
|
||||||
if event.key == pygame.K_RIGHT:
|
if event.key == pygame.K_RIGHT:
|
||||||
@ -69,13 +73,11 @@ while running:
|
|||||||
# checks if new waiter's position down is not occupied by other object
|
# checks if new waiter's position down is not occupied by other object
|
||||||
if drawableManager.isPositionAvailable(waiter.getX(), waiter.getY() + 1):
|
if drawableManager.isPositionAvailable(waiter.getX(), waiter.getY() + 1):
|
||||||
waiter.moveDown()
|
waiter.moveDown()
|
||||||
doRepaint[0] = True
|
drawableManager.forceRepaint()
|
||||||
|
|
||||||
# repaints all objects to the screen
|
# repaints all objects to the screen
|
||||||
# is set only on initial paint or after keyboard event
|
# is set only on initial paint or after keyboard event or call to forceRepaint()
|
||||||
if doRepaint[0]:
|
if drawableManager.mustRepaint():
|
||||||
gridBoard.reinitialize()
|
gridBoard.reinitialize()
|
||||||
gridBoard.draw(drawableManager)
|
gridBoard.draw(drawableManager)
|
||||||
gridBoard.udpdate()
|
gridBoard.udpdate()
|
||||||
doRepaint[0] = False
|
|
||||||
drawableManager.collectOrders()
|
|
125
kelner/src/algorithms/AStar/Finder.py
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
from queue import PriorityQueue
|
||||||
|
from kelner.src.algorithms.AStar.Node import Node
|
||||||
|
|
||||||
|
|
||||||
|
class Finder:
|
||||||
|
|
||||||
|
def __init__(self, table):
|
||||||
|
self._table = table
|
||||||
|
self._xMin = 0
|
||||||
|
self._yMin = 0
|
||||||
|
self._xMax = len(table[0]) - 1
|
||||||
|
self._yMax = len(table) - 1
|
||||||
|
self.__isDiagonal = False
|
||||||
|
|
||||||
|
def _set(self, x, y, v):
|
||||||
|
self._table[y][x] = v
|
||||||
|
|
||||||
|
def _get(self, x, y):
|
||||||
|
return self._table[y][x]
|
||||||
|
|
||||||
|
# returns right position relative to the node
|
||||||
|
def __incXnopY(self, node, neighbours):
|
||||||
|
if node.x < self._xMax and self._get(node.x + 1, node.y) == 0:
|
||||||
|
neighbours.append(Node(node, node.x + 1, node.y, node.distance + 1))
|
||||||
|
|
||||||
|
# returns left position relative to the node
|
||||||
|
def __decXnopY(self, node, neighbours):
|
||||||
|
if self._xMin < node.x and self._get(node.x - 1, node.y) == 0:
|
||||||
|
neighbours.append(Node(node, node.x - 1, node.y, node.distance + 1))
|
||||||
|
|
||||||
|
# returns top position relative to the node
|
||||||
|
def __nopXincY(self, node, neighbours):
|
||||||
|
if node.y < self._yMax and self._get(node.x, node.y + 1) == 0:
|
||||||
|
neighbours.append(Node(node, node.x, node.y + 1, node.distance + 1))
|
||||||
|
|
||||||
|
# returns bottom position relative to the node
|
||||||
|
def __nopXdecY(self, node, neighbours):
|
||||||
|
if self._yMin < node.y and self._get(node.x, node.y - 1) == 0:
|
||||||
|
neighbours.append(Node(node, node.x, node.y - 1, node.distance + 1))
|
||||||
|
|
||||||
|
# returns left top position relative to the node
|
||||||
|
def __decXdecY(self, node, neighbours):
|
||||||
|
if (self._xMin < node.x and self._yMin < node.y and
|
||||||
|
self._get(node.x - 1, node.y - 1) == 0 and
|
||||||
|
self._get(node.x - 1, node.y) == 0 and
|
||||||
|
self._get(node.x, node.y - 1) == 0):
|
||||||
|
neighbours.append(Node(node, node.x - 1, node.y - 1, node.distance + 2))
|
||||||
|
|
||||||
|
# returns left bottom position relative to the node
|
||||||
|
def __decXincY(self, node, neighbours):
|
||||||
|
if (self._xMin < node.x and node.y < self._yMax and
|
||||||
|
self._get(node.x - 1, node.y + 1) == 0 and
|
||||||
|
self._get(node.x - 1, node.y) == 0 and
|
||||||
|
self._get(node.x, node.y + 1) == 0):
|
||||||
|
neighbours.append(Node(node, node.x - 1, node.y + 1, node.distance + 2))
|
||||||
|
|
||||||
|
# returns right bottom position relative to the node
|
||||||
|
def __incXincY(self, node, neighbours):
|
||||||
|
if (node.x < self._xMax and node.y < self._yMax and
|
||||||
|
self._get(node.x + 1, node.y + 1) == 0 and
|
||||||
|
self._get(node.x + 1, node.y) == 0 and
|
||||||
|
self._get(node.x, node.y + 1) == 0):
|
||||||
|
neighbours.append(Node(node, node.x + 1, node.y + 1, node.distance + 2))
|
||||||
|
|
||||||
|
# returns right top position relative to the node
|
||||||
|
def __incXdecY(self, node, neighbours):
|
||||||
|
if (node.x < self._xMax and self._yMin < node.y and
|
||||||
|
self._get(node.x + 1, node.y - 1) == 0 and
|
||||||
|
self._get(node.x + 1, node.y) == 0 and
|
||||||
|
self._get(node.x, node.y - 1) == 0):
|
||||||
|
neighbours.append(Node(node, node.x + 1, node.y - 1, node.distance + 2))
|
||||||
|
|
||||||
|
# returns all plausible positions relative to the node
|
||||||
|
def __getNeighbours(self, node):
|
||||||
|
neighbours = []
|
||||||
|
self.__nopXincY(node, neighbours)
|
||||||
|
self.__incXnopY(node, neighbours)
|
||||||
|
self.__decXnopY(node, neighbours)
|
||||||
|
self.__nopXdecY(node, neighbours)
|
||||||
|
if self.__isDiagonal:
|
||||||
|
self.__decXdecY(node, neighbours)
|
||||||
|
self.__decXincY(node, neighbours)
|
||||||
|
self.__incXincY(node, neighbours)
|
||||||
|
self.__incXdecY(node, neighbours)
|
||||||
|
return neighbours
|
||||||
|
|
||||||
|
# main algorithm - simplification of well known A*
|
||||||
|
def __getPath(self, origin, target):
|
||||||
|
Q = PriorityQueue()
|
||||||
|
V = set()
|
||||||
|
Q.put(origin)
|
||||||
|
while not Q.empty():
|
||||||
|
head = Q.get()
|
||||||
|
if head == target:
|
||||||
|
return head
|
||||||
|
V.add(head)
|
||||||
|
for node in self.__getNeighbours(head):
|
||||||
|
if node not in V:
|
||||||
|
node.estimated = node.distance + node.getDistanceTo(target)
|
||||||
|
Q.put(node)
|
||||||
|
V.add(node)
|
||||||
|
return None
|
||||||
|
|
||||||
|
# returns neighbours for locationXY-tuple as list of tuple(x,y)
|
||||||
|
def getNeighbours(self, locationXY, isDiagonal):
|
||||||
|
neighboursXY = []
|
||||||
|
self.__isDiagonal = isDiagonal
|
||||||
|
location = Node(None, locationXY[0], locationXY[1], 0)
|
||||||
|
neighbours = self.__getNeighbours(location)
|
||||||
|
for neighbour in neighbours:
|
||||||
|
neighboursXY.append((neighbour.x, neighbour.y))
|
||||||
|
return neighboursXY
|
||||||
|
|
||||||
|
# returns the shortest path as list of tuple(x,y) from originXY-tuple to targetXY-tuple
|
||||||
|
def getPath(self, originXY, targetXY, isDiagonal):
|
||||||
|
self.__isDiagonal = isDiagonal
|
||||||
|
origin = Node(None, originXY[0], originXY[1], 0)
|
||||||
|
target = Node(None, targetXY[0], targetXY[1], 0)
|
||||||
|
result = self.__getPath(origin, target)
|
||||||
|
path = []
|
||||||
|
while result is not None:
|
||||||
|
if result.parent is not None:
|
||||||
|
path.insert(0, (result.x, result.y))
|
||||||
|
result = result.parent
|
||||||
|
return path
|
60
kelner/src/algorithms/AStar/FinderTest.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
from random import randint
|
||||||
|
from kelner.src.algorithms.AStar.Finder import Finder
|
||||||
|
|
||||||
|
|
||||||
|
class FinderTest(Finder):
|
||||||
|
|
||||||
|
def __init__(self, table):
|
||||||
|
super().__init__(table)
|
||||||
|
|
||||||
|
def __setValues(self, xys, v):
|
||||||
|
if xys is not None:
|
||||||
|
for xy in xys:
|
||||||
|
self._set(xy[0], xy[1], v)
|
||||||
|
|
||||||
|
def print(self, xys):
|
||||||
|
self.__setValues(xys, 2)
|
||||||
|
for row in self._table:
|
||||||
|
for col in row:
|
||||||
|
v = ' ' if col == 0 else '#' if col == 1 else 'O'
|
||||||
|
print('|', v, sep='', end='')
|
||||||
|
print('|')
|
||||||
|
self.__setValues(xys, 0)
|
||||||
|
|
||||||
|
def getRandomTuple(self):
|
||||||
|
while True:
|
||||||
|
x = randint(self._xMin, self._xMax)
|
||||||
|
y = randint(self._yMin, self._yMax)
|
||||||
|
if self._get(x, y) == 0:
|
||||||
|
break
|
||||||
|
return x, y
|
||||||
|
|
||||||
|
def getRandomBorderTuple(self):
|
||||||
|
xSet = [self._xMin, self._xMax]
|
||||||
|
ySet = [self._yMin, self._yMax]
|
||||||
|
while True:
|
||||||
|
x = randint(self._xMin, self._xMax)
|
||||||
|
y = randint(self._yMin, self._yMax)
|
||||||
|
if (x in xSet or y in ySet) and self._get(x, y) == 0:
|
||||||
|
break
|
||||||
|
return x, y
|
||||||
|
|
||||||
|
def fillRandom(self):
|
||||||
|
for _ in range(120):
|
||||||
|
while True:
|
||||||
|
x = randint(self._xMin, self._xMax)
|
||||||
|
y = randint(self._yMin, self._yMax)
|
||||||
|
if self._get(x, y) == 0:
|
||||||
|
break
|
||||||
|
self._set(x, y, 1)
|
||||||
|
|
||||||
|
|
||||||
|
cols = 20
|
||||||
|
rows = 20
|
||||||
|
table = [[0] * cols for i in range(rows)]
|
||||||
|
finder = FinderTest(table)
|
||||||
|
finder.fillRandom()
|
||||||
|
originXY = finder.getRandomBorderTuple()
|
||||||
|
targetXY = finder.getRandomBorderTuple()
|
||||||
|
result = finder.getPath(originXY, targetXY, True)
|
||||||
|
finder.print(result)
|
34
kelner/src/algorithms/AStar/Node.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
from math import sqrt
|
||||||
|
|
||||||
|
|
||||||
|
class Node:
|
||||||
|
|
||||||
|
def __init__(self, parent, x, y, distance):
|
||||||
|
self.parent = parent
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.distance = distance
|
||||||
|
self.estimated = distance
|
||||||
|
|
||||||
|
# returns distance from the object to other node
|
||||||
|
def getDistanceTo(self, other):
|
||||||
|
dx = self.x - other.x
|
||||||
|
dy = self.y - other.y
|
||||||
|
return sqrt(dx * dx + dy * dy)
|
||||||
|
# abs(dx) + abs(dy)
|
||||||
|
|
||||||
|
# used by str() method to represent the object
|
||||||
|
def __repr__(self):
|
||||||
|
return "%s:%s" % (self.x, self.y)
|
||||||
|
|
||||||
|
# generates hash key for Set
|
||||||
|
def __hash__(self):
|
||||||
|
return hash(str(self))
|
||||||
|
|
||||||
|
# operator (==) for Set (determines if the object equals other node)
|
||||||
|
def __eq__(self, other):
|
||||||
|
return (self.x == other.x) and (self.y == other.y)
|
||||||
|
|
||||||
|
# operator (>) for PriorityQueue comparison (determines the objects order)
|
||||||
|
def __gt__(self, other):
|
||||||
|
return self.estimated > other.estimated
|
@ -5,29 +5,33 @@ class Drawable:
|
|||||||
RED = (255, 0, 0)
|
RED = (255, 0, 0)
|
||||||
GREEN = (0, 255, 0)
|
GREEN = (0, 255, 0)
|
||||||
|
|
||||||
def __init__(self, x, y, minX, maxX, minY, maxY, ratio):
|
def __init__(self, x, y, minX, maxX, minY, maxY, cellSize, offset):
|
||||||
self.__minX = minX
|
self.__minX = minX
|
||||||
self.__maxX = maxX
|
self.__maxX = maxX
|
||||||
self.__minY = minY
|
self.__minY = minY
|
||||||
self.__maxY = maxY
|
self.__maxY = maxY
|
||||||
self.setX(x)
|
self.setX(x)
|
||||||
self.setY(y)
|
self.setY(y)
|
||||||
self.__ratio = ratio #cell size
|
self.__cellSize = cellSize # cell size in pixels
|
||||||
|
self.__offset = offset # paint offset in pixels
|
||||||
|
|
||||||
def setX(self, x):
|
def setX(self, x):
|
||||||
if (x < self.__minX or self.__maxX < x):
|
if x < self.__minX or self.__maxX < x:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
self.__x = x
|
self.__x = x
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def setY(self, y):
|
def setY(self, y):
|
||||||
if (y < self.__minY or self.__maxY < y):
|
if y < self.__minY or self.__maxY < y:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
self.__y = y
|
self.__y = y
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def isPositionCorrect(self, x, y):
|
||||||
|
return self.__minX <= x <= self.__maxX and self.__minY <= y <= self.__maxY
|
||||||
|
|
||||||
def getX(self):
|
def getX(self):
|
||||||
return self.__x
|
return self.__x
|
||||||
|
|
||||||
@ -46,8 +50,14 @@ class Drawable:
|
|||||||
def getMaxY(self):
|
def getMaxY(self):
|
||||||
return self.__maxY
|
return self.__maxY
|
||||||
|
|
||||||
def getRatio(self):
|
def getCellSize(self):
|
||||||
return self.__ratio
|
return self.__cellSize
|
||||||
|
|
||||||
|
def getOffset(self):
|
||||||
|
return self.__offset
|
||||||
|
|
||||||
def draw(self, screen):
|
def draw(self, screen):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def drawAux(self, screen):
|
||||||
|
pass
|
||||||
|
@ -1,28 +1,32 @@
|
|||||||
import pygame
|
import pygame
|
||||||
|
from kelner.src.managers.ImageCache import ImageCache, Images
|
||||||
|
|
||||||
|
|
||||||
class GridBoard:
|
class GridBoard:
|
||||||
|
|
||||||
def __init__(self, width, height, cellSize):
|
def __init__(self, width, height):
|
||||||
pygame.init() #initialize the pygame
|
pygame.init() # initialize the pygame
|
||||||
pygame.display.set_caption("Bardzo mądry kelner") #window caption
|
pygame.display.set_caption("Bardzo mądry kelner") # window caption
|
||||||
self.__width = width
|
self.__width = width
|
||||||
self.__height = height
|
self.__height = height
|
||||||
self.__cellSize = cellSize
|
|
||||||
self.__screen = pygame.display.set_mode((width, height)) # initialize screen
|
self.__screen = pygame.display.set_mode((width, height)) # initialize screen
|
||||||
self.Offset = 50
|
|
||||||
|
|
||||||
#fills the screen with white and draws grid
|
# draws the background
|
||||||
def reinitialize(self):
|
def reinitialize(self):
|
||||||
|
imageBackground = ImageCache.getInstance().getImage(Images.Background, self.__width, self.__height)
|
||||||
|
self.__screen.blit(imageBackground, (0, 0))
|
||||||
|
""" # code below fills the screen with white and draws grid
|
||||||
self.__screen.fill((255, 255, 255))
|
self.__screen.fill((255, 255, 255))
|
||||||
for x in range(0, self.__width, self.__cellSize):
|
for x in range(0, self.__width, self.__cellSize):
|
||||||
pygame.draw.line(self.__screen, (0,0,0), (x,0), (x,(self.__height - 1)))
|
pygame.draw.line(self.__screen, (0,0,0), (x,0), (x,(self.__height - 1)))
|
||||||
for y in range(0, self.__height, self.__cellSize):
|
for y in range(0, self.__height, self.__cellSize):
|
||||||
pygame.draw.line(self.__screen, (0,0,0), (0,y), ((self.__width - 1),y))
|
pygame.draw.line(self.__screen, (0,0,0), (0,y), ((self.__width - 1),y))
|
||||||
|
"""
|
||||||
|
|
||||||
#draws object on screen
|
# draws object on screen
|
||||||
def draw(self, component):
|
def draw(self, component):
|
||||||
component.draw(self.__screen)
|
component.draw(self.__screen)
|
||||||
|
|
||||||
#updates screen
|
# updates screen
|
||||||
def udpdate(self):
|
def udpdate(self):
|
||||||
pygame.display.update()
|
pygame.display.update()
|
@ -1,79 +1,33 @@
|
|||||||
import pygame
|
|
||||||
from enum import Enum
|
|
||||||
from .Drawable import Drawable
|
|
||||||
import random
|
import random
|
||||||
|
from enum import Enum
|
||||||
|
from kelner.src.components.Drawable import Drawable
|
||||||
|
from kelner.src.managers.ImageCache import ImageCache, Images
|
||||||
|
|
||||||
|
|
||||||
|
# status of the table
|
||||||
|
class Status(Enum):
|
||||||
|
NotReady = 0
|
||||||
|
Ready = 1
|
||||||
|
Waiting = 2
|
||||||
|
Served = 3
|
||||||
|
|
||||||
|
|
||||||
class Table(Drawable):
|
class Table(Drawable):
|
||||||
|
|
||||||
def __init__(self, minX, maxX, minY, maxY, ratio):
|
def __init__(self, minX, maxX, minY, maxY, ratio, offset):
|
||||||
#call base class constructor
|
# call base class constructor
|
||||||
Drawable.__init__(self, 0, 0, minX, maxX, minY, maxY, ratio)
|
super().__init__(0, 0, minX, maxX, minY, maxY, ratio, offset)
|
||||||
self.__order = []
|
|
||||||
self.__status = Status.NotReady
|
self.__status = Status.NotReady
|
||||||
self.ilosc_klientow = random.randint(1,3)
|
self.__order = []
|
||||||
self.guest1 = self.getGuest()
|
self.__guests = self.__getRandomGuests()
|
||||||
self.guest2 = self.getGuest()
|
|
||||||
self.guest3 = self.getGuest()
|
|
||||||
self.ksiazka = self.__loadImg('./images/ksiazka.png')
|
|
||||||
self.stol = self.__loadImg('./images/stol.png')
|
|
||||||
self.check = self.__loadImg('./images/check.png')
|
|
||||||
self.plate = self.__loadImg('./images/plate.png')
|
|
||||||
self.Offset = 100
|
|
||||||
|
|
||||||
#sets table color based on it's status
|
|
||||||
def getColor(self):
|
|
||||||
color = None
|
|
||||||
if self.__status == Status.NotReady:
|
|
||||||
color = self.__loadImg('./images/stol.png')
|
|
||||||
elif self.__status == Status.Ready:
|
|
||||||
color = self.__loadImg('./images/kelner.png')
|
|
||||||
elif self.__status == Status.Waiting:
|
|
||||||
color = self.__loadImg('./images/kelner.png')
|
|
||||||
elif self.__status == Status.Served:
|
|
||||||
color = self.__loadImg('./images/kelner.png')
|
|
||||||
return color
|
|
||||||
|
|
||||||
def getGuest(self):
|
|
||||||
guest = None
|
|
||||||
i = random.randint(1,3)
|
|
||||||
if i == 1:
|
|
||||||
guest = self.__loadImg('./images/wiking_blond.png')
|
|
||||||
elif i == 2:
|
|
||||||
guest = self.__loadImg('./images/wiking_rudy.png')
|
|
||||||
elif i == 3:
|
|
||||||
guest = self.__loadImg('./images/wiking_rudy2.png')
|
|
||||||
return guest
|
|
||||||
|
|
||||||
def __loadImg(self, filePath):
|
|
||||||
return pygame.transform.scale((pygame.image.load(filePath)),(140,140))
|
|
||||||
|
|
||||||
def draw(self, screen):
|
|
||||||
screen.blit(self.stol, (self.getX() * 100-20+self.Offset, self.getY() * 100-20+self.Offset))
|
|
||||||
if self.ilosc_klientow == 1:
|
|
||||||
screen.blit(self.guest1, (self.getX() * 100 - 20+self.Offset, self.getY() * 100 - 60+self.Offset))
|
|
||||||
elif self.ilosc_klientow == 2:
|
|
||||||
screen.blit(self.guest1, (self.getX() * 100 - 62+self.Offset, self.getY() * 100 - 60+self.Offset))
|
|
||||||
screen.blit(self.guest2, (self.getX() * 100 - 20+self.Offset, self.getY() * 100 - 60+self.Offset))
|
|
||||||
elif self.ilosc_klientow == 3:
|
|
||||||
screen.blit(self.guest1, (self.getX() * 100 - 62+self.Offset, self.getY() * 100 - 60+self.Offset))
|
|
||||||
screen.blit(self.guest2, (self.getX() * 100 - 20+self.Offset, self.getY() * 100 - 60+self.Offset))
|
|
||||||
screen.blit(self.guest3, (self.getX() * 100 + 22+self.Offset, self.getY() * 100 - 60+self.Offset))
|
|
||||||
|
|
||||||
if self.__status == Status.NotReady:
|
|
||||||
screen.blit(self.ksiazka, (self.getX() * 100 - 20+self.Offset, self.getY() * 100 - 20+self.Offset))
|
|
||||||
elif self.__status == Status.Ready:
|
|
||||||
screen.blit(self.check, (self.getX() * 100 - 20+self.Offset, self.getY() * 100 - 20+self.Offset))
|
|
||||||
elif self.__status == Status.Waiting:
|
|
||||||
if self.ilosc_klientow == 1:
|
|
||||||
screen.blit(self.plate, (self.getX() * 100 - 20+self.Offset, self.getY() * 100 - 20+self.Offset))
|
|
||||||
elif self.ilosc_klientow == 2:
|
|
||||||
screen.blit(self.plate, (self.getX() * 100 - 62+self.Offset, self.getY() * 100 - 20+self.Offset))
|
|
||||||
screen.blit(self.plate, (self.getX() * 100 - 20+self.Offset, self.getY() * 100 - 20+self.Offset))
|
|
||||||
elif self.ilosc_klientow == 3:
|
|
||||||
screen.blit(self.plate, (self.getX() * 100 - 62+self.Offset, self.getY() * 100 - 20+self.Offset))
|
|
||||||
screen.blit(self.plate, (self.getX() * 100- 20+self.Offset, self.getY() * 100 - 20+self.Offset))
|
|
||||||
screen.blit(self.plate, (self.getX() * 100+ 22+self.Offset, self.getY() * 100 - 20+self.Offset))
|
|
||||||
|
|
||||||
|
def __getRandomGuests(self):
|
||||||
|
possibleGuests = [Images.Guest1, Images.Guest2, Images.Guest3]
|
||||||
|
guests = []
|
||||||
|
guestCount = random.randint(1, len(possibleGuests))
|
||||||
|
for _ in range(guestCount):
|
||||||
|
guests.insert(0, possibleGuests[random.randint(0, len(possibleGuests) - 1)])
|
||||||
|
return guests
|
||||||
|
|
||||||
def setOrder(self, order):
|
def setOrder(self, order):
|
||||||
self.__order = order
|
self.__order = order
|
||||||
@ -90,9 +44,57 @@ class Table(Drawable):
|
|||||||
def setStatus(self, status):
|
def setStatus(self, status):
|
||||||
self.__status = status
|
self.__status = status
|
||||||
|
|
||||||
#status of the table
|
def __getImage(self, imageKind):
|
||||||
class Status(Enum):
|
if imageKind in [Images.Guest1, Images.Guest2, Images.Guest3, Images.Plate]:
|
||||||
NotReady = 0
|
size = int(self.getCellSize() / 3)
|
||||||
Ready = 1
|
else:
|
||||||
Waiting = 2
|
size = int(1.4 * self.getCellSize())
|
||||||
Served = 3
|
return ImageCache.getInstance().getImage(imageKind, size, size)
|
||||||
|
|
||||||
|
# draws only table
|
||||||
|
def draw(self, screen):
|
||||||
|
xBase = self.getX() * self.getCellSize() + self.getOffset()
|
||||||
|
yBase = self.getY() * self.getCellSize() + self.getOffset()
|
||||||
|
tableXYOffset = int(0.2 * self.getCellSize())
|
||||||
|
screen.blit(self.__getImage(Images.Table), (xBase - tableXYOffset, yBase - tableXYOffset))
|
||||||
|
|
||||||
|
# draws images related to the status of a table
|
||||||
|
# the method is called in the second turn when all tables are already painted
|
||||||
|
def drawAux(self, screen):
|
||||||
|
xBase = self.getX() * self.getCellSize() + self.getOffset()
|
||||||
|
yBase = self.getY() * self.getCellSize() + self.getOffset()
|
||||||
|
|
||||||
|
guest1XOffset = 0
|
||||||
|
guest2XOffset = int((1 / 3) * self.getCellSize())
|
||||||
|
guest3XOffset = int((2 / 3) * self.getCellSize())
|
||||||
|
guest4XOffset = int((1 / 9) * self.getCellSize())
|
||||||
|
guest5XOffset = int((5 / 9) * self.getCellSize())
|
||||||
|
guestsYOffset = int(0.1 * self.getCellSize())
|
||||||
|
tableXYOffset = int(0.2 * self.getCellSize())
|
||||||
|
|
||||||
|
if len(self.__guests) == 1:
|
||||||
|
screen.blit(self.__getImage(self.__guests[0]), (xBase + guest2XOffset, yBase - guestsYOffset))
|
||||||
|
elif len(self.__guests) == 2:
|
||||||
|
screen.blit(self.__getImage(self.__guests[0]), (xBase + guest4XOffset, yBase - guestsYOffset))
|
||||||
|
screen.blit(self.__getImage(self.__guests[1]), (xBase + guest5XOffset, yBase - guestsYOffset))
|
||||||
|
elif len(self.__guests) == 3:
|
||||||
|
screen.blit(self.__getImage(self.__guests[0]), (xBase + guest1XOffset, yBase - guestsYOffset))
|
||||||
|
screen.blit(self.__getImage(self.__guests[1]), (xBase + guest2XOffset, yBase - guestsYOffset))
|
||||||
|
screen.blit(self.__getImage(self.__guests[2]), (xBase + guest3XOffset, yBase - guestsYOffset))
|
||||||
|
|
||||||
|
if self.isStatus(Status.NotReady):
|
||||||
|
screen.blit(self.__getImage(Images.Menu), (xBase - tableXYOffset, yBase - tableXYOffset))
|
||||||
|
elif self.isStatus(Status.Ready):
|
||||||
|
screen.blit(self.__getImage(Images.Check), (xBase - tableXYOffset, yBase - tableXYOffset))
|
||||||
|
elif self.isStatus(Status.Waiting):
|
||||||
|
platesYOffset = int(0.3 * self.getCellSize())
|
||||||
|
imagePlate = self.__getImage(Images.Plate)
|
||||||
|
if len(self.__guests) == 1:
|
||||||
|
screen.blit(imagePlate, (xBase + guest2XOffset, yBase + platesYOffset))
|
||||||
|
elif len(self.__guests) == 2:
|
||||||
|
screen.blit(imagePlate, (xBase + guest4XOffset, yBase + platesYOffset))
|
||||||
|
screen.blit(imagePlate, (xBase + guest5XOffset, yBase + platesYOffset))
|
||||||
|
elif len(self.__guests) == 3:
|
||||||
|
screen.blit(imagePlate, (xBase + guest1XOffset, yBase + platesYOffset))
|
||||||
|
screen.blit(imagePlate, (xBase + guest2XOffset, yBase + platesYOffset))
|
||||||
|
screen.blit(imagePlate, (xBase + guest3XOffset, yBase + platesYOffset))
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
import pygame
|
from kelner.src.components.Drawable import Drawable
|
||||||
from .Drawable import Drawable
|
from kelner.src.managers.ImageCache import ImageCache, Images
|
||||||
|
|
||||||
|
|
||||||
class Waiter(Drawable):
|
class Waiter(Drawable):
|
||||||
|
|
||||||
def __init__(self, x, y, minX, maxX, minY, maxY, ratio):
|
def __init__(self, x, y, minX, maxX, minY, maxY, ratio, offset):
|
||||||
#call base class constructor
|
# call base class constructor
|
||||||
Drawable.__init__(self, x, y, minX, maxX, minY, maxY, ratio)
|
super().__init__(x, y, minX, maxX, minY, maxY, ratio, offset)
|
||||||
self.__image = self.__loadImg('./images/kelner.png')
|
|
||||||
self.__acceptedOrders = []
|
self.__acceptedOrders = []
|
||||||
self.Offset = 100
|
self.__currentPath = []
|
||||||
|
|
||||||
|
|
||||||
def moveUp(self):
|
def moveUp(self):
|
||||||
if self.getY() > self.getMinY():
|
if self.getY() > self.getMinY():
|
||||||
@ -39,12 +38,21 @@ class Waiter(Drawable):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
#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):
|
||||||
self.__acceptedOrders += [(table, table.getOrder())]
|
self.__acceptedOrders += [(table, table.getOrder())]
|
||||||
|
|
||||||
def __loadImg(self, filePath):
|
def isPathEmpty(self):
|
||||||
return pygame.transform.scale((pygame.image.load(filePath)),(140,140))
|
return self.__currentPath == []
|
||||||
|
|
||||||
|
def setPath(self, path):
|
||||||
|
self.__currentPath = path
|
||||||
|
|
||||||
|
def popStepFromPath(self):
|
||||||
|
return self.__currentPath.pop(0)
|
||||||
|
|
||||||
def draw(self, screen):
|
def draw(self, screen):
|
||||||
screen.blit(self.__image, (self.getX()*100-20+self.Offset, self.getY()*100-20+self.Offset))
|
imageWaiter = ImageCache.getInstance().getImage(Images.Waiter, self.getCellSize(), self.getCellSize())
|
||||||
|
xBase = self.getX() * self.getCellSize() + self.getOffset()
|
||||||
|
yBase = self.getY() * self.getCellSize() + self.getOffset()
|
||||||
|
screen.blit(imageWaiter, (xBase, yBase))
|
||||||
|
@ -1,22 +1,24 @@
|
|||||||
import random
|
import random
|
||||||
from src.components.Table import Table, Status
|
from kelner.src.components.Table import Table, Status
|
||||||
from src.components.Waiter import Waiter
|
from kelner.src.components.Waiter import Waiter
|
||||||
import pygame
|
|
||||||
#drawable objects manager
|
|
||||||
|
# drawable objects manager
|
||||||
class DrawableCollection:
|
class DrawableCollection:
|
||||||
#const, minimal distance between objects
|
# const, minimal distance between objects
|
||||||
__MinDistance = 0
|
__MinDistanceX = 0
|
||||||
|
__MinDistanceY = 0
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
#collection that holds all drawable objects
|
# collection that holds all drawable objects
|
||||||
|
self.__mustRepaint = True
|
||||||
self.__drawables = []
|
self.__drawables = []
|
||||||
self.image = pygame.transform.scale((pygame.image.load('./images/Backgroud.png')),(1700,1100))
|
|
||||||
|
|
||||||
#adds drawable objects to the collection
|
# adds drawable objects to the collection
|
||||||
def add(self, drawable):
|
def add(self, drawable):
|
||||||
self.__drawables.append(drawable)
|
self.__drawables.append(drawable)
|
||||||
|
|
||||||
#generates and sets random (x, y) and cheks if it's not occupied by other object
|
# generates and sets random (x, y) and cheks if it's not occupied by other object
|
||||||
def generatePosition(self, drawable):
|
def generatePosition(self, drawable):
|
||||||
isPositionUnique = False
|
isPositionUnique = False
|
||||||
while not isPositionUnique:
|
while not isPositionUnique:
|
||||||
@ -24,20 +26,14 @@ class DrawableCollection:
|
|||||||
y = random.randint(drawable.getMinY() + 1, drawable.getMaxY() - 1)
|
y = random.randint(drawable.getMinY() + 1, drawable.getMaxY() - 1)
|
||||||
isPositionUnique = True
|
isPositionUnique = True
|
||||||
for item in self.__drawables:
|
for item in self.__drawables:
|
||||||
if abs(item.getX() - x) <= self.__MinDistance and abs(item.getY() - y) <= self.__MinDistance:
|
if abs(item.getX() - x) <= self.__MinDistanceX and abs(item.getY() - y) <= self.__MinDistanceY:
|
||||||
isPositionUnique = False
|
isPositionUnique = False
|
||||||
break
|
break
|
||||||
if isPositionUnique:
|
if isPositionUnique:
|
||||||
drawable.setX(x)
|
drawable.setX(x)
|
||||||
drawable.setY(y)
|
drawable.setY(y)
|
||||||
|
|
||||||
#draws all objects stored in collection
|
# checks if position (x,y) is not occupied by other object
|
||||||
def draw(self, screen):
|
|
||||||
screen.blit(self.image, (0, 0))
|
|
||||||
for item in self.__drawables:
|
|
||||||
item.draw(screen)
|
|
||||||
|
|
||||||
#checks if position (x,y) is not occupied by other object
|
|
||||||
def isPositionAvailable(self, x, y):
|
def isPositionAvailable(self, x, y):
|
||||||
isPositionAvailable = True
|
isPositionAvailable = True
|
||||||
for item in self.__drawables:
|
for item in self.__drawables:
|
||||||
@ -46,25 +42,25 @@ class DrawableCollection:
|
|||||||
break
|
break
|
||||||
return isPositionAvailable
|
return isPositionAvailable
|
||||||
|
|
||||||
#gets all tables by status from collection
|
# gets all tables by status from collection
|
||||||
def getTables(self, status):
|
def getTables(self, status):
|
||||||
result = []
|
result = []
|
||||||
for item in self.__drawables:
|
for item in self.__drawables:
|
||||||
if isinstance(item, Table) and item.isStatus(status):
|
if status is None or isinstance(item, Table) and item.isStatus(status):
|
||||||
result += [item]
|
result += [item]
|
||||||
return result
|
return result
|
||||||
|
|
||||||
#gets all waiters from collection
|
# gets all waiters from collection
|
||||||
def getWaites(self):
|
def getWaiters(self):
|
||||||
result = []
|
result = []
|
||||||
for item in self.__drawables:
|
for item in self.__drawables:
|
||||||
if isinstance(item, Waiter):
|
if isinstance(item, Waiter):
|
||||||
result += [item]
|
result += [item]
|
||||||
return result
|
return result
|
||||||
|
|
||||||
#waiter collects order from the nearest table
|
# waiter collects orders from all nearest tables
|
||||||
def collectOrders(self):
|
def collectOrders(self):
|
||||||
waiters = self.getWaites()
|
waiters = self.getWaiters()
|
||||||
for waiter in waiters:
|
for waiter in waiters:
|
||||||
tables = self.getTables(Status.Ready)
|
tables = self.getTables(Status.Ready)
|
||||||
for table in tables:
|
for table in tables:
|
||||||
@ -72,3 +68,30 @@ class DrawableCollection:
|
|||||||
table.setStatus(Status.Waiting)
|
table.setStatus(Status.Waiting)
|
||||||
waiter.addOrder(table)
|
waiter.addOrder(table)
|
||||||
table.delOrder()
|
table.delOrder()
|
||||||
|
|
||||||
|
# returns table: 0 - position is available, 1 - position is occupied
|
||||||
|
def getReservedPlaces(self, waiter):
|
||||||
|
cols = waiter.getMaxX() - waiter.getMinX() + 1
|
||||||
|
rows = waiter.getMaxY() - waiter.getMinY() + 1
|
||||||
|
reservedPlaces = [[0] * cols for i in range(rows)]
|
||||||
|
tables = self.getTables(None)
|
||||||
|
if tables:
|
||||||
|
for table in tables:
|
||||||
|
reservedPlaces[table.getY()][table.getX()] = 1
|
||||||
|
return reservedPlaces
|
||||||
|
|
||||||
|
# the method is called externally and forces repainting
|
||||||
|
def forceRepaint(self):
|
||||||
|
self.__mustRepaint = True
|
||||||
|
|
||||||
|
# returns boolean value: True if objects should be repainted otherwise False
|
||||||
|
def mustRepaint(self):
|
||||||
|
return self.__mustRepaint
|
||||||
|
|
||||||
|
# draws all objects stored in collection
|
||||||
|
def draw(self, screen):
|
||||||
|
for item in self.__drawables:
|
||||||
|
item.draw(screen)
|
||||||
|
for item in self.__drawables:
|
||||||
|
item.drawAux(screen)
|
||||||
|
self.__mustRepaint = False
|
||||||
|
50
kelner/src/managers/ImageCache.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import pygame
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
# images enum
|
||||||
|
class Images(Enum):
|
||||||
|
Background = 0
|
||||||
|
Waiter = 1
|
||||||
|
Table = 2
|
||||||
|
Menu = 3
|
||||||
|
Check = 4
|
||||||
|
Plate = 5
|
||||||
|
Guest1 = 6
|
||||||
|
Guest2 = 7
|
||||||
|
Guest3 = 8
|
||||||
|
|
||||||
|
|
||||||
|
class ImageCache:
|
||||||
|
__instance = None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getInstance():
|
||||||
|
if ImageCache.__instance is None:
|
||||||
|
ImageCache()
|
||||||
|
return ImageCache.__instance
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
""" Virtually private constructor. """
|
||||||
|
if ImageCache.__instance is not None:
|
||||||
|
raise Exception("This class is a singleton!")
|
||||||
|
else:
|
||||||
|
ImageCache.__instance = self
|
||||||
|
self.__images = {}
|
||||||
|
self.__paths = {Images.Background: './images/Backgroud.png',
|
||||||
|
Images.Waiter: './images/kelner.png',
|
||||||
|
Images.Table: './images/stol.png',
|
||||||
|
Images.Menu: './images/ksiazka.png',
|
||||||
|
Images.Check: './images/check.png',
|
||||||
|
Images.Plate: './images/plate.png',
|
||||||
|
Images.Guest1: './images/wiking_blond.png',
|
||||||
|
Images.Guest2: './images/wiking_rudy.png',
|
||||||
|
Images.Guest3: './images/wiking_rudy2.png'}
|
||||||
|
|
||||||
|
def getImage(self, imageKind, width, height):
|
||||||
|
key = str(imageKind.value) + ':' + str(width) + ':' + 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
|
@ -1,9 +1,10 @@
|
|||||||
import random
|
import random
|
||||||
|
|
||||||
#contains all dishes and generates random order for the table
|
|
||||||
|
# contains all dishes and generates random order for the table
|
||||||
class MenuManager:
|
class MenuManager:
|
||||||
|
|
||||||
#consts, min and max dishes oredered by the people sitting by the same table
|
# consts, min and max dishes ordered by the people sitting by the same table
|
||||||
__MinDishes = 1
|
__MinDishes = 1
|
||||||
__MaxDishes = 3
|
__MaxDishes = 3
|
||||||
|
|
||||||
@ -24,7 +25,8 @@ class MenuManager:
|
|||||||
"EMPTY PLATE",
|
"EMPTY PLATE",
|
||||||
"BEER",
|
"BEER",
|
||||||
"CAKE"]
|
"CAKE"]
|
||||||
#generator
|
|
||||||
|
# generator
|
||||||
def generateOrder(self):
|
def generateOrder(self):
|
||||||
count = random.randint(self.__MinDishes, self.__MaxDishes)
|
count = random.randint(self.__MinDishes, self.__MaxDishes)
|
||||||
order = []
|
order = []
|
||||||
|
29
kelner/src/managers/TableManager.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import threading
|
||||||
|
import time
|
||||||
|
import random
|
||||||
|
from kelner.src.components.Table import Status
|
||||||
|
|
||||||
|
|
||||||
|
# creates new thread
|
||||||
|
class TableManager (threading.Thread):
|
||||||
|
|
||||||
|
def __init__(self, drawableManager, menuManager):
|
||||||
|
super().__init__()
|
||||||
|
self.__drawableManager = drawableManager
|
||||||
|
self.__menuManager = menuManager
|
||||||
|
self.__runThread = True
|
||||||
|
|
||||||
|
# changes the status of a random table from NotReady to Ready
|
||||||
|
def run(self):
|
||||||
|
while self.__runThread:
|
||||||
|
tables = self.__drawableManager.getTables(Status.NotReady)
|
||||||
|
if tables:
|
||||||
|
tableIndex = random.randint(0, len(tables) - 1)
|
||||||
|
table = tables[tableIndex]
|
||||||
|
time.sleep(3)
|
||||||
|
table.setStatus(Status.Ready)
|
||||||
|
table.setOrder(self.__menuManager.generateOrder())
|
||||||
|
self.__drawableManager.forceRepaint()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.__runThread = False
|
@ -1,25 +0,0 @@
|
|||||||
import threading
|
|
||||||
import time
|
|
||||||
import random
|
|
||||||
from src.components.Table import Status
|
|
||||||
|
|
||||||
#creates new threads
|
|
||||||
class TaskManager (threading.Thread):
|
|
||||||
|
|
||||||
def __init__(self, drawableManager, menuManager, doRepaintObject):
|
|
||||||
threading.Thread.__init__(self)
|
|
||||||
self.__drawableManager = drawableManager
|
|
||||||
self.__menuManager = menuManager
|
|
||||||
self.__doRepaintObject = doRepaintObject
|
|
||||||
|
|
||||||
#changes the status of a random table from NotReady to Ready
|
|
||||||
def run(self):
|
|
||||||
while True:
|
|
||||||
time.sleep(3)
|
|
||||||
tables = self.__drawableManager.getTables(Status.NotReady)
|
|
||||||
if tables != []:
|
|
||||||
tableIndex = random.randint(0, len(tables) - 1)
|
|
||||||
table = tables[tableIndex]
|
|
||||||
table.setStatus(Status.Ready)
|
|
||||||
table.setOrder(self.__menuManager.generateOrder())
|
|
||||||
self.__doRepaintObject[0] = True
|
|
57
kelner/src/managers/WaiterManager.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import threading
|
||||||
|
import time
|
||||||
|
import sys
|
||||||
|
from kelner.src.components.Table import Status
|
||||||
|
from kelner.src.algorithms.AStar.Finder import Finder
|
||||||
|
|
||||||
|
|
||||||
|
# creates new thread
|
||||||
|
class WaiterManager (threading.Thread):
|
||||||
|
|
||||||
|
def __init__(self, drawableManager):
|
||||||
|
super().__init__()
|
||||||
|
self.__drawableManager = drawableManager
|
||||||
|
self.__runThread = True
|
||||||
|
|
||||||
|
def __getNearestTargetPath(self, waiter):
|
||||||
|
distance = sys.maxsize
|
||||||
|
nearestTargetPath = None
|
||||||
|
tables = self.__drawableManager.getTables(Status.Ready)
|
||||||
|
if tables:
|
||||||
|
reservedPlaces = self.__drawableManager.getReservedPlaces(waiter)
|
||||||
|
finder = Finder(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 = finder.getPath(origin, target, True)
|
||||||
|
if path:
|
||||||
|
result = len(path)
|
||||||
|
if result < distance:
|
||||||
|
distance = result
|
||||||
|
nearestTargetPath = path
|
||||||
|
return nearestTargetPath
|
||||||
|
|
||||||
|
# changes the status of a random table from NotReady to Ready
|
||||||
|
def run(self):
|
||||||
|
while self.__runThread:
|
||||||
|
waiters = self.__drawableManager.getWaiters()
|
||||||
|
if waiters:
|
||||||
|
for waiter in waiters:
|
||||||
|
path = self.__getNearestTargetPath(waiter)
|
||||||
|
if path is not None:
|
||||||
|
waiter.setPath(path)
|
||||||
|
if not waiter.isPathEmpty():
|
||||||
|
step = waiter.popStepFromPath()
|
||||||
|
time.sleep(0.4)
|
||||||
|
waiter.setX(step[0])
|
||||||
|
waiter.setY(step[1])
|
||||||
|
self.__drawableManager.forceRepaint()
|
||||||
|
if waiter.isPathEmpty():
|
||||||
|
time.sleep(2)
|
||||||
|
self.__drawableManager.collectOrders()
|
||||||
|
self.__drawableManager.forceRepaint()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.__runThread = False
|