Możliwość zamknięcia okna w każdym momencie. Zmiana sposobu wyświetlania. Zastosowanie wzorca "obserwator".

This commit is contained in:
Dominik Jagosz 2022-04-16 16:45:37 +02:00
parent c8ea93916b
commit 1c4c851c3d
8 changed files with 185 additions and 131 deletions

View File

@ -3,42 +3,47 @@ from collections import deque
from bfs import Stan, Akcja, graphsearch
from krata import *
from obserwacja import *
class Agent:
cel: Stan
class Agent(Obserwowany):
bok = BOK_AGENTA1
bokWPolach = BOK_AGENTA1_W_POLACH
cel: Stan or None
kierunek: Kierunek
# droga: int
hitbox: pygame.Rect
poleKoncoweDolne: PoleKraty
def __init__(self, Krata, poleStartoweGorne: PoleKraty, tekstura):
self.krata = Krata
def __init__(self, krata: Krata, poleStartoweGorne: PoleKraty, tekstura):
self.krata = krata
self.poleStartoweGorne = poleStartoweGorne
self.tekstura = tekstura
self.okreslPolozenie()
self.obierzLosowyKierunek()
self.okreslDlugoscDrogi()
Krata.agent = self
# self.okreslDlugoscDrogi()
krata.agent = self
self.cel = None
def ruszSie(self):
if self.droga <= 0:
self.obierzLosowyKierunek()
self.okreslDlugoscDrogi()
self.zrobKrokWMoimKierunku()
self.droga -= 1
self.okreslPolozenie()
if self.wyszedlemPozaKrate() or self.wszedlemWSciane():
self.cofnijSie()
self.zawroc()
self.okreslDlugoscDrogi()
# def ruszSie(self):
# if self.droga <= 0:
# self.obierzLosowyKierunek()
# self.okreslDlugoscDrogi()
# self.zrobKrokWMoimKierunku()
# self.droga -= 1
# self.okreslPolozenie()
# if self.wyszedlemPozaKrate() or self.wszedlemWSciane():
# self.cofnijSie()
# self.zawroc()
# self.okreslDlugoscDrogi()
def obierzLosowyKierunek(self):
self.kierunek = Kierunek(random.randint(0, 3))
if self.maxDlugoscDrogiWMoimKierunku() < 1:
self.obierzLosowyKierunek()
# if self.maxDlugoscDrogiWMoimKierunku() < 1:
# self.obierzLosowyKierunek()
def okreslDlugoscDrogi(self):
self.droga = random.randint(1, self.maxDlugoscDrogiWMoimKierunku())
# def okreslDlugoscDrogi(self):
# self.droga = random.randint(1, self.maxDlugoscDrogiWMoimKierunku())
def cofnijSie(self):
self.zrobKrokWOdwrotnymKierunku()
@ -47,6 +52,7 @@ class Agent:
def okreslPolozenie(self):
self.okreslPoleKoncoweDolne()
self.okreslHitbox()
self.powiadomObserwatorow()
def okreslHitbox(self):
self.hitbox = pygame.Rect(self.poleStartoweGorne.start, self.poleStartoweGorne.gora, self.bok, self.bok)
@ -68,7 +74,6 @@ class Agent:
else:
return False
# ZROBIC sciany
def wszedlemWSciane(self):
for wiersz in range(self.poleStartoweGorne.wiersz, self.poleKoncoweDolne.wiersz + 1):
for kolumna in range(self.poleStartoweGorne.kolumna, self.poleKoncoweDolne.kolumna + 1):
@ -128,41 +133,34 @@ class Agent:
def idzNaWschod(self):
self.poleStartoweGorne.kolumna += 1
# def bfs(self,graph, start, cel):
# sciezka = [start]
# wierzcholek_sciezka = [start, sciezka]
# bfs_kolejka = [wierzcholek_sciezka]
# odwiedzone = set()
# while bfs_kolejka:
# aktualne, sciezka = bfs_kolejka.pop(0)
# odwiedzone.add(aktualne)
# for neighbor in graph[aktualne]:
# if neighbor not in odwiedzone:
# if neighbor is cel:
# return sciezka + [neighbor]
# else:
# bfs_kolejka.append([neighbor, sciezka + [neighbor]])
def idzDoCelu(self, klatkaz):
def idzDoCelu(self):
stan_poczatkowy = Stan(self.kierunek, self.poleStartoweGorne)
stos_akcji = graphsearch(stan_poczatkowy, self.cel)
if stos_akcji == False:
if not stos_akcji:
print("Nie można dotrzeć.")
else:
self.wykonaj_stos_akcji(stos_akcji, klatkaz)
self.wykonaj_stos_akcji(stos_akcji)
print("Dotarłem.")
self.usunCel()
self.krata.krata[self.cel.poleStartoweGorne.wiersz][
self.cel.poleStartoweGorne.kolumna] = ZawartoscPola.PUSTE ##chwilowo-przeniesc pozniej
def ustawCel(self, cel):
self.cel = cel
wiersz = self.cel.poleStartoweGorne.wiersz
kolumna = self.cel.poleStartoweGorne.kolumna
if self.krata.krata[wiersz][kolumna] == ZawartoscPola.PUSTE:
self.krata.krata[wiersz][kolumna] = ZawartoscPola.CEL
def usunCel(self):
wiersz = self.cel.poleStartoweGorne.wiersz
kolumna = self.cel.poleStartoweGorne.kolumna
if self.krata.krata[wiersz][kolumna] == ZawartoscPola.CEL:
self.krata.krata[wiersz][kolumna] = ZawartoscPola.PUSTE
self.cel = None
def wykonaj_stos_akcji(self, stos_akcji: deque, klatkaz):
def wykonaj_stos_akcji(self, stos_akcji: deque):
while stos_akcji:
klatkaz.tick(FPS)
self.narysujAgenta()
akcja = stos_akcji.pop()
print(akcja.name, end=" ")
# print(akcja.name, end=" ")
if akcja == Akcja.KROK_W_PRZOD:
self.zrobKrokWMoimKierunku()
self.okreslPolozenie()
@ -170,7 +168,7 @@ class Agent:
self.obrocSieWLewo()
elif akcja == Akcja.OBROT_W_PRAWO:
self.obrocSieWPrawo()
print()
# print()
def obrocSieWLewo(self):
self.kierunek = self.kierunek.kierunekNaLewo()
@ -179,6 +177,8 @@ class Agent:
self.kierunek = self.kierunek.kierunekNaPrawo()
def narysujAgenta(self):
self.krata.narysujKrate()
self.krata.okno.blit(self.tekstura, (self.hitbox.x, self.hitbox.y))
pygame.display.update()
def powiadomObserwatorow(self):
for obserwator in self.obserwatorzy:
obserwator.odbierzPowiadomienie(self)

