refactoring, perfomance optimizations, bug fixing

This commit is contained in:
Vadzim Valchkovich 2023-06-07 12:43:21 +02:00
parent b26f7b244e
commit ac1659d484
20 changed files with 240 additions and 103 deletions

View File

@ -1,18 +1,22 @@
import os import os
import random import random
from pathlib import Path import logging
import numpy as np import numpy as np
import tensorflow as tf import tensorflow as tf
from tensorflow import keras from tensorflow import keras
from termcolor import colored
class Predictor: class Predictor:
def __init__(self): def __init__(self):
# Turn off interactive logging
tf.get_logger().setLevel(logging.ERROR)
# Load the trained model # Load the trained model
self.model = keras.models.load_model('Network/trained_model.h5') self.model = keras.models.load_model('Network/trained_model.h5')
# Load the class names # Load the class names
self.class_names = ['table', 'done', 'order'] self.class_names = ['table', 'table', 'order']
# Path to the folder containing test images # Path to the folder containing test images
self.test_images_folder = 'Network/Testing/' self.test_images_folder = 'Network/Testing/'
@ -29,11 +33,11 @@ class Predictor:
test_image = np.reshape(test_image, (1, 100, 100, 3)) test_image = np.reshape(test_image, (1, 100, 100, 3))
# Make predictions # Make predictions
predictions = self.model.predict(test_image) predictions = self.model.predict(test_image, verbose=None)
predicted_class_index = np.argmax(predictions[0]) predicted_class_index = np.argmax(predictions[0])
predicted_class = self.class_names[predicted_class_index] predicted_class = self.class_names[predicted_class_index]
print(predicted_class) print(colored("Predicted class: ", "yellow")+f"{predicted_class}")
return predicted_class return predicted_class
def random_path_img(self) -> str: def random_path_img(self) -> str:

View File

@ -1,20 +1,28 @@
import random import random
from termcolor import colored
from src.Engine import Engine from src.Engine import Engine
from src.obj.Waiter import Waiter from src.obj.Waiter import Waiter
from src.obj.Block import Block from src.obj.Block import Block
from src.obj.Kitchen import Kitchen from src.obj.Kitchen import Kitchen
from src.obj.Table import Table from src.obj.Table import Table
from src.UserController import UserController from src.controller.UserController import UserController
from src.StateController import StateController from src.controller.StateController import StateController
from src.controller.ImageController import ImageController
from Network.Predictor import Predictor
print(colored("Initialization...", "green"))
SCREEN_SIZE = [800, 800] SCREEN_SIZE = [800, 800]
SQUARE_SIZE = 40 SQUARE_SIZE = 80
SLEEP_DURATION = 0.125
waiter = Waiter([0, 0], 0, SQUARE_SIZE, SCREEN_SIZE) store = ImageController(SQUARE_SIZE)
kitchen = Kitchen([0, 0], 0, SQUARE_SIZE, SCREEN_SIZE)
waiter = Waiter([0, 0], 0, SQUARE_SIZE, SCREEN_SIZE, store)
kitchen = Kitchen([0, 0], 0, SQUARE_SIZE, SCREEN_SIZE, store)
objects = [] objects = []
for i in range(150): for i in range(25):
pos = [0, 0] pos = [0, 0]
@ -23,15 +31,19 @@ for i in range(150):
random.randint(1, SCREEN_SIZE[0]/SQUARE_SIZE - 1)] random.randint(1, SCREEN_SIZE[0]/SQUARE_SIZE - 1)]
if (random.randint(0, 1)): if (random.randint(0, 1)):
objects.append(Block(pos, 0, SQUARE_SIZE, SCREEN_SIZE)) objects.append(Block(pos, 0, SQUARE_SIZE, SCREEN_SIZE, store))
else: else:
objects.append(Table(pos, 0, SQUARE_SIZE, SCREEN_SIZE)) objects.append(Table(pos, 0, SQUARE_SIZE, SCREEN_SIZE, store))
user = UserController(waiter) user = UserController(waiter)
state = StateController(waiter) state = StateController(waiter)
engine = Engine(SCREEN_SIZE, SQUARE_SIZE, kitchen, user, state) predictor = Predictor()
engine = Engine(SCREEN_SIZE, SQUARE_SIZE, kitchen,
user, state, predictor, SLEEP_DURATION)
for o in objects: for o in objects:
engine.subscribe(o) engine.subscribe(o)
print(colored("Starting model...", "green"))
engine.loop() engine.loop()

