diff --git a/Graphsearch.py b/Graphsearch.py new file mode 100644 index 0000000..6c173b7 --- /dev/null +++ b/Graphsearch.py @@ -0,0 +1,174 @@ +from operator import itemgetter + +import constants + + +class Istate: + def __init__(self, direction, horizontal_index, vertical_index): + self.__direction = direction + self.__horizontal_index = horizontal_index + self.__vertical_index = vertical_index + + @property + def direction(self): + return self.__direction + + @property + def horizontal_index(self): + return self.__horizontal_index + + @property + def vertical_index(self): + return self.__vertical_index + + +class Node: + def __init__(self, action, direction, parent, horizontal_index, vertical_index): + self.__action = action + self.__direction = direction + self.__parent = parent + self.__horizontal_index = horizontal_index + self.__vertical_index = vertical_index + + @property + def action(self): + return self.__action + + @property + def direction(self): + return self.__direction + + @property + def parent(self): + return self.__parent + + @property + def horizontal_index(self): + return self.__horizontal_index + + @property + def vertical_index(self): + return self.__vertical_index + + +def goal_test(elem, goaltest): + if elem.horizontal_index == goaltest[0] and elem.vertical_index == goaltest[1]: + return True + else: + # print("Traktor wartosc horizontal_index: ", elem.horizontal_index) + # print("Traktor wartosc vertical_index: ", elem.vertical_index) + return False + + +def print_moves(elem): + moves_list = [] + while elem.parent is not None: + moves_list.append(elem.action) + elem = elem.parent + moves_list.reverse() + return moves_list + + +def cost(board, node): + cost_value = 0 + while node.parent is not None: + field = board[node.horizontal_index][node.vertical_index] + cost_value = cost_value + field.cost + 1 + node = node.parent + return cost_value + + +def heuristic(node, goaltest): + return abs(node.horizontal_index - goaltest[0]) + abs(node.vertical_index - goaltest[1]) + + +def f(board, node, goaltest): + cost_value = cost(board, node) + return cost_value + heuristic(node, goaltest) + + +def succ(elem): + actions_list = [] + direction = elem.direction + if direction == "UP": + direction = "RIGHT" + elif direction == "RIGHT": + direction = "DOWN" + elif direction == "DOWN": + direction = "LEFT" + elif direction == "LEFT": + direction = "UP" + actions_list.append(("Right_Rotation", (direction, elem.horizontal_index, elem.vertical_index))) + + direction = elem.direction + if direction == "UP": + direction = "LEFT" + elif direction == "LEFT": + direction = "DOWN" + elif direction == "DOWN": + direction = "RIGHT" + elif direction == "RIGHT": + direction = "UP" + actions_list.append(("Left_Rotation", (direction, elem.horizontal_index, elem.vertical_index))) + + horizontal_change = 0 + vertical_change = 0 + + if elem.direction == "RIGHT" and elem.horizontal_index < constants.HORIZONTAL_TILES_NUMBER - 1: + horizontal_change = 1 + elif elem.direction == "LEFT" and elem.horizontal_index > 0: + horizontal_change = -1 + elif elem.direction == "UP" and elem.vertical_index > 0: + vertical_change = -1 + elif elem.direction == "DOWN" and elem.vertical_index < constants.VERTICAL_TILES_NUMBER - 1: + vertical_change = 1 + + actions_list.append(("Move", (elem.direction, elem.horizontal_index + horizontal_change, + elem.vertical_index + vertical_change))) + + return actions_list + + +def graphsearch(fringe, explored, istate, goaltest, board): + node = Node(None, istate.direction, None, istate.horizontal_index, istate.vertical_index) + fringe.append((node, 0)) + while True: + if not fringe: + return False + + elem = fringe.pop(0) + temp = elem[0] + + if goal_test(elem[0], goaltest) is True: + return print_moves(elem[0]) + + explored.append(elem) + + for (action, state) in succ(temp): + fringe_list = [] + fringe_list_priority = [] + explored_list = [] + + for (x, y) in fringe: + fringe_list.append((x.direction, x.horizontal_index, x.vertical_index)) + fringe_list_priority.append(((x.direction, x.horizontal_index, x.vertical_index), y)) + + for (x, y) in explored: + explored_list.append((x.direction, x.horizontal_index, x.vertical_index)) + + x = Node(action, state[0], elem[0], state[1], state[2]) + p = f(board, x, goaltest) + + if state not in fringe_list and state not in explored_list: + fringe.append((x, p)) + fringe = sorted(fringe, key=itemgetter(1)) + elif state in fringe_list: + index = 0 + for (state_priority, r) in fringe_list_priority: + if state_priority == state: + if r > p: + fringe.insert(index, (x, p)) + fringe.pop(index + 1) + fringe = sorted(fringe, key=itemgetter(1)) + break + index = index + 1