2
bfs.py
View File

@ -19,7 +19,7 @@ class Stan:
class Nastepnik:
def __init__(self, akcja: Akcja, stan: Stan, poprzednik):
def __init__(self, akcja: Akcja or None, stan: Stan, poprzednik):
self.akcja = akcja
self.stan = stan
self._poprzednik = poprzednik

View File

@ -1,12 +1,16 @@
import pygame
from enumy_i_slowniki import *
from obserwacja import *
from stale import *
class PoleKraty:
def __init__(self, Krata, wiersz, kolumna):
self.krata = Krata
gora: any
start: any
def __init__(self, krata, wiersz, kolumna):
self.krata = krata
self.bok = self.krata.bokPola
self._wiersz = wiersz
self._kolumna = kolumna
@ -40,7 +44,9 @@ class PoleKraty:
return PoleKraty(self.krata, self.wiersz, self.kolumna)
class Krata:
class Krata(Obserwowany):
krata: []
def __init__(self, okno):
self.okno = okno
self.liczbaPolPoziomo = LICZBA_POL_W_POZIOMIE
@ -56,21 +62,8 @@ class Krata:
self.krata.append([])
for kolumna in range(self.liczbaPolPoziomo):
zawartosc_pola = ZawartoscPola.PUSTE
# ZROBIC sciany
# if wiersz in (0, self.liczbaPolPionowo - 1) or kolumna in (0, self.liczbaPolPoziomo - 1):
# zawartosc_pola = ZawartoscPola.SCIANA
# if wiersz in range(6,18) and kolumna in (5,15,25,35):
# zawartosc_pola = ZawartoscPola.SCIANA
# if wiersz in (4,22) and kolumna in range (10,35):
# zawartosc_pola = ZawartoscPola.SCIANA
self.krata[wiersz].append(zawartosc_pola)
def wyswietlKrate(self):
self.narysujKrate()
# self.narysujKrateAlternatywnie()
# self.narysujAgenta()
pygame.display.update()
def narysujKrate(self):
self.okno.fill(SZARY1)
for wiersz in range(self.liczbaPolPionowo):
@ -82,18 +75,12 @@ class Krata:
def narysujKrateAlternatywnie(self):
self.okno.fill(SZARY1)
# for i in range(stale.NUMBER_OF_BLOCKS_WIDE):
# new_height = round(i * BLOCK_HEIGHT)
# new_width = round(i * BLOCK_HEIGHT)
# pygame.draw.line(surface, BLACK, (0, new_height), (SZEROKOSC_OKNA, new_height), 2)
# pygame.draw.line(surface, BLACK, (new_width, 0), (new_width, WYSOKOSC_OKNA), 2)
for i in range(LICZBA_POL_W_POZIOMIE + 1):
new_height = i * (BOK_POLA + ODSTEP_MIEDZY_POLAMI)
new_width = i * (BOK_POLA + ODSTEP_MIEDZY_POLAMI)
pygame.draw.line(self.okno, CZARNY, (0, new_height), (SZEROKOSC_OKNA, new_height), ODSTEP_MIEDZY_POLAMI)
pygame.draw.line(self.okno, CZARNY, (new_width, 0), (new_width, WYSOKOSC_OKNA), ODSTEP_MIEDZY_POLAMI)
# def narysujAgenta(self):
# if self.agent is not None:
# self.okno.blit(self.agent.tekstura, (self.agent.hitbox.x, self.agent.hitbox.y))
# self.agent.ruszSie()
def powiadomObserwatorow(self):
for obserwator in self.obserwatorzy:
obserwator.odbierzPowiadomienie(self)

