ctac.MapService.FindPath C# (CSharp) Method

FindPath() public method

public FindPath ( Tile start, Tile end, int maxDist, int controllingPlayerId ) : List
start Tile
end Tile
maxDist int
controllingPlayerId int
return List
        public List<Tile> FindPath(Tile start, Tile end, int maxDist, int controllingPlayerId)
        {
            var ret = new List<Tile>();
            if(start == end) return ret;

            // The set of nodes already evaluated.
            var closedset = new List<Tile>();

            // The set of tentative nodes to be evaluated, initially containing the start node
            var openset = new List<Tile>(){ start };

            // The map of navigated nodes.
            var came_from = new Dictionary<Tile, Tile>();

            var g_score = new Dictionary<Tile, int>();
            g_score[start] = 0;    // Cost from start along best known path.

            // Estimated total cost from start to goal through y.
            var f_score = new Dictionary<Tile, int>();
            f_score[start] = g_score[start] + heuristic_cost_estimate(start, end);

            while (openset.Count > 0) {
                // the node in openset having the lowest f_score[] value
                var current = openset.OrderBy(x => getValueOrMax(f_score,x)).First();
                if (current == end) {
                    return ReconstructPath(came_from, end);
                }

                openset.Remove(current);
                closedset.Add(current);

                var neighbors = GetMovableNeighbors(current, controllingPlayerId, end);
                foreach (var neighborDict in neighbors) {
                    var neighbor = neighborDict.Value;
                    if(closedset.Contains(neighbor)){
                        continue;
                    }

                    var tentative_g_score = getValueOrMax(g_score,current) + TileDistance(current.position, neighbor.position);

                    if (!openset.Contains(neighbor) || tentative_g_score < getValueOrMax(g_score,neighbor)) {
                        //check for max dist along path
                        if (tentative_g_score > maxDist)
                        {
                            continue;
                        }

                        came_from[neighbor] = current;
                        g_score[neighbor] = tentative_g_score;
                        f_score[neighbor] = getValueOrMax(g_score,neighbor) + TileDistance(neighbor.position, end.position);
                        if (!openset.Contains(neighbor)) {
                            openset.Add(neighbor);
                        }
                    }
                }

            }

            return null;
        }

Usage Example

Esempio n. 1
0
        public void FindPath()
        {
            var mapService = new MapService();
            mapService.mapModel = new MapModel()
            {
                name = "test map",
                maxPlayers = 0,
                root = null,
                tiles = CreateTiles(10, 10)
            };
            mapService.pieces = new PiecesModel()
            {
                Pieces = new List<PieceModel>()
                {
                    MockPiece(new Vector2(1, 2), false),
                    MockPiece(new Vector2(2, 3), true),
                    MockPiece(new Vector2(3, 2), true),
                    MockPiece(new Vector2(4, 2), true),
                    MockPiece(new Vector2(5, 2), false)
                }
            };

            var start = mapService.mapModel.tiles[new Vector2(2,2)];

            //test to walk around enemy
            var enemyEnd = mapService.mapModel.tiles[new Vector2(0,2)];

            var enemyPath = mapService.FindPath(start, enemyEnd, 4, 1);
            var expectedEnemyPath = new List<Vector2>()
            {
                new Vector2(2, 3),
                new Vector2(1, 3),
                new Vector2(0, 3),
                new Vector2(0, 2),
            };

            CollectionAssert.AreEqual(
                enemyPath.Select(t => t.position).ToList(),
                expectedEnemyPath
            );

            //test to walk through friendly
            var end = mapService.mapModel.tiles[new Vector2(2,4)];
            var tilePath = mapService.FindPath(start, end, 2, 1);
            var expectedTiles = new List<Vector2>()
            {
                new Vector2(2, 3),
                new Vector2(2, 4)
            };

            CollectionAssert.AreEqual(
                tilePath.Select(t => t.position).ToList(),
                expectedTiles
            );

            //test to attack enemy but not land on a friendly
            var passThroughEnd = mapService.mapModel.tiles[new Vector2(5,2)];
            var passTilePath = mapService.FindPath(start, passThroughEnd, 6, 1);
            var passExpectedTiles = new List<Vector2>()
            {
                new Vector2(3, 2),
                new Vector2(3, 3),
                new Vector2(4, 3),
                new Vector2(5, 3),
                new Vector2(5, 2)
            };

            CollectionAssert.AreEqual(
                passTilePath.Select(t => t.position).ToList(),
                passExpectedTiles
            );
        }