import time import numpy as np import pygame import pytmx from queue import Queue import math 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') 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] 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 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 class Chair: def __init__(self, loc): self.loc = loc def render(self, surface): surface.blit(chairImg, (self.loc[0], self.loc[1])) class Food: def __init__(self, name, price): self.name = name self.price = price 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: for closed_child in closed_list: if child == closed_child: continue child.g = current_tile.g + map[child.position[0]][child.position[1]] child.h = ((child.position[0] - end_tile.position[0]) ** 2) + ( (child.position[1] - end_tile.position[1]) ** 2) 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) map = Map() waiter = Waiter([32, 32]) tables = [] chairs = [] 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)) 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) 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: goal = (18, 18) 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)] 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) pygame.display.update() if __name__ == '__main__': main()