2023-05-05 02:56:22 +02:00
|
|
|
from .obj.TemporaryState import TemporaryState
|
2023-05-14 14:23:37 +02:00
|
|
|
from queue import PriorityQueue
|
2023-05-05 02:56:22 +02:00
|
|
|
|
|
|
|
|
|
|
|
class StateController:
|
|
|
|
def __init__(self, istate):
|
|
|
|
self.path = []
|
|
|
|
self.explored = []
|
2023-05-14 14:23:37 +02:00
|
|
|
self.fringe = PriorityQueue()
|
2023-05-05 02:56:22 +02:00
|
|
|
self.istate = istate
|
2023-05-14 14:23:37 +02:00
|
|
|
self.goal = istate.position
|
2023-05-05 02:56:22 +02:00
|
|
|
|
|
|
|
def reset(self):
|
|
|
|
self.path.clear()
|
|
|
|
self.explored.clear()
|
2023-05-14 14:23:37 +02:00
|
|
|
self.fringe = PriorityQueue()
|
2023-05-05 02:56:22 +02:00
|
|
|
|
2023-06-01 17:45:01 +02:00
|
|
|
def build_path(self, goal_state, engine):
|
2023-05-14 14:23:37 +02:00
|
|
|
total_cost = goal_state.cost
|
2023-05-05 02:56:22 +02:00
|
|
|
self.path.append(goal_state)
|
2023-06-01 17:45:01 +02:00
|
|
|
engine.goals.pop()
|
2023-05-26 03:02:16 +02:00
|
|
|
while self.path[-1].parent.agent_role not in ["blank", "waiter"]:
|
2023-05-05 02:56:22 +02:00
|
|
|
self.path.append(self.path[-1].parent)
|
2023-05-14 14:23:37 +02:00
|
|
|
total_cost += self.path[-1].cost
|
2023-05-05 02:56:22 +02:00
|
|
|
|
2023-05-14 14:23:37 +02:00
|
|
|
print("Total path cost:\t{0}".format(total_cost))
|
2023-05-05 02:56:22 +02:00
|
|
|
return self.path
|
|
|
|
|
2023-05-14 14:23:37 +02:00
|
|
|
def graphsearch(self, engine): # A*
|
2023-05-05 02:56:22 +02:00
|
|
|
print("Search path")
|
|
|
|
|
2023-06-01 17:45:01 +02:00
|
|
|
self.goal = list(engine.goals[-1].position)
|
2023-05-14 14:23:37 +02:00
|
|
|
|
2023-05-05 02:56:22 +02:00
|
|
|
self.reset()
|
|
|
|
|
2023-05-14 14:23:37 +02:00
|
|
|
start = TemporaryState(self.istate, 0)
|
|
|
|
|
|
|
|
self.fringe.put(start)
|
2023-05-05 02:56:22 +02:00
|
|
|
|
2023-06-01 17:45:01 +02:00
|
|
|
while self.fringe.queue and not self.path:
|
2023-05-14 14:23:37 +02:00
|
|
|
self.explored.append(self.fringe.get())
|
2023-06-01 17:45:01 +02:00
|
|
|
if self.goal_test(engine):
|
|
|
|
return
|
2023-05-05 02:56:22 +02:00
|
|
|
|
|
|
|
self.succ(self.explored[-1].front(), engine)
|
|
|
|
self.succ(self.explored[-1].left(), engine)
|
|
|
|
self.succ(self.explored[-1].right(), engine)
|
|
|
|
|
|
|
|
engine.redraw()
|
|
|
|
|
|
|
|
self.reset()
|
2023-06-01 17:45:01 +02:00
|
|
|
for o in engine.objects:
|
|
|
|
o.compare_pos(engine.goals[-1].position)
|
|
|
|
o.agent_role = "block"
|
|
|
|
engine.goals.pop()
|
2023-05-05 02:56:22 +02:00
|
|
|
|
|
|
|
print("Not found")
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
def succ(self, state, engine):
|
|
|
|
if state.collide_test():
|
|
|
|
return
|
|
|
|
elif any(e.compare(state) for e in self.explored):
|
|
|
|
return
|
|
|
|
elif any([o.collide_test(state) for o in engine.objects]):
|
|
|
|
return
|
|
|
|
|
2023-05-14 14:23:37 +02:00
|
|
|
for o in engine.objects:
|
|
|
|
if state.cost != 1:
|
|
|
|
break
|
|
|
|
if o.position == state.position:
|
|
|
|
state.change_cost(o)
|
|
|
|
|
|
|
|
state.cost_so_far = self.explored[-1].cost_so_far + state.cost
|
|
|
|
|
|
|
|
in_explored = any([state.compare(s) for s in self.explored]
|
|
|
|
)
|
|
|
|
|
|
|
|
in_frige = any([state.compare(f) for f in self.fringe.queue])
|
|
|
|
|
|
|
|
if not in_explored and not in_frige:
|
|
|
|
state.heuristic(self.goal)
|
|
|
|
self.fringe.put(state)
|
|
|
|
|
|
|
|
elif in_frige:
|
|
|
|
fringe = state
|
|
|
|
for f in self.fringe.queue:
|
|
|
|
if state.compare(f):
|
|
|
|
fringe = f
|
|
|
|
break
|
|
|
|
|
|
|
|
if state.cost_so_far < fringe.cost_so_far:
|
|
|
|
fringe.replace(state)
|
2023-06-01 17:45:01 +02:00
|
|
|
|
|
|
|
def goal_test(self, engine) -> bool:
|
|
|
|
if self.explored[-1].position == self.goal:
|
|
|
|
self.__is_goal__(self.explored[-1], engine)
|
|
|
|
return True
|
|
|
|
|
|
|
|
for fringe in self.fringe.queue:
|
|
|
|
if fringe.position == self.goal:
|
|
|
|
self.__is_goal__(fringe, engine)
|
|
|
|
return True
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
def __is_goal__(self, goal_state, engine):
|
|
|
|
self.reset()
|
|
|
|
self.build_path(goal_state, engine)
|