View File

@ -1,26 +1,31 @@
import time import time
import pygame import pygame
from .obj.Goal import Goal from src.obj.Goal import Goal
from .obj.Object import Object from src.obj.Object import Object
from .obj.Waiter import Waiter from src.obj.Waiter import Waiter
from .obj.Kitchen import Kitchen from src.obj.Kitchen import Kitchen
from .UserController import UserController from src.controller.UserController import UserController
from .StateController import StateController from src.controller.StateController import StateController
from .decisionTree.TreeConcept import TreeEngine from src.decisionTree.TreeConcept import TreeEngine
from Network.Predictor import Predictor
from queue import PriorityQueue from queue import PriorityQueue
from termcolor import colored
from src.obj.PriorityItem import PriorityItem
class Engine: class Engine:
def __init__(self, screen_size, square_size, kitchen: Kitchen, user: UserController, state: StateController): def __init__(self, screen_size, square_size, kitchen: Kitchen, user: UserController, state: StateController, predictor: Predictor, sleep_duration):
pygame.display.set_caption('Waiter Agent') pygame.display.set_caption('Waiter Agent')
self.action_clock = 0 self.action_clock = 0
self.sleep_duration = sleep_duration
self.tree = TreeEngine() self.tree = TreeEngine()
self.kitchen: Kitchen = kitchen self.kitchen: Kitchen = kitchen
self.user: Waiter = user self.user: Waiter = user
self.state: StateController = state self.state: StateController = state
self.predictor: Predictor = predictor
self.screen_size: list[int] = screen_size self.screen_size: list[int] = screen_size
self.screen = pygame.display.set_mode(self.screen_size) self.screen = pygame.display.set_mode(self.screen_size)
@ -63,7 +68,9 @@ class Engine:
def action(self): def action(self):
if not self.state.path: if not self.state.path:
if self.goals: if self.goals:
self.state.graphsearch(self) if not self.state.graphsearch(self) and self.goals:
self.objects.remove(self.goals.pop().parent)
self.user.handler(self) self.user.handler(self)
self.predict() self.predict()
else: else:
@ -72,25 +79,31 @@ class Engine:
state = self.user.obj.changeState(self.state.path.pop()) state = self.user.obj.changeState(self.state.path.pop())
self.clock_increment(state.cost) self.clock_increment(state.cost)
print("Action:\t{0}\tCost:\t{1}\tCost so far: {2}\tBattery: {3}".format( # '''
state.agent_role, print(colored("Action:\t", "blue")+f"{state.agent_role}", end='\t')
state.cost, print(colored("Cost:\t", "blue")+f"{state.cost}", end='\t')
state.cost_so_far, print(colored("Cost so far: ", "blue") +
self.user.obj.battery) f"{state.cost_so_far}", end='\t')
) print(colored("Battery: ", "blue") +
f"{self.user.obj.battery}", end='\t')
print(colored("Basket capacity: ", "blue") +
f"{self.user.obj.basket_capacity}", end='\t')
print(colored("Memory capacity: ", "blue") +
f"{self.user.obj.memory_capacity}")
# '''
# waiter interaction # waiter interaction
for o in self.objects: for o in self.objects:
if self.user.obj.chechNeighbor(o): if self.user.obj.chechNeighbor(o):
o.updateState(self.action_clock) o.updateState(self.action_clock, self.predictor)
if o.compare_pos(self.user.obj.position): if o.compare_pos(self.user.obj.position):
o.action(self.user.obj, self.action_clock) o.action(self.user.obj, self.action_clock)
if self.kitchen.compare_pos(self.user.obj.position): if self.kitchen.compare_pos(self.user.obj.position):
self.kitchen.action(self.user.obj, self.action_clock) self.kitchen.action(self.user.obj, self.action_clock)
time.sleep(0.5) time.sleep(self.sleep_duration)
def clock_increment(self, action_time): def clock_increment(self, action_time):
self.action_clock += action_time self.action_clock += action_time
@ -119,8 +132,8 @@ class Engine:
pygame.display.flip() pygame.display.flip()
def appendGoalPosition(self, position): def appendGoal(self, parent):
self.goals.append(Goal(position, self.square_size, self.screen_size)) self.goals.append(Goal(parent))
def predict(self): def predict(self):
@ -170,16 +183,19 @@ class Engine:
# empty | new order | waiting for dish | have a dish | # empty | new order | waiting for dish | have a dish |
# is actual # is actual
1 if o.isActual() else 0, 1 if o.isActual(self.action_clock) else 0,
# yes | no | # yes | no |
] ]
p = self.tree.make_predict(dataset) p = self.tree.make_predict(dataset)
goal_queue.put((p, o.position)) goal_queue.put(PriorityItem(o, p[0]))
self.goals.clear()
if goal_queue.queue: if goal_queue.queue:
priority, goal = goal_queue.queue[0] item: PriorityItem = goal_queue.get()
if priority == 2: if item.priority == 2:
self.appendGoalPosition(self.kitchen.position) self.appendGoal(self.kitchen)
if self.kitchen.compare_pos(self.user.obj.position):
self.clock_increment(100)
else: else:
self.appendGoalPosition(goal) self.appendGoal(item.obj)

