from enum import Enum from typing import Tuple, Dict class GridCellType(Enum): NOTHING = 0 REGAL = 1 # dodać oznaczenie na miejsce dla paczek class SearchSpace: grid: Dict[Tuple[int, int], GridCellType] = {} def __init__(self) -> None: self._init_grid() def _init_grid(self) -> None: for i in range (0,10): for j in range(0,10): self.grid[(i, j)] = GridCellType.NOTHING for r, c in [(2,2), (2,3), (3,2), (3,3), (8,2), (8,3), (9,2), (9,3), (2,8), (2,9), (3,8), (3,9), (8,8), (8,9), (9,8), (9,9)]: self.grid[(r,c)] = GridCellType.REGAL class Stan: def __init__(self, x, y, kierunek): self.x = x self.y = y self.kierunek = kierunek class Wezel: def __init__(self, stan: Stan, action = None, parent = None): self.stan = stan self.action = action self.parent = parent class Search: def __init__(self, points_grid: SearchSpace): self.points_grid = points_grid def wyszukiwanie_bfs(self, stan_poczatkowy: Stan, stan_docelowy: Stan): pierwszy_wezel = Wezel(stan_poczatkowy) fringe = [pierwszy_wezel] odwiedzone = [] while fringe: wezel = fringe.pop(0) if self.goal_test(state = wezel.stan, goal_state = stan_docelowy): return self.get_actions(wezel) odwiedzone.append(wezel.stan) for action, stan in self.nastepnik(wezel): if wezel not in fringe and stan not in odwiedzone: x_node = Wezel(stan, action, wezel) fringe.append(x_node) return False def goal_test(self, state: Stan, goal_state: Stan): if state.x == goal_state.x and state.y == goal_state.y: return True else: return False def nastepnik(self, wezel: Wezel): # gora -> prawo -> dol -> lewo | obrot w prawo # gora -> lewo -> dol -> prawo | obrot w lewo # 0 gora 1 prawo 2 dol 3 lewo state = wezel.stan right_state = Stan( state.x, state.y,(state.kierunek + 1) % 4) right_node = ["Right", right_state] # 90 degree left state - cost of turn is 1 left_state = Stan (state.x, state.y,3 if state.kierunek == 0 else state.kierunek - 1) # storing temporarily node as list left_node = ["Left", left_state] # always two nodes are possible because we can turn in both sides nodes = [right_node, left_node] y = state.x x = state.y # obrot_w_prawo = Stan(x, y, (wezel.stan.kierunek + 1) % 4) # obrot_w_lewo = Stan(x, y, (wezel.stan.kierunek - 1) % 4) if wezel.stan.kierunek == 0: y -= 1 elif wezel.stan.kierunek == 1: x += 1 elif wezel.stan.kierunek == 2: y += 1 elif wezel.stan.kierunek == 3: x -= 1 place = None if 0 <= y < 98 and 0 <= x < 98: place = self.points_grid.grid[(y,x)] if place is not None and place is GridCellType.NOTHING: ruch_w_przod = Stan(y, x, wezel.stan.kierunek) forward_node = ["Forward", ruch_w_przod] nodes.append(forward_node) # sprawdzenie czy nie wyjdzie poza plansze # if 0 <= x <= 916 and 0 <= y <= 916: # wezly.append(ruch_w_przod) return nodes def get_actions(self, wezel: Wezel): actions = [] moves_forward = 0 turns = 0 parent = wezel while True: action = parent.action parent = parent.parent if action is None: break if action == "Forward": moves_forward = moves_forward + 1 else: turns = turns + 1 actions.append(action) actions.reverse() return actions # class Kierunek(Enum): # POLNOC = 0 # POLUDNIE = 1 # ZACHOD = 2 # WSCHOD = 3 # def kierunekNaLewo(self): # if self == Kierunek.POLNOC: # return Kierunek.ZACHOD # elif self == Kierunek.POLUDNIE: # return Kierunek.WSCHOD # elif self == Kierunek.ZACHOD: # return Kierunek.POLUDNIE # elif self == Kierunek.WSCHOD: # return Kierunek.POLNOC # def kierunekNaPrawo(self): # if self == Kierunek.POLNOC: # return Kierunek.WSCHOD # elif self == Kierunek.POLUDNIE: # return Kierunek.ZACHOD # elif self == Kierunek.ZACHOD: # return Kierunek.POLNOC # elif self == Kierunek.WSCHOD: # return Kierunek.POLUDNIE # class Akcja(Enum): # OBROT_W_LEWO = 0 # OBROT_W_PRAWO = 1 # KROK_W_PRZOD = 2 # class Stan: # def __init__(self, kierunek: Kierunek, x, y): # self.x = x # self.y = y # self.kierunek = kierunek # def skopiuj(self): # return Stan(self.x, self.y, self.kierunek) # class Nastepnik: # def __init__(self, akcja: Akcja or None, 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 goaltest(stan: Stan, cel: Stan): # if stan.x != cel.x: # return False # elif stan.y != cel.y: # return False # else: # return True # 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 stan_w_liscie_nastepnikow(stan: Stan, lista_nastepnikow): # for i in lista_nastepnikow: # if i.stan.kierunek != stan.kierunek: # continue # elif i.stan.x != stan.x: # continue # elif i.stan.y != stan.y: # continue # else: # return True # return False # def nastepnik_kroku_w_przod(nastepnik: Nastepnik): # akcja = Akcja.KROK_W_PRZOD # stan = Stan(nastepnik.stan.kierunek, nastepnik.stan.x, nastepnik.stan.y) # if stan.kierunek == Kierunek.POLNOC: # stan.x -= 1 # elif stan.kierunek == Kierunek.POLUDNIE: # stan.x += 1 # elif stan.kierunek == Kierunek.ZACHOD: # stan.y -= 1 # elif stan.kierunek == Kierunek.WSCHOD: # stan.y += 1 # return Nastepnik(akcja, stan, nastepnik) # def nastepnik_obrotu_w_lewo(nastepnik: Nastepnik): # akcja = Akcja.OBROT_W_LEWO # stan = Stan(nastepnik.stan.kierunek.kierunekNaLewo(), nastepnik.stan.x, nastepnik.stan.y) # return Nastepnik(akcja, stan, nastepnik) # #Nastepnik(Akcja.OBROT_W_LEWO, Stan(nastepnik.stan.kierunek.kierunekNaLewo(), nastepnik.stan.poleStartoweGorne), nastepnik) # # # def nastepnik_obrotu_w_prawo(nastepnik: Nastepnik): # akcja = Akcja.OBROT_W_PRAWO # stan = Stan(nastepnik.stan.kierunek.kierunekNaPrawo(),nastepnik.stan.x, nastepnik.stan.y) # return Nastepnik(akcja, stan, nastepnik) # def succ(nastepnik: Nastepnik): # wynik = [] # pom = nastepnik.skopiuj() # #wynik.append(nastepnik_obrotu_w_lewo(pom)) # wynik.append(nastepnik_obrotu_w_lewo(pom)) # pom = nastepnik.skopiuj() # wynik.append(nastepnik_obrotu_w_prawo(pom)) # pom = nastepnik.skopiuj() # wynik.append(nastepnik_kroku_w_przod(pom)) # return wynik # 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, fringe) and not stan_w_liscie_nastepnikow(nastepnik, explored): # fringe.append(nastepnik) # return False