2024-03-13 18:05:38 +01:00
|
|
|
import pygame
|
|
|
|
import random
|
|
|
|
import time
|
2024-04-04 03:01:13 +02:00
|
|
|
import numpy
|
2024-04-03 21:48:49 +02:00
|
|
|
import threading
|
2024-03-13 18:05:38 +01:00
|
|
|
|
2024-04-11 23:21:53 +02:00
|
|
|
kuchnia_xy = 0
|
|
|
|
pozycja_startowa = 0
|
|
|
|
|
2024-04-24 21:18:09 +02:00
|
|
|
#------------Ustawienia siatki
|
2024-04-11 23:21:53 +02:00
|
|
|
blockSize = 60
|
|
|
|
rows = 14
|
|
|
|
columns = 24
|
2024-04-04 03:01:13 +02:00
|
|
|
|
2024-04-24 21:18:09 +02:00
|
|
|
#-----------------------------Inicjacja klas
|
2024-04-04 03:01:13 +02:00
|
|
|
class Kelner:
|
|
|
|
def __init__(self, x, y):
|
|
|
|
self.x = x
|
|
|
|
self.y = y
|
2024-04-24 21:18:09 +02:00
|
|
|
self.speed = 70 # od 0 do 100, preferowane 70
|
|
|
|
self.stanPrzestrzeni = [0,0,0]
|
2024-04-04 03:01:13 +02:00
|
|
|
self.stan = "stoi" # Stan kelnera: stoi, odbiera lub wraca
|
|
|
|
self.stolik_docelowy = None # Stolik, do którego idzie kelner
|
2024-04-11 23:21:53 +02:00
|
|
|
self.chodzi = True
|
2024-04-04 03:01:13 +02:00
|
|
|
self.cel_x = x
|
|
|
|
self.cel_y = y
|
2024-04-24 21:18:09 +02:00
|
|
|
self.kierunek = 0 # 0 - północ, 1 - wschód, 2 - południe, 3 - zachód
|
|
|
|
self.indexRuchu = 0
|
2024-04-04 03:01:13 +02:00
|
|
|
|
|
|
|
def wklej(self):
|
2024-04-17 21:22:50 +02:00
|
|
|
kelnerRotated = pygame.transform.rotate(kelnerImg, -90 * kelner.kierunek)
|
|
|
|
screen.blit(kelnerRotated, (self.x * blockSize, self.y * blockSize))
|
2024-04-04 03:01:13 +02:00
|
|
|
|
2024-04-24 21:18:09 +02:00
|
|
|
# def idz_do_stolika(self):
|
|
|
|
# self.cel_x, self.cel_y = self.stolik_docelowy.x, self.stolik_docelowy.y
|
|
|
|
# kelner.stan = "odbiera"
|
2024-04-04 03:01:13 +02:00
|
|
|
|
|
|
|
def idz_do_kuchni(self):
|
2024-04-11 23:21:53 +02:00
|
|
|
self.cel_x, self.cel_y = kuchnia_xy, kuchnia_xy
|
2024-04-04 03:01:13 +02:00
|
|
|
self.stolik_docelowy = None
|
|
|
|
kelner.stan = "wraca"
|
|
|
|
|
2024-04-17 21:22:50 +02:00
|
|
|
def obrot_w_lewo(self):
|
2024-04-24 21:18:09 +02:00
|
|
|
self.kierunek = (self.kierunek - 1) % 4
|
|
|
|
self.stanPrzestrzeni[2] = (self.stanPrzestrzeni[2] - 1) % 4
|
2024-04-17 21:22:50 +02:00
|
|
|
|
|
|
|
def obrot_w_prawo(self):
|
2024-04-24 21:18:09 +02:00
|
|
|
self.kierunek = (self.kierunek + 1) % 4
|
|
|
|
self.stanPrzestrzeni[2] = (self.stanPrzestrzeni[2] + 1) % 4
|
2024-04-17 21:22:50 +02:00
|
|
|
|
|
|
|
def idz_do_przodu(self):
|
|
|
|
if self.kierunek == 0:
|
2024-04-24 21:18:09 +02:00
|
|
|
self.y -= 1
|
|
|
|
self.stanPrzestrzeni[1] -= 1
|
2024-04-17 21:22:50 +02:00
|
|
|
elif self.kierunek == 1:
|
2024-04-24 21:18:09 +02:00
|
|
|
self.x += 1
|
|
|
|
self.stanPrzestrzeni[0] += 1
|
2024-04-17 21:22:50 +02:00
|
|
|
elif self.kierunek == 2:
|
2024-04-24 21:18:09 +02:00
|
|
|
self.y += 1
|
|
|
|
self.stanPrzestrzeni[1] += 1
|
2024-04-17 21:22:50 +02:00
|
|
|
elif self.kierunek == 3:
|
2024-04-24 21:18:09 +02:00
|
|
|
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
|
2024-04-17 21:22:50 +02:00
|
|
|
|
2024-04-04 03:01:13 +02:00
|
|
|
|
|
|
|
class Stolik:
|
|
|
|
def __init__(self, x, y):
|
|
|
|
self.x = x
|
|
|
|
self.y = y
|
|
|
|
self.zamowione = False
|
|
|
|
|
|
|
|
def wklej(self):
|
2024-04-11 23:21:53 +02:00
|
|
|
screen.blit(stolikImg, (self.x * blockSize, self.y * blockSize))
|
2024-03-13 18:05:38 +01:00
|
|
|
|
2024-04-04 03:01:13 +02:00
|
|
|
|
2024-04-24 21:18:09 +02:00
|
|
|
#-----------------Przeszukiwanie przestrzeni stanów
|
|
|
|
|
|
|
|
from collections import deque
|
|
|
|
|
|
|
|
def bfs(start, cel, stoliki):
|
|
|
|
queue = deque([start])
|
|
|
|
odwiedzone = set([start])
|
|
|
|
poprzednik = {start: (None, None)} # Słownik ścieżek (stan, ruch)
|
|
|
|
|
|
|
|
while queue:
|
|
|
|
obecny = queue.popleft()
|
|
|
|
|
|
|
|
if obecny[:2] == cel:
|
|
|
|
return odtworz_ruchy(poprzednik, obecny)
|
|
|
|
|
|
|
|
for sasiad, ruch in generuj_nastepniki_i_ruchy(obecny, stoliki):
|
|
|
|
if sasiad not in odwiedzone:
|
|
|
|
odwiedzone.add(sasiad)
|
|
|
|
queue.append(sasiad)
|
|
|
|
poprzednik[sasiad] = (obecny, ruch)
|
|
|
|
|
|
|
|
return [] # Cel nie został znaleziony
|
|
|
|
|
|
|
|
|
|
|
|
#----------Funkcja generowania następników dla poszczególnych stanów
|
|
|
|
def generuj_nastepniki_i_ruchy(stan, stoliki):
|
|
|
|
x, y, kierunek = stan
|
|
|
|
ruchy = []
|
|
|
|
|
|
|
|
# Obrot w lewo
|
|
|
|
nowy_kierunek = (kierunek - 1) % 4
|
|
|
|
ruchy.append(((x, y, nowy_kierunek), 'L'))
|
|
|
|
|
|
|
|
# Obrot w prawo
|
|
|
|
nowy_kierunek = (kierunek + 1) % 4
|
|
|
|
ruchy.append(((x, y, nowy_kierunek), 'R'))
|
|
|
|
|
|
|
|
# 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
|
2024-04-04 03:01:13 +02:00
|
|
|
|
2024-04-24 21:18:09 +02:00
|
|
|
#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 (nowy_x, nowy_y) not in stoliki:
|
|
|
|
ruchy.append(((nowy_x, nowy_y, kierunek), 'F'))
|
2024-04-04 03:01:13 +02:00
|
|
|
|
2024-04-24 21:18:09 +02:00
|
|
|
return ruchy
|
|
|
|
|
|
|
|
#-----Funkcja tworząca listę kroków potrzebnych do uzyskania celu
|
|
|
|
def odtworz_ruchy(poprzednicy, cel):
|
|
|
|
ruchy = []
|
|
|
|
krok = cel
|
|
|
|
while poprzednicy[krok][0] is not None:
|
|
|
|
ruchy.append(poprzednicy[krok][1])
|
|
|
|
krok = poprzednicy[krok][0]
|
|
|
|
ruchy.reverse()
|
|
|
|
return ruchy
|
|
|
|
|
|
|
|
|
|
|
|
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 10", "4 12", "16 10", "12 12", "20 12", "12 9", "0 6", "8 4", "16 4", "23 6"]
|
|
|
|
|
|
|
|
#Tworzenie listy stolikow
|
2024-04-04 03:01:13 +02:00
|
|
|
stoliki = []
|
|
|
|
for coord in coords:
|
|
|
|
x, y = map(int, coord.split())
|
|
|
|
stoliki.append(Stolik(x, y))
|
|
|
|
|
|
|
|
pygame.init()
|
2024-03-13 18:05:38 +01:00
|
|
|
pygame.display.set_caption("Automatyczny kelner")
|
2024-04-04 03:01:13 +02:00
|
|
|
|
2024-04-24 21:18:09 +02:00
|
|
|
#----------------wymiary okna
|
2024-04-11 23:21:53 +02:00
|
|
|
width = columns * blockSize
|
|
|
|
height = rows * blockSize
|
2024-03-13 18:05:38 +01:00
|
|
|
|
|
|
|
screen = pygame.display.set_mode((width, height))
|
|
|
|
|
|
|
|
kelnerImg = pygame.image.load("kelner.png")
|
2024-04-11 23:21:53 +02:00
|
|
|
kelnerImg = pygame.transform.scale(kelnerImg, (blockSize, blockSize))
|
2024-03-13 18:05:38 +01:00
|
|
|
stolikImg = pygame.image.load("stolik.png")
|
2024-04-11 23:21:53 +02:00
|
|
|
stolikImg = pygame.transform.scale(stolikImg, (blockSize, blockSize))
|
2024-04-03 21:48:49 +02:00
|
|
|
menuImg = pygame.image.load("menu.png")
|
2024-04-11 23:21:53 +02:00
|
|
|
menuImg = pygame.transform.scale(menuImg, (blockSize / 2, blockSize / 2))
|
2024-04-03 21:48:49 +02:00
|
|
|
kitchenImg = pygame.image.load("kitchen.png")
|
2024-04-11 23:21:53 +02:00
|
|
|
kitchenImg = pygame.transform.scale(kitchenImg, (blockSize * 2, blockSize * 2))
|
2024-04-03 21:48:49 +02:00
|
|
|
|
|
|
|
def kuchnia(x, y):
|
2024-04-11 23:21:53 +02:00
|
|
|
screen.blit(kitchenImg, (x * blockSize, y * blockSize))
|
2024-03-13 18:05:38 +01:00
|
|
|
|
2024-04-04 03:01:13 +02:00
|
|
|
def menu(x, y):
|
2024-04-11 23:21:53 +02:00
|
|
|
screen.blit(menuImg, (x * blockSize, y * blockSize))
|
2024-04-03 21:48:49 +02:00
|
|
|
|
|
|
|
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)
|
2024-04-24 21:18:09 +02:00
|
|
|
pygame.draw.rect(screen, (200, 200, 200), rect, 1) #-------------Wypisz kratę -TA
|
2024-04-03 21:48:49 +02:00
|
|
|
|
2024-03-13 18:05:38 +01:00
|
|
|
run = True
|
|
|
|
|
2024-04-11 23:21:53 +02:00
|
|
|
# czcionka = pygame.font.SysFont('Arial',50)
|
2024-04-03 21:48:49 +02:00
|
|
|
|
2024-04-11 23:21:53 +02:00
|
|
|
licznik = 0
|
2024-04-24 21:18:09 +02:00
|
|
|
ruchy = []
|
|
|
|
cel2 = []
|
2024-04-03 21:48:49 +02:00
|
|
|
|
2024-03-13 18:05:38 +01:00
|
|
|
while run:
|
2024-04-24 21:18:09 +02:00
|
|
|
stoliki_pozycje = [(stolik.x, stolik.y) for stolik in stoliki]
|
|
|
|
cel2 = list(cel)
|
|
|
|
|
|
|
|
#print(f"{kelner.stanPrzestrzeni}, {cel2}, {kelner.indexRuchu} {kelner.stan}")
|
2024-04-03 21:48:49 +02:00
|
|
|
wypiszOkno()
|
2024-04-04 03:01:13 +02:00
|
|
|
kuchnia(kuchnia_xy, kuchnia_xy)
|
|
|
|
|
|
|
|
for stolik in stoliki:
|
|
|
|
stolik.wklej()
|
2024-04-24 21:18:09 +02:00
|
|
|
|
2024-04-04 03:01:13 +02:00
|
|
|
kelner.wklej()
|
|
|
|
|
|
|
|
if kelner.stan == "wraca":
|
2024-04-24 21:18:09 +02:00
|
|
|
menu(kelner.x, kelner.y)
|
2024-04-04 03:01:13 +02:00
|
|
|
|
2024-04-11 23:21:53 +02:00
|
|
|
licznik += 1
|
|
|
|
|
2024-04-24 21:18:09 +02:00
|
|
|
#------------weź zamowienie
|
|
|
|
for stolik in stoliki:
|
2024-04-04 03:01:13 +02:00
|
|
|
if stolik.zamowione == True:
|
|
|
|
menu(stolik.x, stolik.y)
|
|
|
|
if kelner.stan == "stoi":
|
|
|
|
kelner.stolik_docelowy = stolik
|
2024-04-24 21:18:09 +02:00
|
|
|
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 = bfs(tuple(kelner.stanPrzestrzeni), cel, stoliki_pozycje)
|
|
|
|
kelner.stan = "odbiera"
|
|
|
|
if ruchy:
|
|
|
|
print("Znaleziono ścieżkę ruchów: ", ruchy)
|
|
|
|
else:
|
|
|
|
print("Nie znaleziono ścieżki do celu.")
|
|
|
|
|
|
|
|
|
|
|
|
#----------Losuje stoliki, które dokonają zamówienia
|
2024-04-04 03:01:13 +02:00
|
|
|
if kelner.stan == "stoi":
|
|
|
|
for stolik in stoliki:
|
2024-04-24 21:18:09 +02:00
|
|
|
if stolik.zamowione == True:
|
2024-04-04 03:01:13 +02:00
|
|
|
break
|
2024-04-11 23:21:53 +02:00
|
|
|
for i in range(len(stoliki)):
|
|
|
|
if random.randrange(2) == 1:
|
|
|
|
stoliki[i].zamowione = True
|
2024-04-04 03:01:13 +02:00
|
|
|
|
2024-04-24 21:18:09 +02:00
|
|
|
#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:
|
2024-04-04 03:01:13 +02:00
|
|
|
kelner.stolik_docelowy.zamowione = False
|
|
|
|
kelner.idz_do_kuchni()
|
2024-04-24 21:18:09 +02:00
|
|
|
cel = (kelner.cel_x, kelner.cel_y)
|
|
|
|
print("Szukam ścieżki do kuchni...")
|
|
|
|
ruchy = bfs(tuple(kelner.stanPrzestrzeni), cel, stoliki_pozycje)
|
|
|
|
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:
|
2024-04-04 03:01:13 +02:00
|
|
|
kelner.stan = "stoi"
|
|
|
|
|
2024-04-24 21:18:09 +02:00
|
|
|
|
2024-03-13 18:05:38 +01:00
|
|
|
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
|
|
|
|
pygame.quit()
|