Ejemplo n.º 1
0
def draw_movement(agent, grid, path_list, start_position, end_position,
                  enemy_pos, ambient_colour, bg_colour, character_colour,
                  width, height, tilesize, screen, speed):
    for start_position in path_list:
        if pf.manhattan_dist(enemy_pos,
                             start_position) < 60 and agent.get_state(
                             ) == fsm.States.PATROLLING:
            return start_position

        if pf.manhattan_dist(enemy_pos,
                             start_position) < 20 and agent.get_state(
                             ) == fsm.States.CHASING:
            return start_position

        # Redraw grid and obstacles to not remove the grid in places we've drawn
        grid.draw_obstacles(ambient_colour, tilesize, screen)
        draw_grid(ambient_colour, width, height, tilesize, screen)

        # Draw a rectangle at the current position
        x, y = start_position
        current_pos_rect = pg.Rect(x * tilesize, y * tilesize, tilesize,
                                   tilesize)
        pg.draw.rect(screen, character_colour, current_pos_rect)

        pg.display.flip()

        # Fill in the old position with the background colour
        old_position = start_position
        old_x, old_y = old_position
        old_position_rect = pg.Rect(old_x * tilesize, old_y * tilesize,
                                    tilesize, tilesize)
        pg.draw.rect(screen, bg_colour, old_position_rect)

        # Wait for some time
        time.sleep(speed)
Ejemplo n.º 2
0
def updateFlyingList():
    '''Update movelist for flying enemies'''
    # only border walls for flying list. Flying list to be index 1.
    Map.flyPath.walls = Map.path.border_walls
    Map.flyPath.weights = {}
    for startpoint in Map.mapvar.startpoint:
        came_from, cost_so_far = Pathfinding.get_path(Map.flyPath, startpoint, Map.mapvar.basepoint)
        Map.mapvar.flymovelists.append(Pathfinding.reconstruct_path(came_from, startpoint, Map.mapvar.basepoint))
Ejemplo n.º 3
0
 def chase(self, my_pos, enemy_pos):
     # use A* algorithm to move to Player position (get player as target as well)
     print("I see you! I'm gonna get you!")
     print("Activate super Speed!")
     # Probably want the movement function here
     if pf.manhattan_dist(my_pos, enemy_pos) > 60:
         self.set_state(States.PATROLLING)
         print("Huh, must've been the wind")
     elif pf.manhattan_dist(my_pos, enemy_pos) < 14:
         self.set_state(States.ATTACKING)
         print("Got you now!")
Ejemplo n.º 4
0
def draw_path(path, start, goal, colour, tilesize, screen):
    # Draw the path from start point to goal point
    current = start + path[pf.vec_to_int(
        start)]  # Start drawing path from second node
    while current != goal:
        x, y = current  # Set x and y to be used from current node
        rect = pg.Rect(x * tilesize, y * tilesize, tilesize,
                       tilesize)  # Create a Rect object with proper dimensions
        pg.draw.rect(screen, colour,
                     rect)  # Draw the Rect object in colour on screen
        current = current + path[pf.vec_to_int(
            current)]  # Find the next entry in the path
    return current
Ejemplo n.º 5
0
    def __init__(self, Sound=None):

        self.spritesheet = Image.SpriteSheet(path="res\\testSheet.png",
                                             spriteSize=32)
        self.OffsetX, self.OffsetY = 0, 0
        self.animTiles = []
        self.backRendered = False
        self.playerInputs = Constants.PlayerControls

        self.Entities = []

        super().__init__()

        self.TileMap, caverns = Mapper.generateCellularAutomata()
        self.entitypositions = Mapper.placeEnemiesCellular(caverns)

        for position in self.entitypositions:
            self.Entities.append(
                Entities.TestEnemy(x=position[1],
                                   y=position[0],
                                   Map=self.TileMap))

        playerPos = choice(caverns[0])
        while playerPos in self.entitypositions:
            playerPos = choice(caverns[0])

        self.player = Entities.Player(x=playerPos[1],
                                      y=playerPos[0],
                                      map=self.TileMap)
        self.graph = Pathfinding.Graph(self.TileMap)

        self.Sound = SoundHandler.Sound()
        self.Sound.PlayMusic('res/SFX/music.wav')

        self.offsetScene()
