Traktor/source/bfs.py
2024-06-09 22:09:36 +02:00

208 lines
5.9 KiB
Python

from area.constants import TILE_SIZE
import copy
from area.tractor import Tractor
class Istate:
def __init__(self, x, y, direction ):
self.x = x
self.y = y
self.direction = direction
def get_x(self):
return self.x
def set_x(self, _x):
self.x = _x
def get_y(self):
return self.y
def set_y(self, _y):
self.y = _y
def get_direction(self):
return self.direction
def set_direction(self, _direction):
self.parent = _direction
class Node:
def __init__(self, x, y, direction, parent, action):
self.x = x
self.y = y
self.direction = direction
self.action = action
self.parent = parent
#getters and setters:
def get_parent(self):
return self.parent
def set_parent(self, _parent):
self.parent = _parent
def get_action(self):
return self.action
def set_action(self, _action):
self.parent = _action
def get_x(self):
return self.x
def set_x(self, _x):
self.x = _x
def get_y(self):
return self.y
def set_y(self, _y):
self.y = _y
def get_direction(self):
return self.direction
def set_direction(self, _direction):
self.parent = _direction
def copy(self):
return copy.copy(self)
def goal_test(elem, goalstate):
if elem.get_x() == goalstate[0] and elem.get_y() == goalstate[1]:
return True
else:
return False
#State as a tuple (x,y,direction)
#actions(string): move, rotate_to_left, rotate_to_right
#main search function:
def graphsearch(istate, succ, goaltest, tractor):
fringe = []
explored = []
node = Node(istate.get_x(), istate.get_y(), istate.get_direction(), None, None)
fringe.append(node)
while True:
if not fringe:
return False
elem = fringe.pop(0)
temp = copy.copy(elem)
if goal_test(elem, goaltest) is True: #jesli True zwroc ciag akcji
return get_moves(elem)
explored.append(elem)
for (action, state) in succ(temp, tractor): #dla wszystkich mozliwych stanow i akcjach otrzymanych dla danego wierzcholka
fringe_tuple = []
explored_tuple = []
for node in fringe:
fringe_tuple.append((node.get_x(), node.get_y(), node.get_direction()))
for node in explored:
explored_tuple.append((node.get_x(), node.get_y(), node.get_direction()))
if state not in fringe_tuple and state not in explored_tuple:
x = Node(state[0], state[1], state[2], elem, action)
fringe.append(x)
#funkcja nastepnika - jakie akcje sa mozlwie na danym polu i jaki bedzie stan po wykonaniu tych akcji
def succ(elem, tractor):
actions_states = []
temp = copy.copy(elem.get_direction())
if temp == 1:
temp = 4
else:
temp -= 1
actions_states.append(("rotate_left", (elem.get_x(), elem.get_y(), temp)))
temp = copy.copy(elem.get_direction())
if temp == 4:
temp = 1
else:
temp += 1
actions_states.append(("rotate_right", (elem.get_x(), elem.get_y(), temp)))
temp_move_east = elem.get_x() + TILE_SIZE
temp_move_west = elem.get_x() - TILE_SIZE
temp_move_north = elem.get_y() - TILE_SIZE
temp_move_south = elem.get_y() + TILE_SIZE
if Tractor.can_it_move_node(elem) == "move east" and not Tractor.is_obstacle(tractor, temp_move_east, elem.get_y()):
actions_states.append(("move", (temp_move_east, elem.get_y(), elem.get_direction())))
elif Tractor.can_it_move_node(elem) == "move west" and not Tractor.is_obstacle(tractor, temp_move_west, elem.get_y()):
actions_states.append(("move", (temp_move_west, elem.get_y(), elem.get_direction())))
elif Tractor.can_it_move_node(elem) == "move north" and not Tractor.is_obstacle(tractor,elem.get_x(), temp_move_north):
actions_states.append(("move", (elem.get_x(), temp_move_north, elem.get_direction())))
elif Tractor.can_it_move_node(elem) == "move south" and not Tractor.is_obstacle(tractor, elem.get_x(), temp_move_south):
actions_states.append(("move", (elem.get_x(), temp_move_south, elem.get_direction())))
return actions_states
#its the copy of successor function for A* only - tractor can ride through stones if there is no other way:
def succ_astar(elem):
actions_states = []
temp = copy.copy(elem.get_direction())
if temp == 1:
temp = 4
else:
temp -= 1
actions_states.append(("rotate_left", (elem.get_x(), elem.get_y(), temp)))
temp = copy.copy(elem.get_direction())
if temp == 4:
temp = 1
else:
temp += 1
actions_states.append(("rotate_right", (elem.get_x(), elem.get_y(), temp)))
temp_move_east = elem.get_x() + TILE_SIZE
temp_move_west = elem.get_x() - TILE_SIZE
temp_move_north = elem.get_y() - TILE_SIZE
temp_move_south = elem.get_y() + TILE_SIZE
if Tractor.can_it_move_node(elem) == "move east":
actions_states.append(("move", (temp_move_east, elem.get_y(), elem.get_direction())))
elif Tractor.can_it_move_node(elem) == "move west":
actions_states.append(("move", (temp_move_west, elem.get_y(), elem.get_direction())))
elif Tractor.can_it_move_node(elem) == "move north":
actions_states.append(("move", (elem.get_x(), temp_move_north, elem.get_direction())))
elif Tractor.can_it_move_node(elem) == "move south":
actions_states.append(("move", (elem.get_x(), temp_move_south, elem.get_direction())))
return actions_states
#returns list of actions
def get_moves(elem):
move_list = []
while (elem.get_parent() != None):
move_list.append(elem.get_action())
elem = elem.get_parent()
move_list.reverse()
return move_list