import pygame import numpy as np import math ######################## ### WS ### ######################## # For CNN: import keras from keras.preprocessing import image from keras.models import Sequential from keras.layers import Convolution2D from keras.layers import MaxPooling2D from keras.layers import Flatten from keras.layers import Dense #initializing: classifier = Sequential() #Convolution: classifier.add(Convolution2D(32, (3, 3), input_shape =(256, 256, 3), activation = "relu")) #Pooling: classifier.add(MaxPooling2D(pool_size = (2,2))) # Adding a second convolutional layer classifier.add(Convolution2D(32, 3, 3, activation = 'relu')) classifier.add(MaxPooling2D(pool_size = (2, 2))) #Flattening: classifier.add(Flatten()) #Fully connected layers:: classifier.add(Dense(units = 128, activation = "relu")) classifier.add(Dense(units = 3, activation = "softmax")) # loading weigjts: classifier.load_weights('s444523/best_model_weights2.h5') #Making CNN: classifier.compile(optimizer = "adam", loss = "categorical_crossentropy", metrics = ["accuracy"]) ######################## ### WS ### ######################## # Colors: # Define some colors BLACK = (0, 0, 0) WHITE = (255, 255, 255) GREEN = (0, 255, 0) RED = (255, 0, 0) BLUE = (0, 0, 240) #Width and Height of each square: WIDTH = 20 HEIGHT = 20 #Margin: MARGIN = 5 grid = [[0 for x in range(16)] for y in range(16)] def change_value(i, j, width, n): for r in range (i, i+width): for c in range (j, j+width): grid[r][c] = n # the class "Table" class Table: def __init__(self, coordinate_i, coordinate_j, state = 0): self.coordinate_i = coordinate_i self.coordinate_j = coordinate_j self.state = state change_value(coordinate_i, coordinate_j, 2, 1) def get_destination_coor(self): return [self.coordinate_i, self.coordinate_j-1] ######################## ### WS ### ######################## # The finction "state of meal" chooses a photo of a plate at the given table. def state_of_meal(self): ## !!!!!!### num = np.random.randint(67, 100) ## !!!!!!### if num<=67: img_name = 'plates/{}.png'.format(num) else: img_name = 'plates/{}.jpg'.format(num) return img_name # The function "change state" changes the value of the state variable. # It informs, whether the client are waiting for the waiter to make an order # (0 - empty plates) are eating (2 - full plates) or are waiting for the # waiter to get a recipt (1 - dirty plates) def change_state(self, st): self.state = st ######################## ### /WS ### ######################## class Kitchen: def __init__(self, coordinate_i, coordinate_j): self.coordinate_i = coordinate_i self.coordinate_j = coordinate_j change_value(coordinate_i, coordinate_j, 3, 2) class Agent: def __init__(self,orig_coordinate_i, orig_coordinate_j): self.orig_coordinate_i = orig_coordinate_i self.orig_coordinate_j = orig_coordinate_j self.state = np.array([1,2]) change_value(orig_coordinate_j, orig_coordinate_j, 1, 3) self.state_update(orig_coordinate_i, orig_coordinate_j) self.previous_grid = np.array([-1, -1]) def state_update(self, c1, c2): self.state[0] = c1 self.state[1] = c2 def leave(self): change_value(self.state[0], self.state[1], 1, 0) def previous_grid_update(self): self.previous_grid[0] = self.state[0] self.previous_grid[1] = self.state[1] def move_to(self, nextPos): self.previous_grid_update() self.leave() self.state_update(x + nextPos[0], y + nextPos[1]) change_value(self.state[0], self.state[1], 1, 3) ######################## ### WS ### ######################## #The function "define_table" serches for the apropriate table in the # table_dict (to enable the usage of class attributes and methods) def define_table(self, t_num): t_num = 'table{}'.format(t_num) t_num = table_dict[t_num] return t_num # The function "check_plates" uses the pretrained CNN model to classify # the plate on the table as empty(0), full(2) or dirty(1) def check_plates(self, table_number): table = self.define_table(table_number) plate = table.state_of_meal() plate= image.load_img(plate, target_size = (256, 256)) plate = image.img_to_array(plate) plate = np.expand_dims(plate, axis = 0) result = classifier.predict(plate)[0] print (result) if result[1] == 1: result[1] = 0 x = int(input("Excuse me, have You done eating? 1=Yes, 2 = No \n")) result[x] = 1 for i, x in enumerate(result): if result[i] == 1: table.change_state(i) ######################## ### /WS ### ######################## # check the next grid is not the previous grid to prevent the loop def next_is_previous(self, x, y): return np.array_equal(self.previous_grid, np.array([x, y])) def check_done(): for event in pygame.event.get(): # Checking for the event if event.type == pygame.QUIT: # If the program is closed: return True # To exit the loop def draw_grid(): for row in range(16): # Drawing the grid for column in range(16): color = WHITE if grid[row][column] == 1: color = GREEN if grid[row][column] == 2: color = RED if grid[row][column] == 3: color = BLUE pygame.draw.rect(screen, color, [(MARGIN + WIDTH) * column + MARGIN, (MARGIN + HEIGHT) * row + MARGIN, WIDTH, HEIGHT]) # calculate the distance between two points def distance(point1, point2): return math.sqrt((point2[0] - point1[0])**2 + (point2[1] - point1[1])**2) ## default positions of the agent: x = 12 y = 12 agent = Agent(x, y) table1 = Table(2, 2) table2 = Table (2,7) table3 = Table(2, 12) table4 = Table(7, 2) table5 = Table(7, 7) table6 = Table(7, 12) table7 = Table(12, 2) table8 = Table(12, 7) ################### WS ##################### # I added the dict to loop through tables. table_dict = {"table1":table1, "table2":table2, "table3":table3,"table4":table4, "table5":table5,"table6":table6,"table7":table7,"table8":table8 } ################### WS ##################### #class Kitchen: kitchen = Kitchen(13, 13) # destination array destination_tables = [] pygame.init() WINDOW_SIZE = [405, 405] screen = pygame.display.set_mode(WINDOW_SIZE) pygame.display.set_caption("Waiter_Grid3") done = False clock = pygame.time.Clock() # -------- Main Program Loop ----------- while not done: screen.fill(BLACK) # Background color draw_grid() done = check_done() for value in table_dict.values(): destination_tables.append(value.get_destination_coor()) # We need to define the number of the table by which we are in: num_of_table = 1 while len(destination_tables) != 0: # set the first element(table) in array as currDestination currDestination = destination_tables[0] # from kitchen to table while agent.state[0] != currDestination[0] or agent.state[1] != currDestination[1]: #/////////////////////////////////////// x = agent.state[0] y = agent.state[1] # set a huge default number minDis = 9999 nextPos = [] # check whether the agent goes left if y-1 >= 0 and grid[x][y-1] != 1 and not agent.next_is_previous(x, y-1): minDis = distance([x, y-1], currDestination) nextPos = [0, -1] # means go left # check whether the agent goes right if y+1 <= 15 and grid[x][y+1] != 1 and grid[x][y+1] != 2 and not agent.next_is_previous(x, y+1): d = distance([x, y+1], currDestination) if d < minDis: minDis = d nextPos = [0, 1] # means go right # check whether the agent goes up if x-1 >= 0 and grid[x-1][y] != 1 and not agent.next_is_previous(x-1, y): d = distance([x-1, y], currDestination) if d < minDis: minDis = d nextPos = [-1, 0] # means go up # check whether the agent goes down if x+1 <= 15 and grid[x+1][y] != 1 and grid[x+1][y] != 2 and not agent.next_is_previous(x+1, y): d = distance([x+1, y], currDestination) if d < minDis: minDis = d nextPos = [1, 0] # means go down # print(agent.previous_grid) agent.move_to(nextPos) #//////////////////////////////////////////////// pygame.time.delay(100) screen.fill(BLACK) # Background color draw_grid() # Drawing the grid clock.tick(60) # Limit to 60 frames per second pygame.display.flip() # Updating the screen ######################## ### WS ### ######################## #pygame.time.delay(100) print("I'm at a table no. {}".format(num_of_table)) ## Checking at what state are the plates: agent.check_plates(num_of_table) num_of_table +=1 ######################## ### /WS ### ######################## # set the kitchen as currDestination currDestination = [13, 12] # from table to kitchen while agent.state[0] != currDestination[0] or agent.state[1] != currDestination[1]: #/////////////////////////////////////// x = agent.state[0] y = agent.state[1] # set a huge default number minDis = 9999 nextPos = [] # check whether the agent goes left if y-1 >= 0 and grid[x][y-1] != 1 and not agent.next_is_previous(x, y-1): minDis = distance([x, y-1], currDestination) nextPos = [0, -1] # means go left # check whether the agent goes right if y+1 <= 15 and grid[x][y+1] != 1 and grid[x][y+1] != 2 and not agent.next_is_previous(x, y+1): d = distance([x, y+1], currDestination) if d < minDis: minDis = d nextPos = [0, 1] # means go right # check whether the agent goes up if x-1 >= 0 and grid[x-1][y] != 1 and grid[x-1][y] != 2 and not agent.next_is_previous(x-1, y): d = distance([x-1, y], currDestination) if d < minDis: minDis = d nextPos = [-1, 0] # means go up # check whether the agent goes down if x+1 <= 15 and grid[x+1][y] != 1 and grid[x+1][y] != 2 and not agent.next_is_previous(x+1, y): d = distance([x+1, y], currDestination) if d < minDis: minDis = d nextPos = [1, 0] # means go down agent.move_to(nextPos) #//////////////////////////////////////////////// pygame.time.delay(100) screen.fill(BLACK) # Background color draw_grid() # Drawing the grid clock.tick(60) # Limit to 60 frames per second pygame.display.flip() # Updating the screen destination_tables = destination_tables[1:] # remove the first element in the list # After each fool loop, we can quit the program:. if len(destination_tables) == 0: play_again = 1 play_again = int(input("Exit? 0=No, 1=Yes \n")) if play_again: pygame.quit() pygame.quit()