You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
2.5 KiB
90 lines
2.5 KiB
lines = open("input.txt", "r").read().splitlines()
|
|
|
|
relief = []
|
|
s = None
|
|
e = None
|
|
for i, line in enumerate(lines):
|
|
els = []
|
|
for j, letter in enumerate(line):
|
|
if letter == "S":
|
|
els.append(1)
|
|
s = (i, j)
|
|
elif letter == "E":
|
|
els.append(26)
|
|
e = (i, j)
|
|
else:
|
|
els.append(ord(letter) - 96)
|
|
relief.append(els)
|
|
|
|
|
|
class Node:
|
|
def __init__(self, x, y):
|
|
self.x = x
|
|
self.y = y
|
|
self.g = 999999
|
|
self.h = (e[0] - self.x) + (e[1] - self.y)
|
|
|
|
self.parent = None
|
|
|
|
def f(self):
|
|
return self.g + self.h
|
|
|
|
def get_children(self):
|
|
children = []
|
|
if self.x != 0 and relief[self.x][self.y] + 1 >= relief[self.x - 1][self.y]:
|
|
children.append(Node(self.x - 1, self.y))
|
|
if (
|
|
self.x != len(relief) - 1
|
|
and relief[self.x][self.y] + 1 >= relief[self.x + 1][self.y]
|
|
):
|
|
children.append(Node(self.x + 1, self.y))
|
|
if self.y != 0 and relief[self.x][self.y] + 1 >= relief[self.x][self.y - 1]:
|
|
children.append(Node(self.x, self.y - 1))
|
|
if (
|
|
self.y != len(relief[0]) - 1
|
|
and relief[self.x][self.y] + 1 >= relief[self.x][self.y + 1]
|
|
):
|
|
children.append(Node(self.x, self.y + 1))
|
|
return children
|
|
|
|
|
|
def a_star_search(start, goal):
|
|
start_node = Node(start[0], start[1])
|
|
start_node.g = 0
|
|
openSet = [start_node]
|
|
while len(openSet) > 0:
|
|
current_index, current_node = get_smallest_f(openSet)
|
|
if current_node.x == goal[0] and current_node.y == goal[1]:
|
|
return current_node.g
|
|
openSet.pop(current_index)
|
|
for child in current_node.get_children():
|
|
tentative_gScore = current_node.g + 1
|
|
if tentative_gScore < child.g:
|
|
child.parent = current_node
|
|
child.g = tentative_gScore
|
|
if not_in_set(child, openSet):
|
|
openSet.append(child)
|
|
return None
|
|
|
|
|
|
def get_smallest_f(openset):
|
|
smallest = 999999
|
|
smallest_node = None
|
|
smallest_idx = 99999
|
|
for idx, node in enumerate(openset):
|
|
if node.f() < smallest:
|
|
smallest = node.f()
|
|
smallest_node = node
|
|
smallest_idx = idx
|
|
return smallest_idx, smallest_node
|
|
|
|
|
|
def not_in_set(node, openset):
|
|
for n in openset:
|
|
if n.x == node.x and n.y == node.y:
|
|
return False
|
|
return True
|
|
|
|
|
|
print(a_star_search(s, e))
|