# Python Algorithm: Pt. 11: A*lgorithm.

Did I misspell the title? Hehe. No. Today, our subject is A*! Yay! Hooray! Now to the 0 viewers out there: I am going to explain it! In a video! Isn’t that just great!

Also check out a similar algorithm: https://chekailiang.medium.com/python-algorithm-pt-9-dijkstra-ea23635be325

Also bellman ford: https://chekailiang.medium.com/bellman-ford-df66f6932b4b

Excuse me? I still need to explain it in text? Sheesh…fine. Here you go….

First we need the start node and end node. This determines everything and is very important.

Basically, there is 3 values:

g cost: Distance from original tile

h cost: Distance from end tile

If we want to reach the end tile, the path we should take is the lowest f cost.

The f cost is g+h cost.

Think about it this way. You are trying to spend the least amount of energy. Let’s say the f cost is the energy.

If you were to walk to a house 2 meters in front of you, how will you satisfy your lazy legs? Walking forward 1 meter is 1 meter far from you (g cost) and 1 meter far from the house(h cost). However, walking right 1 meter is 1 meter far from you (g cost) and 3 meters far from the house(h cost). See the difference?

Now, lets add the g cost and h cost together. If you walk forward, the f cost is 2(1+1), while walking right is 4 (1+3). So logically, to spend the least f cost, we walk forward.

class Node():"""A node class for A* Pathfinding"""def __init__(self, parent=None, position=None):self.parent = parentself.position = positionself.g = 0self.h = 0self.f = 0def __eq__(self, other):return self.position == other.positiondef astar(maze, start, end):start_node = Node(None, start)start_node.g = start_node.h = start_node.f = 0end_node = Node(None, end)end_node.g = end_node.h = end_node.f = 0open_list = []closed_list = []open_list.append(start_node)while len(open_list) > 0:current_node = open_list[0]current_index = 0for index, item in enumerate(open_list):if item.f < current_node.f:current_node = itemcurrent_index = indexopen_list.pop(current_index)closed_list.append(current_node)if current_node == end_node:path = []current = current_nodewhile current is not None:path.append(current.position)current = current.parentreturn path[::-1]children = []for new_position in [(0, -1), (0, 1), (-1, 0), (1, 0), (-1, -1), (-1, 1), (1, -1), (1, 1)]:node_position = (current_node.position[0] + new_position[0], current_node.position[1] + new_position[1])if node_position[0] > (len(maze) - 1) or node_position[0] < 0 or node_position[1] > (len(maze[len(maze)-1]) -1) or node_position[1] < 0:continueif maze[node_position[0]][node_position[1]] != 0:continuenew_node = Node(current_node, node_position)children.append(new_node)for child in children:for closed_child in closed_list:if child == closed_child:continuechild.g = current_node.g + 1child.h = ((child.position[0] - end_node.position[0]) **2) + ((child.position[1] - end_node.position[1]) **2)child.f = child.g + child.hfor open_node in open_list:if child == open_node and child.g > open_node.g:continueopen_list.append(child)def main():maze = [[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],]start = 0, 0end = 7, 6path = astar(maze, start, end)print(path)if __name__ == '__main__':main()

Please ignore my face, I woke up very early and I am too tired to edit it out :3