95
main.py
View File

@ -1,81 +1,92 @@
import os
from agent import *
from okno import *
from ramy_czyli_wiedza_agenta import *
# aby działalo w oknie + rozdzielczość ekranu
# ctypes.windll.shcore.SetProcessDpiAwareness(1)
Okno = pygame.display.set_mode((SZEROKOSC_OKNA, WYSOKOSC_OKNA))
okno_pygame = pygame.display.set_mode((SZEROKOSC_OKNA, WYSOKOSC_OKNA))
pygame.display.set_caption("Okno1")
Krata = Krata(Okno)
krata_magazynu = Krata(okno_pygame)
Pomieszczenie = Pomieszczenie(WarunkiPowietrza(0, 0), 0)
def dodaj_agenta():
# pole_lewe_gorne = PoleKraty(Krata, random.randint(0, LICZBA_POL_W_PIONIE - BOK_AGENTA1_W_POLACH),
# pole_lewe_gorne = PoleKraty(krata_magazynu, random.randint(0, LICZBA_POL_W_PIONIE - BOK_AGENTA1_W_POLACH),
# random.randint(0, LICZBA_POL_W_POZIOMIE - BOK_AGENTA1_W_POLACH))
# pole_lewe_gorne = PoleKraty(Krata, LICZBA_POL_W_PIONIE - BOK_AGENTA1_W_POLACH, int(LICZBA_POL_W_POZIOMIE / 2))
pole_lewe_gorne = PoleKraty(Krata, 0, 0)
# pole_lewe_gorne = PoleKraty(krata_magazynu, LICZBA_POL_W_PIONIE - BOK_AGENTA1_W_POLACH, int(LICZBA_POL_W_POZIOMIE / 2))
pole_lewe_gorne = PoleKraty(krata_magazynu, 0, 0)
pom = 'traktor_ikona.png'
ikona = pygame.transform.scale(pygame.image.load(os.path.join('Ikony', pom)),
(BOK_AGENTA1, BOK_AGENTA1))
Agent(Krata, pole_lewe_gorne, ikona)
Agent(krata_magazynu, pole_lewe_gorne, ikona)
# zawsze na poczatku polnoc
Krata.agent.kierunek = Kierunek.POLNOC
krata_magazynu.agent.kierunek = Kierunek.POLNOC
def dodaj_szafke(numerSzafki, iloscPolek, iloscMiejscNaPolce, dostepZeStrony, poczatek_wiersz, poczatek_kolumna):
wymiary_szafki = Wymiary(0, 0, 0)
szafka = Szafka(numerSzafki, wymiary_szafki, iloscPolek, iloscMiejscNaPolce, dostepZeStrony, poczatek_wiersz,
poczatek_kolumna, Krata)
poczatek_kolumna, krata_magazynu)
Pomieszczenie.dodajSzafke(szafka)
def losowy_cel():
kierunek = Kierunek(random.randint(0, 3))
wiersz = random.randint(-1, Krata.liczbaPolPionowo - 1)
kolumna = random.randint(-1, Krata.liczbaPolPoziomo - 1)
Krata.krata[wiersz][kolumna] = ZawartoscPola.CEL
return Stan(kierunek, PoleKraty(Krata, wiersz, kolumna))
wiersz = random.randint(0, krata_magazynu.liczbaPolPionowo - 1)
kolumna = random.randint(0, krata_magazynu.liczbaPolPoziomo - 1)
return Stan(kierunek, PoleKraty(krata_magazynu, wiersz, kolumna))
def zaznacz_cel_na_mapie(cel: Stan):
wiersz = cel.poleStartoweGorne.wiersz
kolumna = cel.poleStartoweGorne.kolumna
if krata_magazynu.krata[wiersz][kolumna] == ZawartoscPola.PUSTE:
krata_magazynu.krata[wiersz][kolumna] = ZawartoscPola.CEL
def nadaj_cel_agentowi(agent: Agent):
agent.cel = losowy_cel()
zaznacz_cel_na_mapie(agent.cel)
print("CEL:", agent.cel.poleStartoweGorne.wiersz, agent.cel.poleStartoweGorne.kolumna)
def main():
dodaj_szafke("A", 2, 12, "P", 2, 2)
dodaj_szafke("B", 2, 12, "L", 2, 3)
dodaj_szafke("C", 2, 5, "P", 1, 6)
dodaj_szafke("D", 2, 6, "L", 1, 7)
dodaj_szafke("C", 2, 4, "P", 9, 6)
dodaj_szafke("D", 2, 3, "L", 10, 7)
dodaj_szafke("E", 2, 8, "P", 3, 11)
dodaj_szafke("F", 2, 10, "L", 2, 13)
dodaj_szafke("H", 2, 12, "L", 1, 18)
dodaj_szafke("I", 2, 7, "P", 5, 23)
dodaj_szafke("J", 2, 12, "L", 1, 25)
dodaj_szafke("G", 2, 10, "P", 5, 29)
# dla kraty 30 x 15
# dodaj_szafke("A", 2, 12, "P", 2, 2)
# dodaj_szafke("B", 2, 12, "L", 2, 3)
# dodaj_szafke("C", 2, 5, "P", 1, 6)
# dodaj_szafke("D", 2, 6, "L", 1, 7)
# dodaj_szafke("C", 2, 4, "P", 9, 6)
# dodaj_szafke("D", 2, 3, "L", 10, 7)
# dodaj_szafke("E", 2, 8, "P", 3, 11)
# dodaj_szafke("F", 2, 10, "L", 2, 13)
# dodaj_szafke("H", 2, 12, "L", 1, 18)
# dodaj_szafke("I", 2, 7, "P", 5, 23)
# dodaj_szafke("J", 2, 12, "L", 1, 25)
# dodaj_szafke("G", 2, 10, "P", 5, 29)
# dla kraty 10 x 10
dodaj_szafke("A", 1, 8, "P", 1, 1)
dodaj_szafke("B", 1, 8, "L", 1, 4)
dodaj_szafke("C", 1, 8, "P", 1, 6)
dodaj_szafke("C", 1, 8, "P", 1, 8)
dodaj_agenta()
# Krata.wyswietlKrate()
klatkaz = pygame.time.Clock()
warunek_dzialania = True
while warunek_dzialania:
klatkaz.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
warunek_dzialania = False
break
okno1 = Okno(krata_magazynu, krata_magazynu.agent)
okno1.wyswietlOkno()
while True:
# cel to Stan (pole kraty gdzie ma stać agent, aby położyć paczkę na półkę, w obiekcie klasy Miejsce jest to artybut dostęp + kierunek <-na razie niepotrzebny)
if Krata.agent.cel is None:
Krata.agent.cel = losowy_cel()
Krata.krata[Krata.agent.cel.poleStartoweGorne.wiersz][
Krata.agent.cel.poleStartoweGorne.kolumna] = ZawartoscPola.CEL
print("CEL:", Krata.agent.cel.poleStartoweGorne.wiersz, Krata.agent.cel.poleStartoweGorne.kolumna)
Krata.agent.idzDoCelu(klatkaz)
pygame.quit()
if krata_magazynu.agent.cel is None:
nadaj_cel_agentowi(krata_magazynu.agent)
krata_magazynu.agent.idzDoCelu()
try:
main()
except pygame.error:
pygame.quit()