View File

@ -0,0 +1,20 @@
import os
import pygame
class ImageController():
def __init__(self, square_size):
self.images = {}
for role in os.listdir('src/img/'):
image = pygame.image.load('src/img/{0}'.format(role))
image = pygame.transform.scale(
image,
(square_size, square_size)
)
self.images[role.split('.')[0]] = image
def getRoleImage(self, role):
return self.images[role]

View File

@ -1,11 +1,12 @@
from .obj.TemporaryState import TemporaryState from src.obj.TemporaryState import TemporaryState
from queue import PriorityQueue from queue import PriorityQueue
from termcolor import colored
class StateController: class StateController:
def __init__(self, istate): def __init__(self, istate: TemporaryState):
self.path = [] self.path: list[TemporaryState] = []
self.explored = [] self.explored: list[TemporaryState] = []
self.fringe = PriorityQueue() self.fringe = PriorityQueue()
self.istate = istate self.istate = istate
self.goal = istate.position self.goal = istate.position
@ -23,14 +24,14 @@ class StateController:
self.path.append(self.path[-1].parent) self.path.append(self.path[-1].parent)
total_cost += self.path[-1].cost total_cost += self.path[-1].cost
print("Total path cost:\t{0}".format(total_cost)) print(colored(f"Total path cost: ", "green")+f"{total_cost}")
return self.path return self.path
def graphsearch(self, engine): # A* def graphsearch(self, engine): # A*
print("Search path")
self.goal = list(engine.goals[-1].position) self.goal = list(engine.goals[-1].position)
print(colored(f"Search path to ", "yellow")+f"{self.goal}")
self.reset() self.reset()
start = TemporaryState(self.istate, 0) start = TemporaryState(self.istate, 0)
@ -49,16 +50,13 @@ class StateController:
engine.redraw() engine.redraw()
self.reset() self.reset()
for o in engine.objects:
o.compare_pos(engine.goals[-1].position)
o.agent_role = "block"
engine.goals.pop()
print("Not found") print(colored("Not found", "red"))
return False return False
def succ(self, state, engine): def succ(self, state: TemporaryState, engine):
if state.collide_test(): if state.collide_test():
return return
elif any(e.compare(state) for e in self.explored): elif any(e.compare(state) for e in self.explored):
@ -74,9 +72,7 @@ class StateController:
state.cost_so_far = self.explored[-1].cost_so_far + state.cost state.cost_so_far = self.explored[-1].cost_so_far + state.cost
in_explored = any([state.compare(s) for s in self.explored] in_explored = any([state.compare(s) for s in self.explored])
)
in_frige = any([state.compare(f) for f in self.fringe.queue]) in_frige = any([state.compare(f) for f in self.fringe.queue])
if not in_explored and not in_frige: if not in_explored and not in_frige:

View File

@ -9,7 +9,7 @@ def convertDataset():
4: ["no", "yes"], 4: ["no", "yes"],
5: ["no", "yes"], 5: ["no", "yes"],
6: ["no", "yes"], 6: ["no", "yes"],
7: ["empty", "new order", "waiting for dish", "have a dish"], 7: ["empty", "new order", "waiting for cooking", "waiting for the dish"],
8: ["no", "yes"], 8: ["no", "yes"],
9: ["high priority", "low priority", "return to kitchen"] 9: ["high priority", "low priority", "return to kitchen"]
} }

View File

