import random import time import numpy as np import pygame import pytmx from queue import Queue import math import pandas as pd from sklearn.model_selection import train_test_split from sklearn.tree import DecisionTreeClassifier import json pygame.init() display = pygame.display.set_mode((640, 640)) clock = pygame.time.Clock() gameMap = pytmx.load_pygame("cafe.tmx") waiterImg = pygame.image.load("waiter.png") waiterImgD = pygame.image.load("waiterD.png") waiterImgL = pygame.image.load("waiterL.png") waiterImgR = pygame.image.load("waiterR.png") tableImg = pygame.image.load('table.png') chairImg = pygame.image.load('chair.png') clientImg = pygame.image.load('client.png') class Waiter: def __init__(self, loc): self.loc = loc def render(self, surface): surface.blit(waiterImg, (self.loc[0], self.loc[1])) def handle_events(self): key = pygame.key.get_pressed() if key[pygame.K_w] or key[pygame.K_UP]: self.loc[1] -= 32 elif key[pygame.K_s] or key[pygame.K_DOWN]: self.loc[1] += 32 elif key[pygame.K_a] or key[pygame.K_LEFT]: self.loc[0] -= 32 elif key[pygame.K_d] or key[pygame.K_RIGHT]: self.loc[0] += 32 def up(self): self.loc[1] -= 32 def down(self): self.loc[1] += 32 def left(self): self.loc[0] -= 32 def right(self): self.loc[0] += 32 class Client: def __init__(self, loc): self.loc = loc def render(self, surface): surface.blit(clientImg, (self.loc[0], self.loc[1])) def generate_client(): loc_for_client = [] for i in chairs: for j in i: loc_for_client.append(j.loc) loc = (random.randint(0, len(loc_for_client))) client_coordinates = (loc_for_client[loc]) return client_coordinates class Table: def __init__(self, loc, num): self.loc = loc self.number = num self.num_of_chairs = np.random.randint(1, 5) def render(self, surface): surface.blit(tableImg, (self.loc[0], self.loc[1])) def get_number(self): return self.number def get_number_of_chairs(self): return self.num_of_chairs def check_collision_with_table(x,y): answer = False for i in tables_coordinates: if i[0] <= x <= i[0] + 32 and i[1] <= y <= i[1] + 32: answer = True else: continue return answer class Chair: def __init__(self, loc): self.loc = loc def render(self, surface): surface.blit(chairImg, (self.loc[0], self.loc[1])) def pos_of_chair(table_cor, k): pos = ((table_cor[0], table_cor[1] - 32), (table_cor[0], table_cor[1] + 32), (table_cor[0] - 32, table_cor[1]), (table_cor[0] + 32, table_cor[1])) return pos[k] def check_collision_with_chair(x,y): answer = False for i in chairs: for j in i: if j.loc[0] <= x <= j.loc[0] + 32 and j.loc[1] <= y <= j.loc[1] + 32: answer = True else: continue return answer class Food: def __init__(self, name, pos_in_card, price, spiciness, vege, size, allergens, ingridients, drink_in): self.name = name self.pos_in_card = pos_in_card self.price = price self.spiciness = spiciness self.vege = vege self.size = size self.allergens = allergens self.ingridients = ingridients self.drink_in = drink_in def get_food(self): return self.name, self.price class Menu: def __init__(self, card={}): self.card = card def get_menu(self): return self.card def add_to_card(self, dish): self.card[str(len(self.card) + 1)] = dish class Order(Table): def __init__(self, status=False, table=0, dishes=[]): self.table = table self.dishes = dishes self.status = status def take_order(self, foods, table): self.dishes.append(foods) self.table = table.number def deliver(self): self.status = True class Graph: def __init__(self, num_of_nodes, directed=True): self.m_num_of_nodes = num_of_nodes self.m_nodes = range(self.m_num_of_nodes) self.m_directed = directed self.m_adj_list = {node: set() for node in self.m_nodes} def add_edge(self, node1, node2, weight=1): self.m_adj_list[node1].add((node2, weight)) if not self.m_directed: self.m_adj_list[node2].add((node1, weight)) def print_adj_list(self): for key in self.m_adj_list.keys(): print("node", key, ": ", self.m_adj_list[key]) def bfs(self, start_node, target_node): visited = set() queue = Queue() queue.put(start_node) visited.add(start_node) parent = dict() parent[start_node] = None path_found = False while not queue.empty(): current_node = queue.get() if current_node == target_node: path_found = True break for (next_node, weight) in self.m_adj_list[current_node]: if next_node not in visited: queue.put(next_node) parent[next_node] = current_node visited.add(next_node) path = [] if path_found: path.append(target_node) while parent[target_node] is not None: path.append(parent[target_node]) target_node = parent[target_node] path.reverse() return path def pathFromTo(start, dest): tab2 = [42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57] tab4 = [41, 58] tab3 = [] tab5 = [] for x in range(16): for num in tab4: tab5.append(num + x * 20) for x in range(16): for num in tab2: tab3.append(num + x * 20) graph = Graph(400, directed=False) for x in tab5: b = x + 1 c = x + 20 d = x - 20 graph.add_edge(x, b) graph.add_edge(x, c) graph.add_edge(x, d) for x in tab3: b = x + 1 c = x + 20 d = x - 1 e = x - 20 graph.add_edge(x, b) graph.add_edge(x, c) graph.add_edge(x, d) graph.add_edge(x, e) graph.add_edge(21, 22) graph.add_edge(21, 41) graph.add_edge(378, 358) graph.add_edge(378, 377) graph.add_edge(38, 37) graph.add_edge(38, 58) graph.add_edge(361, 362) graph.add_edge(361, 341) # graph.print_adj_list() path = [] path = graph.bfs(start, dest) return path def numToX(num): digits = [int(a) for a in str(num)] if num >= 100: if digits[1] % 2 == 0: x = digits[2] else: x = digits[2] + 10 else: if digits[0] % 2 == 0: x = digits[1] else: x = digits[1] + 10 x = x * 32 return x def numToY(num): y = (math.floor(num / 20)) * 32 return y def coordsToNum(coords): num = ((coords[1] // 32) * 20) + (coords[0] // 32) return int(num) def waiterGo(dest): print("Path: ", (pathFromTo(coordsToNum(waiter.loc), dest))) go = [] for numb in range(len(pathFromTo(coordsToNum(waiter.loc), dest)) - 1): go.append(pathFromTo(coordsToNum(waiter.loc), dest)[numb] - pathFromTo(coordsToNum(waiter.loc), dest)[numb + 1]) for x in range(len(go)): if go[x] == -20: waiter.down() display.blit(waiterImgD, (waiter.loc[0], waiter.loc[1])) # waiter.render(display) pygame.display.update() time.sleep(0.2) elif go[x] == 20: waiter.up() display.blit(waiterImg, (waiter.loc[0], waiter.loc[1])) # waiter.render(display) pygame.display.update() time.sleep(0.2) elif go[x] == 1: waiter.left() display.blit(waiterImgL, (waiter.loc[0], waiter.loc[1])) # waiter.render(display) pygame.display.update() time.sleep(0.2) elif go[x] == -1: waiter.right() display.blit(waiterImgR, (waiter.loc[0], waiter.loc[1])) # waiter.render(display) pygame.display.update() time.sleep(0.2) def mouseToNum(): x = pygame.mouse.get_pos()[0] y = pygame.mouse.get_pos()[1] cordTab = [x, y] squareNum = coordsToNum(cordTab) return squareNum class Map: def __init__(self): self.arr = np.zeros((20, 20)) self.arr[1:19, 1:19] = 1 def add_chair(self, loc): self.arr[loc[0] // 32, loc[1] // 32] = 100 def add_table(self, loc): self.arr[loc[0] // 32, loc[1] // 32] = 200 def get_arr(self): return self.arr.transpose() class Tile(): def __init__(self, parent=None, loc=None): self.parent = parent self.position = loc self.g = 0 self.h = 0 self.f = 0 def __eq__(self, other): return self.position == other.position def astar(map, start, end): start_tile = Tile(None, start) start_tile.g = start_tile.h = start_tile.f = 0 end_tile = Tile(None, end) end_tile.g = end_tile.h = end_tile.f = 0 open_list = [] closed_list = [] open_list.append(start_tile) while len(open_list) > 0: current_tile = open_list[0] current_index = 0 for index, item in enumerate(open_list): if item.f <= current_tile.f: current_tile = item current_index = index open_list.pop(current_index) closed_list.append(current_tile) if current_tile == end_tile: path = [] current = current_tile while current is not None: path.append(current.position) current = current.parent return path[::-1] children = [] for new_position in [(0, -1), (0, 1), (-1, 0), (1, 0)]: tile_position = (current_tile.position[0] + new_position[0], current_tile.position[1] + new_position[1]) if map[tile_position[0]][tile_position[1]] == 0: continue new_node = Tile(current_tile, tile_position) children.append(new_node) for child in children: skip = False for closed_child in closed_list: if child == closed_child: skip = True if skip is False: child.g = current_tile.g + map[child.position[0]][child.position[1]] child.h = np.absolute(child.position[0] - end_tile.position[0]) + np.absolute(child.position[1] - end_tile.position[1]) child.f = child.g + child.h for open_node in open_list: if child == open_node and child.g > open_node.g: continue open_list.append(child) def tell_preferences(): possibilities = [[30, 40 ,50, None], [True, False, None], [True, False, None], ["high", "low", None], ["tomato", "olives", "feta", None], ["sausage", "pineapple", "mushrooms", "shrimps", "salami", None], [True, False, None]] choices = [] for i in possibilities: choices.append(random.choice(i)) return choices def evaluate_preferences(preferences): data = [] if preferences[0] == 30: data.append(30) elif preferences[0] == 40: data.append(40) elif preferences[0] == 50: data.append(50) else: data.append(random.choice([30, 40, 50])) if preferences[1] is True: data.append(1) elif preferences[1] is False: data.append(0) else: data.append(random.choice([1, 0])) if preferences[2] is True: data.append(1) elif preferences[2] is False: data.append(0) else: data.append(random.choice([1, 0])) if preferences[3] == 'low': data.append(30) elif preferences[3] == 'high': data.append(50) else: data.append(random.choice([30, 50])) if preferences[4] == 'tomato': data.append(1) elif preferences[4] == 'olives': data.append(3) elif preferences[4] == 'feta': data.append(2) else: data.append(0) if preferences[5] == 'salami': data.append(1) elif preferences[5] == 'mushrooms': data.append(2) elif preferences[5] == 'pineapple': data.append(3) elif preferences[5] == 'shrimps': data.append(4) elif preferences[5] == 'sausage': data.append(5) else: data.append(0) if preferences[6] is True: data.append(1) elif preferences[6] is False: data.append(0) else: data.append(random.choice([1, 0])) return data def choose_pizza(prefernce): df = pd.read_excel("restaurant.xlsx") d = {'low': 30, 'high': 50} df['level of hunger'] = df['level of hunger'].map(d) d = {'none': 0, 'tomato': 1, 'feta': 2, 'olives': 3} df['allergy'] = df['allergy'].map(d) d = {'none': 0, 'salami': 1, 'mushrooms': 2, 'pineapple': 3, 'shrimps': 4, 'sausage': 5} df['favorite ingridient'] = df['favorite ingridient'].map(d) d = {'margherita': 0, 'hawajska': 1, 'funghi': 2, 'light': 3, '4 sery': 4, 'pepperoni': 5, 'salami': 6, 'wegetarianska': 7, 'barbecue': 8, 'miesna': 9, 'paprykowa': 10, 'jalapeno': 11, 'barbecue wege': 12, 'kebab': 13, 'grecka': 14, 'piekielna': 15, 'drwala': 16, 'grzybowa': 17, 'staropolska': 18, 'goralska': 19, 'prosciutto': 20, 'broccoli': 21, 'americana': 22, 'farmerska': 23, 'nachos': 24, 'texas': 25, 'kurczak': 26, 'zielona': 27, 'mix': 28} df['pizza'] = df['pizza'].map(d) features = ['budget', 'spiciness', 'vege', 'level of hunger', 'allergy', 'favorite ingridient', 'drink in'] x = df[features] y = df['pizza'] x_train, x_test, y_train, y_test = train_test_split(x, y) clf = DecisionTreeClassifier(random_state=400) clf = clf.fit(x_train, y_train) return clf.predict([prefernce]) def get_pizza(number): with open("dishes.json") as f: data = json.load(f) for i in data: if i["pos_in_card"] == int(number): food = Food(i['name'], i['pos_in_card'], i['price'], i['spiciness'], i['vege'], i['size'], i['allergens'], i['ingridients'], i['drink_in']) return food map = Map() waiter = Waiter([32, 32]) tables = [] tables_coordinates = ((32 * 3, 32 * 2), (32 * 7, 32 * 2), (32 * 12, 32 * 2), (32 * 16, 32 * 2), (32 * 3, 32 * 6), (32 * 7, 32 * 6), (32 * 12, 32 * 6), (32 * 16, 32 * 6), (32 * 3, 32 * 13), (32 * 7, 32 * 13), (32 * 12, 32 * 13), (32 * 16, 32 * 13), (32 * 3, 32 * 17), (32 * 7, 32 * 17), (32 * 12, 32 * 17), (32 * 16, 32 * 17)) chairs = [] for i in range(16): tables.append(Table(tables_coordinates[i], i)) arr = [] for j in range(0, tables[i].get_number_of_chairs()): arr.append(Chair(pos_of_chair(tables_coordinates[i], j))) map.add_chair(Chair(pos_of_chair(tables_coordinates[i], j)).loc) chairs.append(arr) for table in tables: map.add_table(table.loc) client = Client(generate_client()) def main(): direction = [] while True: clock.tick(10) keys = pygame.key.get_pressed() for event in pygame.event.get(): if event.type == pygame.QUIT: quit() if keys[pygame.K_ESCAPE]: quit() for layer in gameMap.visible_layers: for x, y, gid, in layer: tile = gameMap.get_tile_image_by_gid(gid) if tile is not None: display.blit(tile, (x * gameMap.tilewidth, y * gameMap.tileheight)) waiter.handle_events() for table in tables: table.render(display) for chair_list in chairs: for chair in chair_list: chair.render(display) key = pygame.key.get_pressed() left, middle, right = pygame.mouse.get_pressed() if left: waiterGo(mouseToNum()) elif right: while True: x = pygame.mouse.get_pos()[1] y = pygame.mouse.get_pos()[0] if y > 608 or y < 32 or x > 608 or x < 32 or check_collision_with_table(y,x) or check_collision_with_chair(y, x): print("I can't go there") break goal = (x // 32, y // 32) route = astar(map.get_arr(), (waiter.loc[1] // 32, waiter.loc[0] // 32), goal) direction = [(x[1] - y[1], x[0] - y[0]) for x, y in zip(route[1:], route)] break elif middle: if client.loc[0] in [64, 128, 192, 256, 352, 416, 480, 544]: while True: x = client.loc[1] - 32 y = client.loc[0] goal = (x // 32, y // 32) route = astar(map.get_arr(), (waiter.loc[1] // 32, waiter.loc[0] // 32), goal) direction = [(x[1] - y[1], x[0] - y[0]) for x, y in zip(route[1:], route)] break elif client.loc[0] in [96, 224, 384, 512]: while True: x = client.loc[1] y = client.loc[0] - 32 goal = (x // 32, y // 32) route = astar(map.get_arr(), (waiter.loc[1] // 32, waiter.loc[0] // 32), goal) direction = [(x[1] - y[1], x[0] - y[0]) for x, y in zip(route[1:], route)] break print() print("Hello Sir, tell me yours preferences") print("Pass: 'budget', 'spiciness', 'vege', 'level_of_hunger', 'allergy', 'favorite_ingridient', 'drink_in'\n") print("Here is my list of preferences") ingridients = tell_preferences() print(ingridients) print() pizza = get_pizza(choose_pizza(evaluate_preferences(ingridients))) print("Our proposition:") print("Name = {}\nprice = {}\nspiciness = {}\nvege = {}\nsize = {}\nallergens = {}\ningridients = {}\ndrink_in = {}\n" .format(pizza.name,pizza.price, pizza.spiciness,pizza.vege,pizza.size,pizza.allergens,pizza.ingridients,pizza.drink_in)) if len(direction) > 0: d = direction.pop(0) if d[0] == 1: waiter.right() elif d[0] == -1: waiter.left() elif d[1] == 1: waiter.down() elif d[1] == -1: waiter.up() key = pygame.key.get_pressed() if key[pygame.K_p]: pass waiter.render(display) client.render(display) pygame.display.update() if __name__ == '__main__': main()