31
obserwacja.py Normal file
View File

@ -0,0 +1,31 @@
# https://refactoring.guru/pl/design-patterns/observer/python/example
from __future__ import annotations
from abc import ABC, abstractmethod
class Obserwowany(ABC):
obserwatorzy = []
def dolaczObserwatora(self, obserwator: Obserwator):
self.obserwatorzy.append(obserwator)
def odlaczObserwatora(self, obserwator: Obserwator):
self.obserwatorzy.remove(obserwator)
@abstractmethod
def powiadomObserwatorow(self):
"""
Notify all observers about an event.
"""
pass
class Obserwator(ABC):
@abstractmethod
def odbierzPowiadomienie(self, obserwowany: Obserwowany):
"""
Receive update from subject.
"""
pass

23
okno.py Normal file
View File

@ -0,0 +1,23 @@
from krata import *
class Okno(Obserwator):
def __init__(self, krata, agent):
self.krata = krata
self.agent = agent
self.krata.dolaczObserwatora(self)
self.agent.dolaczObserwatora(self)
self.klatkaz = pygame.time.Clock()
def wyswietlOkno(self):
self.klatkaz.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
# print("Użytkownik spróbował zamknąć okno.")
pygame.quit()
self.krata.narysujKrate()
self.agent.narysujAgenta()
pygame.display.update()
def odbierzPowiadomienie(self, obserwowany: Obserwowany):
self.wyswietlOkno()