@ -6,7 +6,8 @@ def generateRawDataset():
battery_values = ['high', 'low'] battery_values = ['high', 'low']
distance_values = ['far', 'close'] distance_values = ['far', 'close']
mood_values = ['undefined', 'good', 'bad'] mood_values = ['undefined', 'good', 'bad']
status_values = ['empty', 'new order', 'waiting for dish', 'have a dish'] status_values = ["empty", "new order",
"waiting for cooking", "waiting for the dish"]
other = ['no', 'yes'] other = ['no', 'yes']
training_data = [] training_data = []
@ -97,9 +98,9 @@ def getPriority(dataset) -> str:
return PRIORITY['kitchen'] return PRIORITY['kitchen']
elif IS_ACTUAL == "no": elif IS_ACTUAL == "no":
return PRIORITY['high'] return PRIORITY['high']
elif STATUS_OF_TABLE == "empty" or STATUS_OF_TABLE == "have a dish": elif STATUS_OF_TABLE == "empty" or STATUS_OF_TABLE == "waiting for cooking":
return PRIORITY['kitchen'] return PRIORITY['kitchen']
elif STATUS_OF_TABLE == "new order": elif STATUS_OF_TABLE == "new order" or STATUS_OF_TABLE == "waiting for the dish":
return mood_and_distance() return mood_and_distance()
elif BASKET_IS_EMPTY == "yes": elif BASKET_IS_EMPTY == "yes":
return PRIORITY['kitchen'] return PRIORITY['kitchen']

BIN
src/img/dish_cooking.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

BIN
src/img/dish_done.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
src/img/unknown.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

View File

@ -2,8 +2,8 @@ from src.obj.Object import Object
class Block(Object): class Block(Object):
def __init__(self, position, orientation, square_size, screen_size): def __init__(self, position, orientation, square_size, screen_size, store):
super().__init__("block", position, orientation, square_size, screen_size) super().__init__("block", position, orientation, square_size, screen_size, store)
def collide_test(self, waiter: Object) -> bool: def collide_test(self, waiter: Object) -> bool:
return waiter.position == self.position return waiter.position == self.position

View File

@ -2,8 +2,15 @@ from src.obj.Object import Object
class Goal(Object): class Goal(Object):
def __init__(self, position, square_size, screen_size): def __init__(self, parent: Object):
super().__init__("goal", position, 0, square_size, screen_size) super().__init__("goal", parent.position, 0,
parent.square_size, parent.screen_size, parent.store)
self.parent = parent
if parent.agent_role != 'kitchen':
print("waiting_time:", parent.waiting_time, end='\t')
print("cooking_time:", parent.cooking_time, end='\t')
print("is_actual:", parent.is_actual)
def collide_test(self, waiter: Object) -> bool: def collide_test(self, waiter: Object) -> bool:
return waiter.position == self.position return waiter.position == self.position

View File

@ -2,9 +2,30 @@ from src.obj.Object import Object
class Kitchen(Object): class Kitchen(Object):
def __init__(self, position, orientation, square_size, screen_size): def __init__(self, position, orientation, square_size, screen_size, store):
super().__init__("kitchen", position, orientation, square_size, screen_size) super().__init__("kitchen", position, orientation, square_size, screen_size, store)
self.cooking = []
self.done = []
def action(self, waiter, current_time): def action(self, waiter, current_time):
waiter.combine_orders(current_time) self.cook_dishes(current_time)
waiter.combine_orders(current_time, self)
waiter.recharge() waiter.recharge()
def cook_dishes(self, current_time):
for table in self.cooking:
if table.dish_is_ready(current_time):
self.done.append(table)
table.setMark("dish_done")
for table in self.done:
if table in self.cooking:
self.cooking.remove(table)
def take_order(self, order):
order.start_cooking()
order.setMark("dish_cooking")
self.cooking.append(order)
def has_dishes(self) -> bool:
return len(self.done) > 0

13
src/obj/Mark.py Normal file
View File

@ -0,0 +1,13 @@
from src.obj.Object import Object
class Mark(Object):
def __init__(self, parent, mark_type):
super().__init__(
mark_type,
parent.position,
parent.orientation,
parent.square_size,
parent.screen_size,
parent.store
)

View File

