Projekt_KELNER/tiles.py

750 lines
22 KiB
Python

import random
import time
import numpy as np
import pygame
import pytmx
from queue import Queue
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
import json
import openpyxl
import matplotlib.pyplot as plt
import os
import cv2
from tqdm import tqdm
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D
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')
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)
ans = clf.predict([prefernce])
append_choice(ans, prefernce, d, df)
return ans
def append_df_to_excel(df, excel_path):
df_excel = pd.read_excel(excel_path)
result = pd.concat([df_excel, df], ignore_index=True)
result.to_excel(excel_path, index=False)
def append_choice(ans, pre, d, df):
new_row = pre
new_row.append(list(d.keys())[list(d.values()).index(int(ans))])
if new_row[3] == 30:
new_row[3] = 'low'
if new_row[3] == 50:
new_row[3] = 'high'
if new_row[4] == 0:
new_row[4] = 'none'
if new_row[4] == 1:
new_row[4] = 'tomato'
if new_row[4] == 2:
new_row[4] = 'feta'
if new_row[4] == 3:
new_row[4] = 'olives'
if new_row[5] == 0:
new_row[5] = 'none'
if new_row[5] == 1:
new_row[5] = 'salami'
if new_row[5] == 2:
new_row[5] = 'mushrooms'
if new_row[5] == 3:
new_row[5] = 'pineapple'
if new_row[5] == 4:
new_row[5] = 'shrimps'
if new_row[5] == 5:
new_row[5] = 'sausage'
data = {"budget": new_row[0], "spiciness": new_row[1], "vege": new_row[2], "level of hunger": new_row[3],
"allergy": new_row[4], "favorite ingridient": new_row[5], "drink in": 1, "pizza": new_row[7]}
n_df = pd.DataFrame(data, index=[len(df) + 1])
append_df_to_excel(n_df, "restaurant.xlsx")
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
#network
def create_training_data():
DATADIR = "Images"
CATEGORIES = ["yes", "no"]
IMG_SIZE = 90
training_data = []
for category in CATEGORIES:
path = os.path.join(DATADIR, category)
class_num = CATEGORIES.index(category) # 0 - pepperoni, 1 - no pepperoni
for img in tqdm(os.listdir(path)):
try:
img_array = cv2.imread(os.path.join(path, img), cv2.IMREAD_GRAYSCALE)
new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))
training_data.append([new_array, class_num])
except Exception as e:
pass
X = []
y = []
for features, label in training_data:
X.append(features)
y.append(label)
X = np.array(X).reshape(-1, IMG_SIZE, IMG_SIZE, 1)
y = np.array(y)
print("Training data created!")
return X,y
def learn_neural_network(X,y):
X = X/255.0
model = Sequential()
model.add(Conv2D(64, (3, 3), input_shape=X.shape[1:]))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(64))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
model.fit(X, y, batch_size=1, epochs=10, validation_batch_size=0.1)
return model
def prepare_img(filepath):
IMG_SIZE = 90
img_array = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE)
new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))
return new_array.reshape(-1, IMG_SIZE, IMG_SIZE, 1) / 255
def predict(model):
return model.predict([prepare_img('directory')])
def reusult(prediction):
if prediction[0][0] >= 0.5:
print(math.ceil(prediction[0][0]))
print('No pepperoni')
elif prediction[0][0] < 0.5:
print(math.floor(prediction[0][0]))
print("Pepperoni")
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 middle:
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 left:
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()