View File

@ -9,6 +9,8 @@ class Wymiary:
class Mapa:
mapa: []
def __init__(self):
self.liczbaPolPoziomo = LICZBA_POL_W_POZIOMIE
self.liczbaPolPionowo = LICZBA_POL_W_PIONIE
@ -18,13 +20,13 @@ class Mapa:
self.agent = None
def utworzPustaMape(self):
self.krata = []
self.mapa = []
for wiersz in range(self.liczbaPolPionowo):
self.krata.append([])
self.mapa.append([])
for kolumna in range(self.liczbaPolPoziomo):
zawartosc_pola = ZawartoscPola.PUSTE
nowe_pole = PoleMapy(self, wiersz, kolumna, zawartosc_pola)
self.krata[wiersz].append(nowe_pole)
self.mapa[wiersz].append(nowe_pole)
class PoleMapy:
@ -61,7 +63,7 @@ class Miejsce: # wcześniej półka
class Szafka:
def __init__(self, numerSzafki, wymiary: Wymiary, iloscPolek, iloscMiejscNaPolce, dostepZeStrony, poczatek_kolumna,
poczatek_wiersz1, Krata: Krata):
poczatek_wiersz1, krata: Krata):
self.numerSzafki = numerSzafki
self.wymiary = wymiary
self.iloscPolek = iloscPolek
@ -70,7 +72,7 @@ class Szafka:
self.Miejsca = []
self.zajmowanePola = []
self.utworzPustaSzafke(numerSzafki, iloscPolek, iloscMiejscNaPolce, dostepZeStrony, poczatek_kolumna,
poczatek_wiersz1, Krata)
poczatek_wiersz1, krata)
def dodajMiejsce(self, miejsce: Miejsce):
self.Miejsca.append(miejsce)
@ -79,7 +81,7 @@ class Szafka:
self.zajmowanePola.append(pole)
def utworzPustaSzafke(self, numerSzafki, iloscPolek, iloscMiejscNaPolce, dostepZeStrony, poczatek_wiersz1,
poczatek_kolumna, Krata: Krata):
poczatek_kolumna, krata: Krata):
for i in range(iloscPolek):
for j in range(iloscMiejscNaPolce):
wymiar_miejsca = Wymiary(0, 0, 0)
@ -89,16 +91,16 @@ class Szafka:
for m in range(DUZA_SZAFA): # wiersz
poczatek_wiersz = poczatek_wiersz1 + j * DUZA_SZAFA + m
for n in range(DUZA_SZAFA): # kolumna
Krata.krata[poczatek_wiersz][poczatek_kolumna + n] = ZawartoscPola.SCIANA
pole = PoleKraty(Krata, poczatek_wiersz, poczatek_kolumna + n)
krata.krata[poczatek_wiersz][poczatek_kolumna + n] = ZawartoscPola.SCIANA
pole = PoleKraty(krata, poczatek_wiersz, poczatek_kolumna + n)
miejsce.dodajPole(pole)
self.dodajPole(pole)
if dostepZeStrony == "L":
pole_dostepu = PoleKraty(Krata, poczatek_wiersz,
pole_dostepu = PoleKraty(krata, poczatek_wiersz,
poczatek_kolumna + n - BOK_AGENTA1_W_POLACH) # dostęp z lewej strony
miejsce.dodajDostep(pole_dostepu)
elif dostepZeStrony == "P":
pole_dostepu = PoleKraty(Krata, poczatek_wiersz,
pole_dostepu = PoleKraty(krata, poczatek_wiersz,
poczatek_kolumna + n + BOK_AGENTA1_W_POLACH) # dostęp z prawej strony strony
miejsce.dodajDostep(pole_dostepu)
self.dodajMiejsce(miejsce)

View File

@ -1,10 +1,10 @@
FPS = 5
FPS = 10
#
# SZEROKOSC_OKNA = 1500
# WYSOKOSC_OKNA = 750
#
LICZBA_POL_W_POZIOMIE = 30
LICZBA_POL_W_PIONIE = 15
LICZBA_POL_W_POZIOMIE = 10
LICZBA_POL_W_PIONIE = 10
BOK_POLA = 45
ODSTEP_MIEDZY_POLAMI = 1
SZEROKOSC_OKNA = LICZBA_POL_W_POZIOMIE * (BOK_POLA + ODSTEP_MIEDZY_POLAMI) + ODSTEP_MIEDZY_POLAMI