149 lines
4.5 KiB
Python
149 lines
4.5 KiB
Python
from collections import deque
|
|
|
|
from krata import *
|
|
|
|
|
|
class Akcja(Enum):
|
|
OBROT_W_LEWO = 0
|
|
OBROT_W_PRAWO = 1
|
|
KROK_W_PRZOD = 2
|
|
|
|
|
|
class Stan:
|
|
def __init__(self, kierunek: Kierunek, poleStartoweGorne: PoleKraty):
|
|
self.kierunek = kierunek
|
|
self.poleStartoweGorne = poleStartoweGorne
|
|
|
|
def skopiuj(self):
|
|
return Stan(self.kierunek, self.poleStartoweGorne.skopiuj())
|
|
|
|
|
|
class Nastepnik:
|
|
def __init__(self, akcja: Akcja, stan: Stan, poprzednik):
|
|
self.akcja = akcja
|
|
self.stan = stan
|
|
self._poprzednik = poprzednik
|
|
|
|
def getPoprzednik(self):
|
|
return self._poprzednik
|
|
|
|
def setPoprzednik(self, x):
|
|
raise Exception
|
|
|
|
poprzednik = property(getPoprzednik, setPoprzednik)
|
|
|
|
def skopiuj(self):
|
|
return Nastepnik(self.akcja, self.stan.skopiuj(), self.poprzednik)
|
|
|
|
|
|
def nastepnik_obrotu_w_lewo(nastepnik: Nastepnik):
|
|
akcja = Akcja.OBROT_W_LEWO
|
|
stan = Stan(nastepnik.stan.kierunek.kierunekNaLewo(), nastepnik.stan.poleStartoweGorne)
|
|
return Nastepnik(akcja, stan, nastepnik)
|
|
|
|
|
|
def nastepnik_obrotu_w_prawo(nastepnik: Nastepnik):
|
|
akcja = Akcja.OBROT_W_PRAWO
|
|
stan = Stan(nastepnik.stan.kierunek.kierunekNaPrawo(), nastepnik.stan.poleStartoweGorne)
|
|
return Nastepnik(akcja, stan, nastepnik)
|
|
|
|
|
|
def nastepnik_kroku_w_przod(nastepnik: Nastepnik):
|
|
akcja = Akcja.KROK_W_PRZOD
|
|
stan = Stan(nastepnik.stan.kierunek, nastepnik.stan.poleStartoweGorne)
|
|
if stan.kierunek == Kierunek.POLNOC:
|
|
stan.poleStartoweGorne.wiersz -= 1
|
|
elif stan.kierunek == Kierunek.POLUDNIE:
|
|
stan.poleStartoweGorne.wiersz += 1
|
|
elif stan.kierunek == Kierunek.ZACHOD:
|
|
stan.poleStartoweGorne.kolumna -= 1
|
|
elif stan.kierunek == Kierunek.WSCHOD:
|
|
stan.poleStartoweGorne.kolumna += 1
|
|
return Nastepnik(akcja, stan, nastepnik)
|
|
|
|
|
|
def pole_w_granicach_kraty(pole: PoleKraty):
|
|
if pole.wiersz not in range(0, pole.krata.liczbaPolPionowo):
|
|
return False
|
|
elif pole.kolumna not in range(0, pole.krata.liczbaPolPoziomo):
|
|
return False
|
|
else:
|
|
return True
|
|
|
|
|
|
def pole_puste(pole: PoleKraty):
|
|
if pole.krata.krata[pole.wiersz][pole.kolumna] in (ZawartoscPola.PUSTE, ZawartoscPola.CEL):
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
|
|
def mozna_zrobic_krok_w_przod(nastepnik: Nastepnik):
|
|
nastepnik = nastepnik_kroku_w_przod(nastepnik)
|
|
if pole_w_granicach_kraty(nastepnik.stan.poleStartoweGorne) and pole_puste(nastepnik.stan.poleStartoweGorne):
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
|
|
def succ(nastepnik: Nastepnik):
|
|
wynik = []
|
|
pom = nastepnik.skopiuj()
|
|
wynik.append(nastepnik_obrotu_w_lewo(pom))
|
|
pom = nastepnik.skopiuj()
|
|
wynik.append(nastepnik_obrotu_w_prawo(pom))
|
|
pom = nastepnik.skopiuj()
|
|
if mozna_zrobic_krok_w_przod(pom):
|
|
pom = nastepnik.skopiuj()
|
|
wynik.append(nastepnik_kroku_w_przod(pom))
|
|
return wynik
|
|
|
|
|
|
def goaltest(stan: Stan, cel: Stan):
|
|
if stan.poleStartoweGorne.wiersz != cel.poleStartoweGorne.wiersz:
|
|
return False
|
|
elif stan.poleStartoweGorne.kolumna != cel.poleStartoweGorne.kolumna:
|
|
return False
|
|
else:
|
|
return True
|
|
|
|
|
|
def stan_w_liscie_nastepnikow(stan: Stan, lista_nastepnikow):
|
|
for i in lista_nastepnikow:
|
|
if i.stan.kierunek != stan.kierunek:
|
|
continue
|
|
elif i.stan.poleStartoweGorne.wiersz != stan.poleStartoweGorne.wiersz:
|
|
continue
|
|
elif i.stan.poleStartoweGorne.kolumna != stan.poleStartoweGorne.kolumna:
|
|
continue
|
|
else:
|
|
return True
|
|
return False
|
|
|
|
|
|
def stos_akcji(stan_koncowy: Nastepnik):
|
|
stos = deque()
|
|
while stan_koncowy.poprzednik is not None:
|
|
stos.append(stan_koncowy.akcja)
|
|
stan_koncowy = stan_koncowy.poprzednik
|
|
return stos
|
|
|
|
|
|
def graphsearch(istate: Stan, cel: Stan):
|
|
fringe = deque()
|
|
explored = []
|
|
fringe.append(Nastepnik(None, istate, None))
|
|
while fringe:
|
|
# for i in fringe:
|
|
# print("F",i.stan.kierunek,i.stan.poleStartoweGorne.wiersz,i.stan.poleStartoweGorne.kolumna,end=" ")
|
|
# print()
|
|
element: Nastepnik = fringe.popleft()
|
|
if goaltest(element.stan, cel):
|
|
return stos_akcji(element)
|
|
explored.append(element)
|
|
for nastepnik in succ(element):
|
|
if not stan_w_liscie_nastepnikow(nastepnik.stan, fringe) and not stan_w_liscie_nastepnikow(nastepnik.stan,
|
|
explored):
|
|
fringe.append(nastepnik)
|
|
return False
|