automatyczny_kelner/src/StateController.py

93 lines
2.5 KiB
Python
Raw Normal View History

from .obj.TemporaryState import TemporaryState
2023-05-14 14:23:37 +02:00
from queue import PriorityQueue
class StateController:
def __init__(self, istate):
self.path = []
self.explored = []
2023-05-14 14:23:37 +02:00
self.fringe = PriorityQueue()
self.istate = istate
2023-05-14 14:23:37 +02:00
self.goal = istate.position
def reset(self):
self.path.clear()
self.explored.clear()
2023-05-14 14:23:37 +02:00
self.fringe = PriorityQueue()
def build_path(self, goal_state):
2023-05-14 14:23:37 +02:00
total_cost = goal_state.cost
self.path.append(goal_state)
2023-05-14 14:23:37 +02:00
while self.path[-1].parent.agent_role != "blank":
self.path.append(self.path[-1].parent)
2023-05-14 14:23:37 +02:00
total_cost += self.path[-1].cost
2023-05-14 14:23:37 +02:00
print("Total path cost:\t{0}".format(total_cost))
return self.path
2023-05-14 14:23:37 +02:00
def graphsearch(self, engine): # A*
print("Search path")
2023-05-14 14:23:37 +02:00
self.goal = list(engine.goals.pop())
self.reset()
2023-05-14 14:23:37 +02:00
start = TemporaryState(self.istate, 0)
self.fringe.put(start)
2023-05-14 14:23:37 +02:00
while self.fringe and not self.path:
self.explored.append(self.fringe.get())
2023-05-14 14:23:37 +02:00
if self.explored[-1].position == self.goal:
goal_state = self.explored[-1]
self.reset()
return self.build_path(goal_state)
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()
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)