brean / python-pathfinding

Implementation of common pathfinding algorithms
https://brean.github.io/svelte-pyscript-pathfinding
MIT License
315 stars 64 forks source link

On names and parameter orders of coodinates #50

Open XinyiLiu577086410 opened 11 months ago

XinyiLiu577086410 commented 11 months ago

Hi, It is my first time to use python-pathfinding, it's nice but sth make me confused... To be brief, I am writing a bot to play a game, this is what I try to do tonight:

   def ParseMap(map:List[Map]) -> (List[List[Map]], List[List[List[tuple]]], tuple):
    parsedMap = [[Map() for i in range(MapEdgeLength)] for j in range(MapEdgeLength)]
    paths = [[[] for i in range(MapEdgeLength)] for j in range(MapEdgeLength)]
    accessableNow = [[1 for i in range(MapEdgeLength)] for j in range(MapEdgeLength)]
    playerPosition = None
    for grid in map:
        parsedMap[grid.x][grid.y] = grid
        for obj in grid.objs:
            if obj.type == ObjType.Player and obj.property.player_id != gContext["playerID"] and playerPosition is None:
                playerPosition = (grid.x, grid.y)
            if obj.type == ObjType.Block or obj.type == ObjType.Bomb:
                accessableNow[grid.x][grid.y] = 0 # (a)
    # pfGrid: an abbreviation of pathfinding grid
    pfGrid = Grid(matrix=accessableNow)
    for grid in map:
        pfGrid.cleanup()
        finder = AStarFinder(diagonal_movement=DiagonalMovement.never)
        newPath, _ = finder.find_path(pfGrid.node(playerPosition[0], playerPosition[1]),
                                        pfGrid.node(grid.x, grid.y, pfGrid) #(b)
        myNewPath = [(newPath[i].x, newPath[i].y) for i in range(len(newPath))]
        paths[grid.x][grid.y] = myNewPath
    return parsedMap, paths, playerPosition

Some names of variables in the code above are provided by the organizer of the contest I am taking part in. My code above failed to get correct answer until I rewite (a) as:

 accessableNow[grid.y][grid.x] = 0

or rewrite (b) as:

 newPath, _ = finder.find_path(pfGrid.node(playerPosition[1], playerPosition[0]),
                                        pfGrid.node(grid.y, grid.x, pfGrid) #(b)

Later, I refer to the docs but find nothing about parameter order. As I look into the grid.py i found:

       def node(self, x, y) -> GridNode:
        """
            get node at position
            :param x: x pos
            :param y: y pos
            :return:
        """
        return self.nodes[y][x]

Below is what I suggest: Rearrangeing parameters x and y as the order they appear in the List indexes:

       def node(self, y, x) -> GridNode:
           return self.nodes[y][x]

or rename them to the form xi where i is the order they appear in the indexes:

       def node(self, x1, x2) -> GridNode:
           return self.nodes[x1][x2]

so that People who use the pathfinding can access a node not according to a specific name convention, but the order they pass parameters to these functions before.

brean commented 11 months ago

Hi XinyiLiu577086410, Good point. I think it depends on what is more common in daily use. In a coordinate system I would expect "x first (for left), then y (for up)" but if you have an array I would expect the outer array as columns and then the inner ones as rows, so accessing them would be "y first then x". But I also see that that's confusing as well. We could also rename node(self, y, x) to node(self, column, row)...

This could be a nice small entrance for a new developer: Do some research on how other libraries are handling coordinates and what should be considered standard.