2024-04-20 14:47:25 +02:00
|
|
|
from area.constants import TILE_SIZE
|
2024-04-14 14:28:40 +02:00
|
|
|
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
|
2024-04-20 14:47:25 +02:00
|
|
|
|
|
|
|
|
|
|
|
#State as a tuple (x,y,direction)
|
2024-04-14 14:28:40 +02:00
|
|
|
|
|
|
|
#actions(string): move, rotate_to_left, rotate_to_right
|
|
|
|
|
|
|
|
#main search function:
|
2024-04-14 23:19:06 +02:00
|
|
|
def graphsearch(istate, succ, goaltest, tractor):
|
2024-04-14 14:28:40 +02:00
|
|
|
|
|
|
|
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)
|
|
|
|
|
2024-04-14 23:19:06 +02:00
|
|
|
for (action, state) in succ(temp, tractor): #dla wszystkich mozliwych stanow i akcjach otrzymanych dla danego wierzcholka
|
2024-04-14 14:28:40 +02:00
|
|
|
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
|
2024-04-14 23:19:06 +02:00
|
|
|
def succ(elem, tractor):
|
2024-04-14 14:28:40 +02:00
|
|
|
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
|
|
|
|
|
2024-04-14 23:19:06 +02:00
|
|
|
if Tractor.can_it_move_node(elem) == "move east" and not Tractor.is_obstacle(tractor, temp_move_east, elem.get_y()):
|
2024-04-14 14:28:40 +02:00
|
|
|
actions_states.append(("move", (temp_move_east, elem.get_y(), elem.get_direction())))
|
2024-04-14 23:19:06 +02:00
|
|
|
|
|
|
|
elif Tractor.can_it_move_node(elem) == "move west" and not Tractor.is_obstacle(tractor, temp_move_west, elem.get_y()):
|
2024-04-14 14:28:40 +02:00
|
|
|
actions_states.append(("move", (temp_move_west, elem.get_y(), elem.get_direction())))
|
2024-04-14 23:19:06 +02:00
|
|
|
|
|
|
|
elif Tractor.can_it_move_node(elem) == "move north" and not Tractor.is_obstacle(tractor,elem.get_x(), temp_move_north):
|
2024-04-14 14:28:40 +02:00
|
|
|
actions_states.append(("move", (elem.get_x(), temp_move_north, elem.get_direction())))
|
2024-04-14 23:19:06 +02:00
|
|
|
|
|
|
|
elif Tractor.can_it_move_node(elem) == "move south" and not Tractor.is_obstacle(tractor, elem.get_x(), temp_move_south):
|
2024-04-14 14:28:40 +02:00
|
|
|
actions_states.append(("move", (elem.get_x(), temp_move_south, elem.get_direction())))
|
2024-04-14 23:19:06 +02:00
|
|
|
|
2024-04-14 14:28:40 +02:00
|
|
|
return actions_states
|
|
|
|
|
2024-06-09 22:09:36 +02:00
|
|
|
|
|
|
|
#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())))
|
2024-04-14 14:28:40 +02:00
|
|
|
|
2024-06-09 22:09:36 +02:00
|
|
|
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
|
2024-04-14 14:28:40 +02:00
|
|
|
|
2024-04-20 14:47:25 +02:00
|
|
|
#returns list of actions
|
2024-04-14 14:28:40 +02:00
|
|
|
def get_moves(elem):
|
|
|
|
move_list = []
|
|
|
|
while (elem.get_parent() != None):
|
|
|
|
move_list.append(elem.get_action())
|
|
|
|
elem = elem.get_parent()
|
2024-04-14 15:05:20 +02:00
|
|
|
move_list.reverse()
|
|
|
|
return move_list
|
2024-04-14 14:28:40 +02:00
|
|
|
|