A* and corrected graphsearch
This commit is contained in:
parent
5109d10d8c
commit
b12ed9bcda
174
Graphsearch.py
Normal file
174
Graphsearch.py
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user