@ -1,19 +1,17 @@
import pygame import pygame
from src.controller.ImageController import ImageController
class Object: class Object:
def __init__(self, agent_role, position, orientation, square_size, screen_size): def __init__(self, agent_role, position, orientation, square_size, screen_size, store: ImageController):
self.agent_role = agent_role self.agent_role = agent_role
self.position = position self.position = position
self.orientation = orientation % 4 self.orientation = orientation % 4
self.square_size = square_size self.square_size = square_size
self.screen_size = screen_size self.screen_size = screen_size
self.square_count = screen_size[0] // square_size self.square_count = screen_size[0] // square_size
self.image = store.getRoleImage(agent_role)
self.image = pygame.image.load( self.store = store
'src/img/{0}.png'.format(self.agent_role))
self.image = pygame.transform.scale(
self.image, (self.square_size, self.square_size))
self.rect = pygame.Rect(position[0] * square_size, self.rect = pygame.Rect(position[0] * square_size,
position[1] * square_size, position[1] * square_size,
@ -21,9 +19,7 @@ class Object:
def change_role(self, new_role): def change_role(self, new_role):
self.agent_role = new_role self.agent_role = new_role
self.image = pygame.image.load('src/img/{0}.png'.format(new_role)) self.image = self.store.getRoleImage(new_role)
self.image = pygame.transform.scale(
self.image, (self.square_size, self.square_size))
def get_angle(self): def get_angle(self):
''' '''
@ -58,5 +54,5 @@ class Object:
def action(self, obj): def action(self, obj):
pass pass
def updateState(self, current_time): def updateState(self, current_time, predictor):
pass pass

19
src/obj/PriorityItem.py Normal file
View File

@ -0,0 +1,19 @@
class PriorityItem():
def __init__(self, obj, priority):
self.obj = obj
self.priority = priority
def __eq__(self, __value) -> bool:
return self.priority == __value.priority
def __lt__(self, __value) -> bool:
return self.priority < __value.priority
def __le__(self, __value) -> bool:
return self.priority <= __value.priority
def __gt__(self, __value) -> bool:
return self.priority > __value.priority
def __ge__(self, __value) -> bool:
return self.priority >= __value.priority

View File

@ -1,31 +1,45 @@
import random import random
from src.obj.Object import Object from src.obj.Object import Object
from Network.Predictor import Predictor from src.obj.Mark import Mark
class Table(Object): class Table(Object):
def __init__(self, position, orientation, square_size, screen_size): def __init__(self, position, orientation, square_size, screen_size, store):
super().__init__("table", position, orientation, square_size, screen_size) super().__init__("table", position, orientation, square_size, screen_size, store)
self.waiting_time = 0 self.waiting_time = 0
self.cooking_time = 0 self.cooking_time = 0
self.is_actual = False self.is_actual = False
self.p = Predictor() self.mark = Mark(self, "unknown")
def isActual(self, current_time):
if self.is_actual and self.agent_role == "table":
if current_time - self.waiting_time > 1000:
self.reset(current_time)
def isActual(self):
return self.is_actual return self.is_actual
def updateState(self, current_time): def setMark(self, mark_type):
self.mark = Mark(self, mark_type)
def unsetMark(self):
self.mark = None
def blit(self, screen):
super().blit(screen)
if self.mark:
self.mark.blit(screen)
def updateState(self, current_time, predictor):
if self.is_actual: if self.is_actual:
return return
self.unsetMark()
self.is_actual = True self.is_actual = True
# here must be neural network choise # here must be neural network choise
new_role = self.p.predict(self.p.random_path_img()) new_role = predictor.predict(predictor.random_path_img())
self.change_role(new_role, current_time) self.change_role(new_role, current_time)
if self.agent_role == "table": if self.agent_role == "wait":
return self.cooking_time = random.randint(0, 1000)
elif self.agent_role == "wait":
self.cooking_time = random.randint(0, 300)
def dish_is_ready(self, current_time): def dish_is_ready(self, current_time):
return current_time - self.waiting_time > self.cooking_time return current_time - self.waiting_time > self.cooking_time
@ -46,6 +60,7 @@ class Table(Object):
def reset(self, current_time): def reset(self, current_time):
self.is_actual = False self.is_actual = False
self.mark = Mark(self, "unknown")
self.change_role("table", current_time) self.change_role("table", current_time)
def set_order(self, current_time): def set_order(self, current_time):
@ -56,6 +71,10 @@ class Table(Object):
if self.agent_role == "order": if self.agent_role == "order":
self.change_role("wait", current_time) self.change_role("wait", current_time)
def start_cooking(self):
if self.agent_role == "wait":
self.cooking_time = random.randint(0, 1000)
def set_done(self, current_time): def set_done(self, current_time):
if self.agent_role == "wait": if self.agent_role == "wait":
self.change_role("done", current_time) self.change_role("done", current_time)
@ -72,12 +91,12 @@ class Table(Object):
def get_customers_count(self) -> int: def get_customers_count(self) -> int:
return self.customers return self.customers
def get_mood(self, current_time) -> int: # перапісаць def get_mood(self, current_time) -> int:
if self.agent_role == "table": if self.agent_role == "table":
return 2 # undefined return 2 # undefined
diff = current_time - self.waiting_time diff = current_time - self.waiting_time
return 0 if diff >= 300 else 1 # 0 - bad; 1 - good return 0 if diff >= 1000 else 1 # 0 - bad; 1 - good
def action(self, waiter, current_time): def action(self, waiter, current_time):
if self.is_order(): if self.is_order():

View File

@ -8,7 +8,11 @@ class TemporaryState(Waiter):
copy.copy(parent.orientation), copy.copy(parent.orientation),
copy.copy(parent.square_size), copy.copy(parent.square_size),
copy.copy(parent.screen_size), copy.copy(parent.screen_size),
copy.copy(parent.basket)) parent.store,
copy.copy(parent.basket),
copy.copy(parent.memory),
copy.copy(parent.battery)
)
self.agent_role = action self.agent_role = action
self.parent = parent self.parent = parent
self.cost = cost self.cost = cost