Ejemplo n.º 6
0
 def Main(args):
     Program.device = IrrlichtDevice.CreateDevice(DriverType.Direct3D9,
                                                  Dimension2Di(1280, 768))
     if Program.device == None:
         return
     Program.device.SetWindowCaption("Pathfinding - Irrlicht Engine")
     Program.device.OnEvent += Program.device_OnEvent
     driver = Program.device.VideoDriver
     font = Program.device.GUIEnvironment.GetFont(
         "../../media/fontlucida.png")
     fontNormalColor = Color.OpaqueWhite
     fontActionColor = Color.OpaqueYellow
     pathfindingTexture = driver.GetTexture("../../media/pathfinding.png")
     cellSize = pathfindingTexture.Size.Height
     Program.pathfinding = Pathfinding(64, 48, cellSize, 0, 0)
     Program.pathfinding.SetCell(4, 4, CellType.Start)
     Program.pathfinding.SetCell(Program.pathfinding.Width - 5,
                                 Program.pathfinding.Height - 5,
                                 CellType.Finish)
     while Program.device.Run():
         driver.BeginScene(True, False)
         Program.pathfinding.FindPath()
         Program.pathfinding.Draw(driver, pathfindingTexture)
         # draw info panel
         v = Vector2Di(
             Program.pathfinding.Width * Program.pathfinding.CellSize + 20,
             20)
         font.Draw("FPS: " + str(driver.FPS), v, fontNormalColor)
         v.Y += 32
         font.Draw(
             "Map size: " + str(Program.pathfinding.Width) + " x " +
             str(Program.pathfinding.Height), v, fontNormalColor)
         v.Y += 16
         font.Draw(
             "Shortest path: " +
             ("N/A" if Program.pathfinding.PathLength == -1 else
              Program.pathfinding.PathLength.ToString()), v,
             fontNormalColor)
         v.Y += 16
         font.Draw(
             "Calculation time: " +
             str(Program.pathfinding.PathCalcTimeMs) + " ms", v,
             fontNormalColor)
         v.Y += 32
         font.Draw(
             "[LMB] Set cell impassable" if Program.workMode else
             "[LMB] Set Start cell", v, fontActionColor)
         v.Y += 16
         font.Draw(
             "[RMB] Set cell passable" if Program.workMode else
             "[RMB] Set Finish cell", v, fontActionColor)
         v.Y += 16
         font.Draw("[Space] Change mode", v, fontActionColor)
         v.Y += 32
         font.Draw("[F1] Clean up the map", v, fontActionColor)
         v.Y += 16
         font.Draw("[F2] Add random blocks", v, fontActionColor)
         driver.EndScene()
     Program.device.Drop()
Ejemplo n.º 7
0
    def Route_Player(self):
        aStar = Pathfinding.AStar(
            self.area, self.area[self.player.pos[1]][self.player.pos[0]],
            self.area[self.endPos[1]][self.endPos[0]])
        self.route = aStar.process()

        while len(self.route) > 0:
            nextMove = self.route.pop()
            self.move_player(nextMove)
            time.sleep(0.1)
Ejemplo n.º 8
0
def updatePath():
    '''Update the path using A* algorithm'''
    # Map.newPath.walls = Map.path.get_wall_list()
    Map.myGrid.walls = Map.path.get_wall_list()
    if len(Map.mapvar.flymovelists) == 0:
         updateFlyingList()

    Map.mapvar.movelists = []
    x=0
    for startpoint in Map.mapvar.startpoint:
        came_from, cost_so_far = Pathfinding.get_path(Map.myGrid, startpoint, Map.mapvar.basepoint)
        if came_from == 'Path Blocked':
            Map.mapvar.blockedSquare = cost_so_far
            return False
        Map.mapvar.movelists.append(Pathfinding.reconstruct_path(came_from, startpoint, Map.mapvar.basepoint))

    Map.mapvar.genmovelists()
    Map.mapvar.updatePath = False
    Map.mapvar.roadGen()
    updateIce()
