Inteligentny_Wozek/wyszukiwanie.py
2023-05-06 12:57:48 +02:00

282 lines
8.3 KiB
Python

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