View File

@ -3,11 +3,11 @@ from src.obj.Object import Object
class Waiter(Object): class Waiter(Object):
def __init__(self, position, orientation, square_size, screen_size, basket=[], memory=[], battery=300): def __init__(self, position, orientation, square_size, screen_size, store, basket=[], memory=[], battery=300):
super().__init__("waiter", position, orientation, square_size, screen_size) super().__init__("waiter", position, orientation, square_size, screen_size, store)
self.battery = battery self.battery = battery
self.basket_size = 4 self.basket_capacity = 4
self.memory_size = 4 self.memory_capacity = 4
self.basket = basket self.basket = basket
self.memory = memory self.memory = memory
self.prev_position = copy.deepcopy(self.position) self.prev_position = copy.deepcopy(self.position)
@ -17,6 +17,7 @@ class Waiter(Object):
self.position = copy.deepcopy(state.position) self.position = copy.deepcopy(state.position)
self.orientation = copy.copy(state.orientation) self.orientation = copy.copy(state.orientation)
self.basket = copy.copy(state.basket) self.basket = copy.copy(state.basket)
self.memory = copy.copy(state.memory)
self.battery -= state.cost self.battery -= state.cost
return state return state
@ -24,24 +25,32 @@ class Waiter(Object):
return table in self.basket return table in self.basket
def basket_is_full(self) -> bool: def basket_is_full(self) -> bool:
return self.basket_size == 0 return self.basket_capacity == 0
def basket_is_empty(self) -> bool: def basket_is_empty(self) -> bool:
return self.basket_size == 4 return self.basket_capacity == 4
def combine_orders(self, current_time): def combine_orders(self, current_time, kitchen):
while not self.basket_is_full() and not self.memory_is_empty():
dish = self.memory.pop() # take orders
for table in self.memory:
kitchen.take_order(table)
self.memory = []
self.memory_capacity = 4
# take dishes
while not self.basket_is_full() and kitchen.has_dishes():
dish = kitchen.done.pop()
dish.set_done(current_time) dish.set_done(current_time)
self.basket.append(dish) self.basket.append(dish)
self.basket_size -= 1 self.basket_capacity -= 1
self.memory_size += 1
def deliver_dish(self, table, current_time): def deliver_dish(self, table, current_time):
if table in self.basket: if table in self.basket:
table.reset(current_time) table.reset(current_time)
self.basket.remove(table) self.basket.remove(table)
self.basket_size += 1 self.basket_capacity += 1
def order_in_memory(self, table) -> bool: def order_in_memory(self, table) -> bool:
return table in self.memory return table in self.memory
@ -50,7 +59,7 @@ class Waiter(Object):
return not self.memory return not self.memory
def memory_is_full(self) -> bool: def memory_is_full(self) -> bool:
return self.memory_size == 0 return self.memory_capacity == 0
def collect_order(self, table, current_time): def collect_order(self, table, current_time):
if self.memory_is_full(): if self.memory_is_full():
@ -58,7 +67,7 @@ class Waiter(Object):
if table.agent_role == "order": if table.agent_role == "order":
table.set_wait(current_time) table.set_wait(current_time)
self.memory.append(table) self.memory.append(table)
self.memory_size -= 1 self.memory_capacity -= 1
def battery_status(self) -> int: def battery_status(self) -> int:
return 1 if self.battery >= 100 else 0 return 1 if self.battery >= 100 else 0