Ejemplo n.º 9
0
def path_to_list(path, start, end):
    # Turns the path Dictionary into a list of pygame.math.Vector2 instead
    current = start
    path_list = []
    # Fill list with all parts of the path
    while current != end:
        path_list.append(current)
        current = current + path[pf.vec_to_int(current)]
    # Make sure to add the end node at the end of the function (not done in the while loop
    path_list.append(end)
    return path_list
Ejemplo n.º 10
0
def main():
    window = pygame.display.set_mode((1600, 900))
    pygame.display.set_caption("A* Pathfinding")
    nodeSize = 20
    gridSizeX = int(pygame.display.get_surface().get_width() / nodeSize)
    gridSizeY = int(pygame.display.get_surface().get_height() / nodeSize)
    #gridSizeX = 100
    #gridSizeY = 100
    grid = NodeGrid.NodeGrid(pygame.display.get_surface().get_size(),
                             gridSizeX, gridSizeY, nodeSize)
    grid.createGrid()
    startNode = None
    targetNode = None
    run = True
    drag = False
    positionSet = 0  # Like a game state; 0 = set target, 1 = set start, 2 = set obstacles, 3 = all set, ready to play

    #clear()
    print("Set the target position")
    while (run):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False

            if positionSet == 0:  # Nothing set yet
                if event.type == pygame.MOUSEBUTTONDOWN:
                    targetNode = grid.setPoints(pygame.mouse.get_pos(), 1)
                    if targetNode != None:
                        positionSet += 1
                        print("Set the start position")
                    else:
                        print("Target node already in place")
                        positionSet += 1
            elif positionSet == 1:  # Target has been set
                if event.type == pygame.MOUSEBUTTONDOWN:
                    startNode = grid.setPoints(pygame.mouse.get_pos(), 2)
                    if startNode != None:
                        positionSet += 1
                        print(
                            "Set obstacles. This is not required. Press 'Enter' to continue"
                        )
                    else:
                        print("Start node already in place")
                        positionSet += 1
            elif positionSet == 2:  # Start point has been set
                if event.type == pygame.MOUSEBUTTONDOWN:
                    if event.button == 1:
                        drag = True
                elif event.type == pygame.MOUSEBUTTONUP:
                    if event.button == 1:
                        drag = False
                elif event.type == pygame.MOUSEMOTION:
                    if drag:
                        grid.setPoints(pygame.mouse.get_pos(), 3)
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_RETURN:
                        positionSet += 1
                        print("All set! Ready for pathfinding")
                        print(
                            "Press 'Enter' to get the best path to the target")
                        print(
                            "Press 'Space' to show the process of finding the path"
                        )
            elif positionSet == 3:  # All set, ready to begin
                pathfinding = Pathfinding.PathFinding(targetNode, startNode,
                                                      grid)
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_RETURN:  # Find path immediately
                        pathfinding.findPath()
                    elif event.key == pygame.K_SPACE:  # Show steps while running
                        pathfinding.findPath(True, window, grid)
                    elif event.key == pygame.K_BACKSPACE:  # Step-by-step solving
                        pass
                    positionSet += 1
                    print("All done. Press 'Space' to begin again")
            elif positionSet == 4:
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_SPACE:
                        grid.resetGrid()
                        targetNode = None
                        startNode = None
                        positionSet = 0
                        clear()
                        print("Set the target position")

        grid.drawGrid(window)
        pygame.display.update()
