175 lines
5.1 KiB
Python
175 lines
5.1 KiB
Python
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
|