Automatyczny_kelner/main_network.py

544 lines
18 KiB
Python

import pygame
import random
import time
import pandas as pd
import math
import matplotlib.pyplot as plt
kuchnia_xy = 0
pozycja_startowa = 0
losuj_uklad = False # Gdy True, losuje uklad stolikow oraz przeszkod
# ------------Ustawienia siatki
blockSize = 60
rows = 14
columns = 24
# -----------------------------Inicjacja klas
class Kelner:
def __init__(self, x, y):
self.x = x
self.y = y
self.speed = 80 # od 0 do 100, preferowane 80
self.stanPrzestrzeni = [0, 0, 0]
self.stan = "stoi" # Stan kelnera: stoi, odbiera lub wraca
self.stolik_docelowy = None # Stolik, do którego idzie kelner
self.chodzi = True
self.cel_x = x
self.cel_y = y
self.kierunek = 0 # 0 - północ, 1 - wschód, 2 - południe, 3 - zachód
self.indexRuchu = 0
def wklej(self):
kelnerRotated = pygame.transform.rotate(kelnerImg, -90 * kelner.kierunek)
screen.blit(kelnerRotated, (self.x * blockSize, self.y * blockSize))
# def idz_do_stolika(self):
# self.cel_x, self.cel_y = self.stolik_docelowy.x, self.stolik_docelowy.y
# kelner.stan = "odbiera"
def idz_do_kuchni(self):
self.cel_x, self.cel_y = kuchnia_xy, kuchnia_xy
self.stolik_docelowy = None
kelner.stan = "wraca"
def obrot_w_lewo(self):
self.kierunek = (self.kierunek - 1) % 4
self.stanPrzestrzeni[2] = (self.stanPrzestrzeni[2] - 1) % 4
def obrot_w_prawo(self):
self.kierunek = (self.kierunek + 1) % 4
self.stanPrzestrzeni[2] = (self.stanPrzestrzeni[2] + 1) % 4
def idz_do_przodu(self):
if self.kierunek == 0:
self.y -= 1
self.stanPrzestrzeni[1] -= 1
elif self.kierunek == 1:
self.x += 1
self.stanPrzestrzeni[0] += 1
elif self.kierunek == 2:
self.y += 1
self.stanPrzestrzeni[1] += 1
elif self.kierunek == 3:
self.x -= 1
self.stanPrzestrzeni[0] -= 1
def wykonajAkcje(self, ruchy):
if self.indexRuchu < len(ruchy):
akcja = ruchy[self.indexRuchu]
if akcja == 'F':
self.idz_do_przodu()
elif akcja == 'L':
self.obrot_w_lewo()
elif akcja == 'R':
self.obrot_w_prawo()
self.indexRuchu += 1
if self.indexRuchu >= len(ruchy): # Reset po zakończeniu wszystkich ruchów
self.indexRuchu = 0
class Stolik:
def __init__(self, x, y):
self.x = x
self.y = y
self.zamowione = False
def wklej(self):
screen.blit(stolikImg, (self.x * blockSize, self.y * blockSize))
class Przeszkoda:
def __init__(self, x, y, typ):
self.x = x
self.y = y
self.typ = typ
# ocena kosztu przeszkody
if self.typ == "sliska podloga":
self.cena = 2
elif self.typ == "dywan":
self.cena = 4
def wklej(self):
if self.typ == "sliska podloga":
screen.blit(sliskaPodlogaImg, (self.x * blockSize, self.y * blockSize))
elif self.typ == "dywan":
screen.blit(dywanImg, (self.x * blockSize, self.y * blockSize))
# -----------------Przeszukiwanie przestrzeni stanów
import heapq
def a_star(start, cel, stoliki, przeszkody):
queue = [] # Kolejka priorytetowa
heapq.heappush(queue, (0, start)) # (koszt, stan)
odwiedzone = set([start])
poprzednicy = {start: (None, None, 0)} # (poprzedni stan, ruch, koszt do tej pory)
while queue:
obecny_koszt, obecny = heapq.heappop(queue) # pobranie stanu z najniższym kosztem
if obecny[:2] == cel:
return odtworz_ruchy(poprzednicy, obecny)
for nastepnik, ruch, koszt_ruchu in generuj_nastepniki_i_ruchy(obecny, stoliki, przeszkody):
nowy_koszt = poprzednicy[obecny][2] + koszt_ruchu # Obliczanie nowego kosztu dojscia do nastepnika
# nastepnik nie był odwiedzony lub znaleziono tansza sciezke do niego
if nastepnik not in odwiedzone or nowy_koszt < poprzednicy.get(nastepnik, (None, None, float('inf')))[2]:
heapq.heappush(queue, (nowy_koszt + heurystyka(nastepnik, cel), nastepnik))
poprzednicy[nastepnik] = (obecny, ruch, nowy_koszt)
odwiedzone.add(nastepnik)
return []
def heurystyka(nastepnik, cel):
# Oszacowanie sumy odleglosci w pionie i w poziomie
return abs(nastepnik[0] - cel[0]) + abs(nastepnik[1] - cel[1])
# ----------Funkcja generowania następników dla poszczególnych stanów
def generuj_nastepniki_i_ruchy(stan, stoliki, przeszkody):
x, y, kierunek = stan
ruchy = []
# Obrot w lewo
nowy_kierunek = (kierunek - 1) % 4
ruchy.append(((x, y, nowy_kierunek), 'L', 1))
# Obrot w prawo
nowy_kierunek = (kierunek + 1) % 4
ruchy.append(((x, y, nowy_kierunek), 'R', 1))
# Krok do przodu
if kierunek == 0:
nowy_x, nowy_y = x, y - 1
elif kierunek == 1:
nowy_x, nowy_y = x + 1, y
elif kierunek == 2:
nowy_x, nowy_y = x, y + 1
elif kierunek == 3:
nowy_x, nowy_y = x - 1, y
# sprawdzamy, czy następny stan jest w granicach planszy
if 0 <= nowy_x < columns and 0 <= nowy_y < rows:
# sprawdzamy, czy następny stan nie wchodzi w stolik
if not any(stolik.x == nowy_x and stolik.y == nowy_y for stolik in stoliki):
koszt = next(
(przeszkoda.cena for przeszkoda in przeszkody if przeszkoda.x == nowy_x and przeszkoda.y == nowy_y), 1)
ruchy.append(((nowy_x, nowy_y, kierunek), 'F', koszt))
return ruchy
# -----Funkcja tworząca listę kroków potrzebnych do uzyskania celu
def odtworz_ruchy(poprzednicy, cel):
ruchy = []
krok = cel
while krok and poprzednicy[krok][0] is not None:
ruchy.append(poprzednicy[krok][1])
krok = poprzednicy[krok][0]
ruchy.reverse()
return ruchy
def licz_entropie(data, target_column):
total_rows = len(data)
target_values = data[target_column].unique()
entropy = 0
for value in target_values:
value_count = len(data[data[target_column] == value])
proportion = value_count / total_rows
entropy -= proportion * math.log2(proportion)
return entropy
def licz_zysk(atrybut,korzen,data):
entropia_wazona = 0
unique_values = data[atrybut].unique()
for value in unique_values:
subset = data[data[atrybut] == value]
proportion = len(subset) / len(data)
entropia_wazona += proportion * licz_entropie(subset, data.columns[-1])
zysk = korzen - entropia_wazona
return zysk
def szukaj_split(z, atrybuty):
max = 0
max_atr = "None"
for atrybut in atrybuty:
if z[atrybut]>max:
max = z[atrybut]
max_atr = atrybut
return max_atr
def GenerujDane(ques):
k = [0,0,0,0,0,0,0,0]
for n in range(8):
k[n] = random.choice([0,1])
print(ques[n] + str(k[n]))
return k
def id3(data,mode,klient):
zysk = {}
korzen = licz_entropie(data,data.columns[-1])
lista = data.columns
for atrybut in lista[:-1]:
zysk[atrybut] = licz_zysk(atrybut,korzen,data)
split = szukaj_split(zysk, data.head(0).columns[:-1])
if split == "None":
wynik = data.iloc[0, -1]
if wynik == 1 and mode == "klient":
print("Klient zadowolony!")
elif wynik == 0 and mode == "klient":
print("Klient niezadowolony!")
print("---------------------------------------------------------------------------------------")
else:
#print("Split: " + str(split))
subset0 = data[data[split] == 0]
subset0 = subset0.drop([split], axis=1)
subset1 = data[data[split] == 1]
subset1 = subset1.drop([split], axis=1)
#print("Klient: " + str(klient))
if len(subset0) < len(data) and len(subset1) < len(data):
if mode == "klient":
if klient[split] == 0:
frames.append(subset0)
else:
frames.append(subset1)
elif mode == "full":
frames.append(subset0)
frames.append(subset1)
if len(frames) > 0:
newData = frames.pop()
id3(newData,mode, klient)
start = (0, 0, 0) # Początkowy stan
cel = (0, 0) # Docelowe współrzędne
# --------------Inicjacja obiektów
kelner = Kelner(pozycja_startowa, pozycja_startowa)
# -----------wspolrzedne stolikow
coords = ["8 4", "16 4", "0 7", "23 7", "12 9", "8 10", "16 10", "4 12", "12 12", "20 12"]
# -----------wspolrzedne sliskich podlog
coords2 = ["0 2", "0 3", "0 4", "0 5", "4 8", "4 9", "12 2", "12 3", "15 8", "16 8", "19 4", "20 4", "21 4"]
# -----------wspolrzedne dywanow
coords3 = ["6 0", "6 1", "2 2", "3 2", "4 2", "5 2", "1 5", "6 2", "8 6", "8 7", "20 2", "20 3", "19 9", "20 9", "21 9"]
# Tworzenie listy stolikow i przeszkod
stoliki = []
przeszkody = []
if not losuj_uklad:
for coord in coords:
x, y = map(int, coord.split())
stoliki.append(Stolik(x, y))
for coord in coords2:
x, y = map(int, coord.split())
przeszkody.append(Przeszkoda(x, y, "sliska podloga"))
for coord in coords3:
x, y = map(int, coord.split())
przeszkody.append(Przeszkoda(x, y, "dywan"))
else:
juzbyly = []
for j in range(1, rows):
for i in range(columns):
if (random.randrange(7) == 0) and ((i, j - 1) not in juzbyly) and (
((i - 1, j - 1) not in juzbyly) or ((i + 1, j - 1) not in juzbyly)):
stoliki.append(Stolik(i, j))
juzbyly.append((i, j))
elif random.randrange(9) == 0:
przeszkody.append(Przeszkoda(i, j, "sliska podloga"))
elif random.randrange(12) == 0:
przeszkody.append(Przeszkoda(i, j, "dywan"))
# stoliki = []
# for i in range(rows)
pygame.init()
pygame.display.set_caption("Automatyczny kelner")
# ----------------wymiary okna
width = columns * blockSize
height = rows * blockSize
screen = pygame.display.set_mode((width, height))
kelnerImg = pygame.image.load("kelner.png")
kelnerImg = pygame.transform.scale(kelnerImg, (blockSize, blockSize))
stolikImg = pygame.image.load("stolik.png")
stolikImg = pygame.transform.scale(stolikImg, (blockSize, blockSize))
menuImg = pygame.image.load("menu.png")
menuImg = pygame.transform.scale(menuImg, (blockSize / 2, blockSize / 2))
kitchenImg = pygame.image.load("kitchen.png")
kitchenImg = pygame.transform.scale(kitchenImg, (blockSize * 2, blockSize * 2))
sliskaPodlogaImg = pygame.image.load("plama.png")
sliskaPodlogaImg = pygame.transform.scale(sliskaPodlogaImg, (blockSize, blockSize))
dywanImg = pygame.image.load("dywan.png")
dywanImg = pygame.transform.scale(dywanImg, (blockSize, blockSize))
def kuchnia(x, y):
screen.blit(kitchenImg, (x * blockSize, y * blockSize))
def menu(x, y):
screen.blit(menuImg, (x * blockSize, y * blockSize))
def wypiszOkno():
screen.fill((0, 0, 0))
for x in range(0, width, blockSize):
for y in range(0, height, blockSize):
rect = pygame.Rect(x, y, blockSize, blockSize)
pygame.draw.rect(screen, (200, 200, 200), rect, 1) # -------------Wypisz kratę -TA
# pygame.draw.rect(screen, (0, 0, 0), rect, 1) #-------------Wypisz kratę -TA
def czyZadowolony():
data = pd.read_csv('zbior_uczacy.csv')
frames = []
frames.append(data)
ques = ["Czy klient sie usmiecha? ", "Czy zostawil napiwek? ", "Czy zachowywal sie grzecznie? ",
"Czy zjadl cala porcje? ", "Czy zlozyl dodatkowe zamowienia? ",
"Czy wyrazil zainteresowanie karta stalego klienta? ", "Czy zarezerwowal stolik na przyszlosc? ",
"Czy zabral wizytowke? "]
k = GenerujDane(ques)
atrybuty = []
for column in data.columns[:-1]:
atrybuty.append(column)
klient = {}
i = 0
for atr in atrybuty:
klient[atr] = k[i]
i = i + 1
while len(frames) > 0:
data = frames.pop()
id3(data, "klient", klient)
run = True
# czcionka = pygame.font.SysFont('Arial',50)
licznik = 0
ruchy = []
cel2 = []
klient = {}
frames = []
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.tree import plot_tree, DecisionTreeClassifier
data = pd.read_csv('zbior_uczacy.csv')
data.head()
#print(heart_data)
data_x = data.drop('Zadowolony', axis=1)
data_y = data['Zadowolony']
data_x_encoded = pd.get_dummies(data_x, drop_first = True)
data_x_encoded.head()
best_acc = 0
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
X_train, X_test, y_train, y_test = train_test_split(data_x_encoded, data_y, test_size=0.3)
dtree = DecisionTreeClassifier(max_depth=100)
dtree.fit(X_train, y_train)
fig = plt.figure(figsize=((25,20)))
plot_tree(dtree,
feature_names=data_x_encoded.columns,
class_names=['niezadowolony', 'zadowolony'],
impurity=False,
proportion=False,
filled=True)
fig.savefig('tree.png')
#---------------Neural network
import tensorflow as tf
from tensorflow import keras
import numpy as np
import os
import random
from PIL import Image
new_model = keras.models.load_model("/home/kwak/PycharmProjects/AutomatycznyKelner/pythonProject1/nn.keras")
data_cat = ["churros", "cup_cakes", "donuts"]
img_height = 160
img_width = 160
def randomImage(img_height, img_width):
folder_path = r"Automatyczny_kelner/onTable_toFillWIthRandomPictures"
files = os.listdir(folder_path)
image_files = [file for file in files if file.endswith(('png', 'jpg', 'jpeg', 'gif'))]
random_image = random.choice(image_files)
image_path = os.path.join(folder_path, random_image)
image = Image.open(image_path)
image.show()
image = image_path
image_load = tf.keras.utils.load_img(image, target_size=(img_height, img_width))
img_arr = tf.keras.utils.array_to_img(image_load)
img_bat = tf.expand_dims(img_arr, 0)
predict = new_model.predict(img_bat)
print(predict)
#predicted_class = np.argmax(predict, axis=-1)
#print(data_cat[int(predicted_class)])
score = tf.nn.softmax(predict)
print('Food in image is {} with accuracy of {:0.2f}'.format(data_cat[np.argmax(score)], np.max(score) * 100))
while run:
cel2 = list(cel)
# print(f"{kelner.stanPrzestrzeni}, {cel2}, {kelner.indexRuchu} {kelner.stan}")
wypiszOkno()
kuchnia(kuchnia_xy, kuchnia_xy)
for stolik in stoliki:
stolik.wklej()
for przeszkoda in przeszkody:
przeszkoda.wklej()
kelner.wklej()
if kelner.stan == "wraca":
menu(kelner.x, kelner.y)
licznik += 1
# ------------weź zamowienie
for stolik in stoliki:
if stolik.zamowione == True:
menu(stolik.x, stolik.y)
if kelner.stan == "stoi":
kelner.stolik_docelowy = stolik
kelner.cel_x, kelner.cel_y = kelner.stolik_docelowy.x, kelner.stolik_docelowy.y - 1
cel = (kelner.cel_x, kelner.cel_y)
print("Szukam ścieżki do stolika...")
ruchy = a_star(tuple(kelner.stanPrzestrzeni), cel, stoliki, przeszkody)
kelner.stan = "odbiera"
if ruchy:
print("Znaleziono ścieżkę ruchów: ", ruchy)
czyZadowolony()
else:
print("Nie znaleziono ścieżki do celu.")
# ----------Losuje stoliki, które dokonają zamówienia
if kelner.stan == "stoi":
for stolik in stoliki:
if stolik.zamowione == True:
break
for i in range(len(stoliki)):
if random.randrange(2) == 1:
stoliki[i].zamowione = True
# print(kelner.stan)--------------------------Wypisuje stan kelnera
# print(f"{kelner.x} {kelner.y}")-------------Wypisuje wspolrzedne kelnera
# ----------------Zmiana pozycji kelnera
if kelner.chodzi == True and licznik % (101 - kelner.speed) == 0 and kelner.stanPrzestrzeni[
:2] != cel2: # ograniczenie prędkości
kelner.wykonajAkcje(ruchy)
if kelner.stanPrzestrzeni[:2] == cel2:
if kelner.stan == "odbiera" and kelner.x == kelner.stolik_docelowy.x and kelner.y == kelner.stolik_docelowy.y - 1:
kelner.stolik_docelowy.zamowione = False
kelner.idz_do_kuchni()
cel = (kelner.cel_x, kelner.cel_y)
print("Szukam ścieżki do kuchni...")
ruchy = a_star(tuple(kelner.stanPrzestrzeni), cel, stoliki, przeszkody)
if ruchy:
print("Znaleziono ścieżkę ruchów: ", ruchy)
else:
print("Nie znaleziono ścieżki do celu.")
# ---------neural_network
randomImage(img_height, img_width)
elif kelner.stan == "wraca" and kelner.x == kuchnia_xy and kelner.y == kuchnia_xy:
kelner.stan = "stoi"
time.sleep(0.001)
key = pygame.key.get_pressed()
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#------------------------------------------------------------------------------------------------------------------
'''
frames.clear()
frames.append(data)
while len(frames) > 0:
data = frames.pop()
id3(data,"full")
'''
pygame.quit()