Ejemplo n.º 11
0
def main(*args):
    global screen
    global wallMap
    global offset
    global mag

    # Initializing pygame internals and basic window setup
    pygame.init()
    pygame.font.init()
    myfont = pygame.font.SysFont('Arial', 20)
    enemCount = pygame.font.SysFont('Arial', 10)

    mag = 1.25
    width = 1280
    height = 600
    screen = pygame.display.set_mode((width, height))
    pygame.display.set_caption("Adolescent Deformed Samurai Tortoises")

    clock = pygame.time.Clock()

    wallimage = imageio.imread("images\\walls.bmp")
    waterimage = imageio.imread("images\\water.bmp")
    wallMap = []
    waterMap = []
    enemyMap = []
    enemyTruthMap = []
    damageMap = []
    bg = pygame.transform.scale(
        pygame.image.load("images\\world.png"),
        (int(len(wallimage[0]) * mag), int(len(wallimage[0]) * mag)))
    wave = 1
    remainSpawn = 2 * wave
    spawns = [Point(12, 1), Point(12, 23), Point(1, 16), Point(23, 9)]
    maxEnemDen = 4
    killCount = 0

    #Camera offset initialization
    offset = Point(0, 0)

    if (args[0] == "blue"):
        player = PlayableCharacters.Leo(wallMap, waterMap,
                                        Point(1250 / 2, 600 / 2))
    elif (args[0] == "red"):
        player = PlayableCharacters.Raph(wallMap, waterMap,
                                         Point(1250 / 2, 600 / 2))
    elif (args[0] == "orange"):
        player = PlayableCharacters.Mike(wallMap, waterMap,
                                         Point(1250 / 2, 600 / 2))
    elif (args[0] == "purple"):
        player = PlayableCharacters.Donny(wallMap, waterMap,
                                          Point(1250 / 2, 600 / 2))

    #Boolean flags for movement. Rudimentary but they do the trick
    UP = False
    DOWN = False
    RIGHT = False
    LEFT = False

    #Enables debug visuals
    DEBUG = False

    #Creation of empty wall map lookup
    for row in range(25):
        wallMap.append([])
        waterMap.append([])
        enemyMap.append([])
        enemyTruthMap.append([])
        damageMap.append([])
        for x in range(25):
            wallMap[row].append(0)
            waterMap[row].append(0)
            enemyMap[row].append(0)
            enemyTruthMap[row].append(0)
            damageMap[row].append(0)

    # Reading the wall map and creating a local version for look-up
    for x in range(0, len(wallimage[0]), 50):
        for y in range(0, len(wallimage[0]), 50):
            wallMap[int(x / 50)][int(
                y / 50)] = True if wallimage[y + 25][x +
                                                     25][0] == 64 else False
            waterMap[int(x / 50)][int(
                y /
                50)] = True if waterimage[y + 25][x + 25][2] != 0 else False

    enemies = []

    # for row in range(50):
    #     enemies.append(Enemy.Enemy(wallMap, waterMap, enemyMap, Point(
    #         random.randrange(50,1200),
    #         random.randrange(50,1200))))

    #Game loop
    while True:
        if player.health > 0 or (player.health <= 0 and DEBUG):
            #Going through game events
            for event in pygame.event.get():
                #If the "X" button is clicked
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                if event.type == pygame.MOUSEBUTTONDOWN:
                    if player.attack == 0:
                        deltaX = pygame.mouse.get_pos()[0] - (
                            calcScreenPos(player)[0] +
                            player.getImage(mag).get_size()[0] / 2)
                        deltaY = pygame.mouse.get_pos()[1] - (
                            calcScreenPos(player)[1] +
                            player.getImage(mag).get_size()[1] / 2)
                        if (abs(deltaX) >= abs(deltaY)):
                            if deltaX > 0:
                                LEFT = False
                                player.rot = 3
                                damageMap[int(player.pos.x / 50) + 1][int(
                                    player.pos.y / 50)] = player.damage
                            else:
                                RIGHT = False
                                player.rot = 1
                                damageMap[int(player.pos.x / 50) - 1][int(
                                    player.pos.y / 50)] = player.damage
                        else:
                            if deltaY > 0:
                                UP = False
                                player.rot = 2
                                damageMap[int(player.pos.x /
                                              50)][int(player.pos.y / 50) +
                                                   1] = player.damage
                            else:
                                DOWN = False
                                player.rot = 0
                                damageMap[int(player.pos.x /
                                              50)][int(player.pos.y / 50) -
                                                   1] = player.damage

                        damageMap[int(player.pos.x / 50)][int(
                            player.pos.y / 50)] = player.damage
                        player.attack = 1
                #If a key is pressed/unpressed
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_v:
                        DEBUG = not DEBUG
                    if event.key == pygame.K_w:
                        UP = True
                        DOWN = False
                        RIGHT = False
                        LEFT = False
                    if event.key == pygame.K_s:
                        UP = False
                        DOWN = True
                        RIGHT = False
                        LEFT = False
                    if event.key == pygame.K_d:
                        UP = False
                        DOWN = False
                        RIGHT = True
                        LEFT = False
                    if event.key == pygame.K_a:
                        UP = False
                        DOWN = False
                        RIGHT = False
                        LEFT = True
                if event.type == pygame.KEYUP:
                    if event.key == pygame.K_w:
                        UP = False
                    if event.key == pygame.K_s:
                        DOWN = False
                    if event.key == pygame.K_d:
                        RIGHT = False
                    if event.key == pygame.K_a:
                        LEFT = False

            #Spawning enemies at start of round
            if len(enemies) == 0:
                wave += 1
                remainSpawn = 2 * wave
                for row in enemyMap:
                    for column in range(len(row)):
                        row[column] = 0
            if (remainSpawn > 0):
                for i in range(remainSpawn):
                    availSpawn = []
                    for point in spawns:
                        if enemyMap[point.x][point.y] < 1:
                            availSpawn.append(point)
                    if (len(availSpawn) > 0):
                        spawn = random.choice(availSpawn).__copy__()
                        remainSpawn -= 1
                        spawn.x *= 50
                        spawn.y *= 50
                        enemy = Enemy.Enemy(wallMap, waterMap, enemyMap, spawn)
                        enemies.append(enemy)
                    else:
                        break
            """
            Only one form of movement is allowed at a time, in order to allow
            for basic 90 degree angles in all calcs. 
            """

            if UP:
                #Move player
                player.move(Point(0, -player.speed))

                #Fix camera offset
                if player.pos.y * mag - offset.y < width * 0.1:
                    if offset.y > 0:
                        offset.y = -(width * 0.1 - (player.pos.y * mag))
            elif DOWN:
                #Move player
                player.move(Point(0, player.speed))

                #Fix camera offset
                if player.pos.y * mag - offset.y > height - width * 0.1:
                    if offset.y < len(wallimage[0]) * mag - height:
                        offset.y = -(height - width * 0.1 -
                                     (player.pos.y * mag))
            elif RIGHT:
                #Move player
                player.move(Point(player.speed, 0))

                #Fix camera offset
                if player.pos.x * mag - offset.x > width - width * 0.15:
                    if offset.x < len(wallimage[0]) * mag - width:
                        offset.x = -(width - width * 0.15 -
                                     (player.pos.x * mag))
            elif LEFT:
                #Move player
                player.move(Point(-player.speed, 0))

                #Fix camera offset
                if player.pos.x * mag - offset.x < width * 0.15:
                    if offset.x > 0:
                        offset.x = player.pos.x * mag - width * 0.15
            for x in range(25):
                for y in range(25):
                    enemyTruthMap[x][y] = enemyMap[x][y] > maxEnemDen

            for row in range(len(damageMap)):
                for column in range(len(damageMap[row])):
                    if player.attack == 0:
                        damageMap[row][column] = 0

            dirMap = Pathfinding.getVectorField(player.pos, wallMap, waterMap,
                                                enemyMap)

            # Fill the screen with black to clear off last frame
            screen.fill((0, 0, 0))

            # Draw map with offset
            screen.blit(bg, (int(round(-offset.x)), int(round(-offset.y))))
            if DEBUG:
                debugDraw(bg, player, enemies, damageMap, dirMap, myfont,
                          enemyMap)

            for enemy in enemies:
                if enemy.health > 0:
                    enemy.moveD(dirMap[int(enemy.pos.y / 50)][int(enemy.pos.x /
                                                                  50)])
                    dam = damageMap[int(enemy.pos.x / 50)][int(enemy.pos.y /
                                                               50)]
                    enemy.health -= dam
                    pos = list(calcScreenPos(enemy))
                    screen.blit(enemy.getImage(mag), pos)
                    if distance(player.pos,
                                enemy.pos) < 40**2 and enemy.attack == 0:
                        player.health -= 10
                        enemy.attack = 1
                    pos[0] += enemy.getImage(mag).get_size()[0] / 2 - 15
                    pos[1] += enemy.getImage(mag).get_size()[1] / 2 - 10
                    enemHealth = myfont.render(str(enemy.health), False,
                                               (255, 0, 0))
                    screen.blit(enemHealth, pos)
                else:
                    killCount += 1
                    enemyMap[int(enemy.pos.x / 50)][int(enemy.pos.y / 50)] -= 1
                    enemies.remove(enemy)

            #Draw player
            screen.blit(player.getImage(mag), calcScreenPos(player))

            #Drawing health bar
            pygame.draw.rect(screen, (255, 0, 0),
                             ((1250 * 0.3 / 2, 10), (1260 * (2 / 3), 20)))
            pygame.draw.rect(screen, (0, 255, 0),
                             ((1250 * 0.3 / 2, 10),
                              (1260 * (2 / 3) *
                               (abs(player.health) / 100), 20)))

            #Updating display and ticking internal game clock
            fpsCounter = myfont.render("FPS: " + str(int(clock.get_fps())),
                                       False, (0, 255, 0))
            waveCount = myfont.render("Wave: " + str(wave), False, (0, 255, 0))
            enemyCount = myfont.render("Enemy Count: " + str(len(enemies)),
                                       False, (0, 255, 0))
            screen.blit(fpsCounter, (0, 0))
            screen.blit(waveCount, (0, 25))
            screen.blit(enemyCount, (0, 50))
            clock.tick(60)
            pygame.display.update()
        else:
            # Ending the game
            print("You died, after killing " + str(killCount) +
                  " members of the toe clan!")
            pygame.quit()
            break
