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') 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.") 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()