text: import pygame, sys, math
  import Astar
  import blocks
  
  def main():
      
      screen = pygame.display.set_mode((width, height))
      Clock = pygame.time.Clock()
      grid_sprite_list = pygame.sprite.Group()
      
      def find_rect(x,y):
          # Input x,y coordinates x,y in [0, 24]
          # Returns Sprite object in grid group located at x,y in grid
          x_pos = 20*x
          y_pos = 20*y 
          for r in grid_sprite_list:
              if r.rect.x == x_pos and r.rect.y == y_pos:
                  return r
          return None
  
      def mouse_translate(cords):
          # Input raw mouse position
          # Output position in x,y coordniates on the grid, i.e (12, 102) -> (0, 100)
          x = cords[0] + 12 # Coords are offset by half of width of grids beause we meausre from top left corner of the mouse position.
          y = cords[1] + 12
  
          x = math.trunc(x / 20)
          y = math.trunc(y / 20) 
          
          # Edge cases because we start counting the grid from 0
          if x > 0:
              x -= 1
              
          if y > 0:
              y -= 1
          
          return (x,y)
  
      # Initiate grid 
      for i in range(int(width/20)):
          for j in range(int(height/20)):
              grid_sprite_list.add(grid(i*20, j*20))
  
      
  
      # Game loop
      while 1:
          for event in pygame.event.get():
              if event.type == pygame.QUIT:
                  sys.exit()
              if event.type == pygame.KEYDOWN:
                  # Handle set starter node event
                  if event.key == pygame.K_s:
                      x,y = mouse_translate(pygame.mouse.get_pos())
                      r = find_rect(x,y)
                      
                      if r == None: # Catch not found rect
                          break
                      elif r._color == green: # If already starting point set back to normal point
                          r._color = std_block_color
                          r.start = False
                      else:
                          r._color = green
                          r.start = True
                  # Handle set end node event
                  elif event.key == pygame.K_e:
                      x,y = mouse_translate(pygame.mouse.get_pos())
                      r = find_rect(x,y)
                      
                      if r == None: # Catch not found rect
                          break
                      elif r._color == red: # If already end point set back to normal point
                          r._color = std_block_color
                          r._end = False
                      else:
                          r._color = red
                          r.end = True
                  elif event.key == pygame.K_SPACE:
                      start_node = tuple
                      end_node = tuple
                      for r in grid_sprite_list:
                          if r.start:
                              start_node = (r.xpos, r.ypos)
                              
                          elif r.end:
                              end_node = (r.xpos, r.ypos)
                              
                      l = Astar.search(start_node, end_node, grid_sprite_list)
                      
                      try:
                          for r in l:
                              find_rect(r[0], r[1])._color = (255, 0, 255)
                      except:
                          print('No path found!')
  
          # Handle mouse cursour button being hold
          if pygame.mouse.get_pressed()[0] == 1:
              # If mouse pressed the coresponding grid block will become a wall
              # Start and end nodes will be ignored
              x,y = mouse_translate(pygame.mouse.get_pos())
              r = find_rect(x,y)
              if r == None:
                  return 0
              elif r.start == True or r.end == True:
                  return 0
              
              else:
                  r.wall = True
                  r._color = wall_block_color
          # Delete walls if shift + mouse pressed. Ignores end and start points walls
          if pygame.mouse.get_pressed()[0] == 1 and pygame.key.get_pressed()[304] == 1:
              x,y = mouse_translate(pygame.mouse.get_pos())
              r = find_rect(x,y)
              if r == None:
                  return 0
              elif r.start == True or r.end == True:
                  return 0
              
              elif r.wall == True:
                  r.wall = False
                  r._color = std_block_color
              elif r.wall == False:
                  return 0
          screen.fill(main_background)
  
          grid_sprite_list.draw(screen)
          grid_sprite_list.update()
  
          
  
          
          pygame.display.flip()
          
          Clock.tick(30)
  
  if __name__ == '__main__':
      grid = blocks.Grid # Import block class used to create grid 
      # Game settings
      # Dont touch width and height as alot function are staticly defined out of these variables
      width, height = (500, 500)
      green = (127, 255, 0)
      red = (250, 18, 18)
      wall_block_color = (47, 79, 79)
      std_block_color = (211, 211, 211)
      main_background = (255, 255, 255)
      main()