Ejemplo n.º 12
0
        else:
            self.basepoint = (23, 9)  # update newPath/flyPath below too


mapvar = Map()


class Path():
    def __init__(self):
        pass

    def createPath(self):
        if mapvar.pointmovelist is not None:
            self.movelist = mapvar.pointmovelists[0][:]
        gen_border_walls()
        self.border_walls = list([(child.squpos[0], child.squpos[1])
                                  for child in mapvar.wallcontainer.children])
        self.wall_list = None

    def get_wall_list(self):
        walls = list([(child.squpos[0], child.squpos[1])
                      for child in mapvar.wallcontainer.children])
        return walls


path = Path()
flyPath = Pathfinding.neighborGridwithWeights(mapvar.squwid, mapvar.squhei - 1,
                                              0, (28, 9))
myGrid = Pathfinding.neighborGridwithWeights(mapvar.squwid, mapvar.squhei - 1,
                                             0, (28, 9))
Ejemplo n.º 13
0
 def patrol(self, my_position, enemy_pos):
     # use A* algorithm to calculate path between the two points
     print("*whistling jolly tune*")
     # Probably want the movement function here
     if pf.manhattan_dist(my_position, enemy_pos) < 60:
         self.set_state(States.CHASING)
Ejemplo n.º 14
0
def play():
    x_screen = 500
    y_screen = 150
    os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (x_screen, y_screen)

    pg.init()
    screen = pg.display.set_mode((WIDTH, HEIGHT))
    clock = pg.time.Clock()

    g = sg.WeightedGrid(GRIDWIDTH, GRIDHEIGHT)
    obstacles = [(12, 7), (13, 7), (14, 7), (15, 7), (16, 7), (7, 7), (1, 6),
                 (2, 6), (3, 6), (5, 10), (5, 11), (5, 12), (5, 9), (5, 8),
                 (12, 8), (12, 9), (12, 10), (12, 11), (15, 11), (15, 10),
                 (17, 7), (18, 7), (21, 7), (21, 6), (21, 5), (21, 4), (21, 3),
                 (22, 5), (23, 5), (24, 5), (25, 5), (18, 10), (20, 10),
                 (19, 10), (21, 10), (22, 10), (23, 10), (14, 4), (14, 5),
                 (14, 6), (14, 0), (14, 1), (9, 2), (7, 3), (10, 3), (9, 3),
                 (2, 5), (2, 4), (2, 3), (2, 2), (2, 0), (2, 1), (0, 11),
                 (1, 11), (2, 11), (21, 2), (20, 11), (20, 12), (23, 13),
                 (23, 14), (24, 10), (25, 10), (6, 12), (7, 12), (10, 12),
                 (11, 12),
                 (12, 12), (5, 3), (6, 3), (10, 15), (7, 15), (6, 15), (5, 15),
                 (2, 15), (3, 15), (9, 15), (8, 15), (2, 14), (2, 13), (2, 12),
                 (7, 16), (7, 17), (7, 18), (7, 21), (7, 20), (7, 19), (6, 16),
                 (6, 17), (6, 18), (6, 19), (6, 20), (6, 21), (6, 22), (7, 22),
                 (6, 23), (7, 23), (7, 24), (6, 24), (6, 25), (8, 23), (7, 26),
                 (6, 26), (8, 27), (9, 28), (10, 28), (11, 27), (12, 26),
                 (13, 25), (12, 24), (11, 23), (13, 23), (12, 23), (14, 23),
                 (13, 24), (14, 26), (14, 25), (14, 24), (13, 26), (12, 27),
                 (13, 27), (12, 28), (11, 28), (8, 28), (7, 28), (7, 27),
                 (6, 27), (5, 26), (4, 26), (4, 25), (5, 25), (5, 24), (5, 23),
                 (4, 24), (3, 25), (3, 26), (0, 26), (0, 25), (0, 24), (0, 22),
                 (0, 21), (0, 20), (0, 19), (0, 23), (0, 18), (0, 27), (0, 28),
                 (1, 28), (1, 29), (2, 29), (2, 30), (2, 31), (1, 30), (1, 31),
                 (0, 31), (0, 30), (0, 29), (6, 7), (3, 3), (4, 3), (8, 3),
                 (13, 6), (13, 5), (13, 4), (14, 3), (5, 7), (7, 10), (6, 10),
                 (9, 11), (11, 11), (10, 11), (13, 16), (13, 18), (13, 19),
                 (13, 22), (13, 21), (13, 15), (15, 15), (14, 15), (18, 12),
                 (17, 12), (16, 12), (15, 12), (23, 15), (22, 15), (21, 15),
                 (20, 15), (19, 15), (18, 15), (17, 15), (14, 31), (14, 30),
                 (14, 29), (13, 30), (13, 31), (12, 31), (9, 31), (6, 31),
                 (5, 31), (4, 31), (3, 31), (8, 31), (11, 31), (10, 31), (7,
                                                                          31),
                 (3, 30), (15, 28), (15, 29), (15, 30), (15, 31), (15, 24),
                 (15, 25), (15, 26), (15, 23), (14, 22), (12, 22), (7, 14),
                 (10, 13), (13, 14), (16, 13), (19, 14), (22, 11), (18, 3),
                 (17, 3), (18, 4), (17, 4), (8, 5), (10, 5), (9, 5), (7, 5),
                 (6, 5), (16, 25), (16, 24), (17, 24), (17, 25), (18, 24),
                 (20, 25), (18, 25), (20, 26), (20, 27), (19, 27), (19, 28),
                 (19, 31), (19, 30), (24, 28), (24, 29), (25, 28), (25, 29),
                 (26, 28), (26, 29), (27, 28), (27, 29), (28, 29), (30, 28),
                 (31, 28), (31, 29), (25, 31), (24, 31), (23, 25), (24, 25),
                 (25, 25), (26, 25), (27, 25), (26, 24), (23, 24), (24, 24),
                 (25, 24), (27, 24), (27, 23), (26, 23), (27, 22), (26, 22),
                 (26, 21), (27, 19), (26, 19), (26, 20), (27, 20), (27, 21),
                 (27, 18), (26, 16), (26, 17), (26, 18), (27, 17), (27, 16),
                 (25, 19), (24, 19), (23, 19), (22, 19), (21, 19), (20, 19),
                 (20, 20), (17, 19), (16, 19), (17, 20), (16, 20), (10, 20),
                 (10, 19), (9, 19), (9, 20), (10, 17), (19, 17), (18, 17),
                 (29, 13), (30, 13), (31, 13), (27, 13), (28, 13), (30, 20),
                 (30, 17), (30, 16), (30, 18), (30, 23), (30, 26), (30, 27),
                 (31, 27), (31, 26), (31, 30), (31, 31), (30, 31), (29, 31),
                 (28, 31), (27, 31), (26, 31), (15, 0), (16, 0), (17, 0),
                 (19, 0), (18, 0), (21, 0), (22, 0), (24, 0), (23, 0), (28, 0),
                 (27, 0), (30, 0), (29, 0), (31, 0), (31, 2), (31, 1), (31, 3),
                 (31, 4), (31, 5), (29, 5), (30, 5), (29, 3), (29, 2), (28, 3),
                 (25, 3), (25, 2), (24, 2), (28, 8), (29, 8), (30, 8), (29, 9),
                 (24, 8), (23, 8), (25, 8), (25, 7), (22, 22), (21, 22)]
    for obstacle in obstacles:
        g.obstacles.append(vec(obstacle))

    print("Setting up")
    player_goal = vec(9, 25)
    player_position = vec(9, 25)
    path = pf.a_star(g, player_goal, player_position)
    path_list = df.path_to_list(path, player_position, player_goal)

    agent_1 = fsm.Agent()
    patrol_goal = vec(31, 9)
    patrol_start = vec(1, 9)

    running = True
    while running:
        clock.tick(FPS)
        # Events for making more walls and getting player input
        for event in pg.event.get():
            if event.type == pg.QUIT:
                running = False
            if event.type == pg.KEYDOWN:
                if event.key == pg.K_ESCAPE:
                    running = False
                if event.key == pg.K_m:
                    # "Save" the list of walls, so it can be copy pasted
                    print([(int(loc.x), int(loc.y)) for loc in g.obstacles])
            if event.type == pg.MOUSEBUTTONDOWN:
                mpos = vec(pg.mouse.get_pos()) // TILESIZE
                if event.button == 1:
                    if mpos in g.obstacles:
                        g.obstacles.remove(mpos)
                    else:
                        g.obstacles.append(mpos)
                if event.button == 3:
                    print("Shhh! I'm moving")
                    player_goal = mpos
                path = pf.a_star(g, player_goal, player_position)
                path_list = df.path_to_list(path, player_position,
                                            player_goal)  #
        # Pygame "level" drawing of obstacles and grid
        pg.display.set_caption("Pathfinding Finally Working")
        screen.fill(BLACK)
        g.draw_obstacles(LIGHTGRAY, TILESIZE, screen)
        df.draw_grid(LIGHTGRAY, WIDTH, HEIGHT, TILESIZE, screen)

        # Draw the player's path from its position (player_position) to the set goal
        df.draw_movement(agent_1, g, path_list, player_position, player_goal,
                         patrol_start, LIGHTGRAY, BLACK, BLUE, WIDTH, HEIGHT,
                         TILESIZE, screen, 0.5)
        if path_list and path_list[-1] is not None:
            player_position = path_list[-1]
            path = pf.a_star(g, player_position, player_goal)
            path_list = df.path_to_list(path, player_position, player_goal)

        # Draw and control states of agent_1
        if agent_1.get_state() == fsm.States.PATROLLING:
            agent_1.patrol(patrol_start, player_position)
            patrol_path = pf.a_star(g, patrol_start, patrol_goal)
            patrol_path_list = df.path_to_list(patrol_path, patrol_goal,
                                               patrol_start)
            start_chase = df.draw_movement(agent_1, g, patrol_path_list,
                                           patrol_start, patrol_goal,
                                           player_position, LIGHTGRAY, BLACK,
                                           RED, WIDTH, HEIGHT, TILESIZE,
                                           screen, 0.25)
            if start_chase != vec(0, 0) and start_chase != None:
                agent_1.set_state(fsm.States.CHASING)
            patrol_start = patrol_path_list[0]
            patrol_goal = patrol_path_list[-1]

            if agent_1.get_state() == fsm.States.CHASING:
                agent_1.chase(start_chase, player_position)
                chase_path = pf.a_star(g, player_position, start_chase)
                chase_path_list = df.path_to_list(chase_path, start_chase,
                                                  player_position)
                start_chase = df.draw_movement(agent_1, g, chase_path_list,
                                               start_chase, patrol_goal,
                                               player_position, LIGHTGRAY,
                                               BLACK, RED, WIDTH, HEIGHT,
                                               TILESIZE, screen, 0.1)
                if pf.manhattan_dist(player_position, start_chase) < 20:
                    agent_1.set_state(fsm.States.ATTACKING)
            if agent_1.get_state() == fsm.States.ATTACKING:
                agent_1.attack(start_chase, player_position)