示例#1
0
        public void TestOn3x3Map()
        {
            byte[,] map = new byte[3, 3] {
                { 1, 2, 3, },
                { 3, 4, 2, },
                { 5, 6, 5, },
            };

            var start  = new Location(0, 0);
            var finish = new Location(2, 2);

            var pathFinder = new AStarPathFinder();

            var path = pathFinder.Find(map, start, finish).ToList();

            var result = new List <Location>()
            {
                new Location(2, 1),
                new Location(2, 0),
                new Location(1, 0),
                new Location(0, 0),
            };

            Assert.Equal(result, path);
        }
示例#2
0
        public void TestOn5x5MapWithAlmostWall()
        {
            byte[,] map = new byte[5, 5] {
                { 1, 2, 0, 6, 7 },
                { 3, 4, 3, 4, 6 },
                { 5, 6, 0, 6, 2 },
                { 7, 8, 0, 2, 6 },
                { 7, 8, 0, 2, 6 },
            };

            var start  = new Location(0, 0);
            var finish = new Location(4, 4);

            var pathFinder = new AStarPathFinder();

            var path = pathFinder.Find(map, start, finish).ToList();

            var result = new List <Location>()
            {
                new Location(3, 4),
                new Location(3, 3),
                new Location(2, 3),
                new Location(1, 3),
                new Location(1, 2),
                new Location(1, 1),
                new Location(1, 0),
                new Location(0, 0),
            };

            Assert.Equal(result, path);
        }
示例#3
0
        public override Path InitiateTurn()
        {
            Path.PathAction action;

            if (Target.OccupiedBy == null)
            {
                action = Path.PathAction.Move;
            }
            else if (Target.OccupiedBy.GetComponent <Monster>() != null)
            {
                action = Path.PathAction.Attack;
                Console.WriteLine("Chasing::InitiateTurn() found out that Target tile is occupied by a hero -> this shouldn't happen.");
            }
            else
            {
                action = Path.PathAction.Use;
            }

            AStarPathFinder pf   = new AStarPathFinder(action);
            Path            path = pf.Find(Monster.Tile, Target);

            Monster.Tile.OccupiedBy = null;
            Monster.Tile            = null;

            return(path);
        }
示例#4
0
        public override Path InitiateTurn()
        {
            AStarPathFinder pf   = new AStarPathFinder(Path.PathAction.Attack);
            Path            path = pf.Find(Monster.Tile, Candidate.Tile);

            Monster.Tile.OccupiedBy = null;
            Monster.Tile            = null;

            return(path);
        }
示例#5
0
        bool CheckMovementInitialization()
        {
            if (Selected && // we're selected
                Player.SelectedNode != null && // player has clicked on a map node
                (Player.SelectedNode.OccupiedBy == null || Player.SelectedNode.OccupiedBy.GetComponent <Hero>() == null) && // the map node is not occupied by an allied unit
                Reachable != null && Reachable.Contains(Player.SelectedNode))    // destination tile is reachable
            {
                // action upon completion
                Path.PathAction action;
                if (Player.SelectedNode.OccupiedBy == null)
                {
                    action = Path.PathAction.Move;
                }
                else if (Player.SelectedNode.OccupiedBy.GetComponent <Monster>() != null)
                {
                    action = Path.PathAction.Attack;
                }
                else
                {
                    action = Path.PathAction.Use;
                }

                // if we're attacking, check whether we still can
                if (action == Path.PathAction.Attack)
                {
                    if (AlreadyAttacked)
                    {
                        return(false);
                    }

                    AlreadyAttacked = true;
                }

                // forbid user interaction while moving
                Player.InvalidateSelection();
                Player.Mode = Player.PlayerMode.Waiting;
                Player.InvalidateHighlight(Reachable);

                // initilize movement
                AStarPathFinder pf = new AStarPathFinder(action);
                Path            = pf.Find(Tile, Player.SelectedNode);
                Tile.OccupiedBy = null;
                Tile            = null;

                return(true);
            }

            return(false);
        }
示例#6
0
        public override Path InitiateTurn()
        {
            MapNode goal     = Monster.Reachable.First();
            int     bestDist = DistancesSum(goal);

            foreach (MapNode node in Monster.Reachable)
            {
                int currDist = DistancesSum(node);

                if (currDist > bestDist)
                {
                    goal     = node;
                    bestDist = currDist;
                }
            }

            if (goal == Monster.Tile)
            {
                PatrolNext = true;
                return(null);
            }

            Path.PathAction action;
            if (goal.OccupiedBy == null)
            {
                action = Path.PathAction.Move;
            }
            else if (goal.OccupiedBy.GetComponent <Monster>() != null)
            {
                action = Path.PathAction.Attack;
            }
            else
            {
                action = Path.PathAction.Use;
            }

            AStarPathFinder pf   = new AStarPathFinder(action);
            Path            path = pf.Find(Monster.Tile, goal);

            Monster.Tile.OccupiedBy = null;
            Monster.Tile            = null;

            return(path);
        }
示例#7
0
        public void TestOn5x5MapWithWall()
        {
            byte[,] map = new byte[5, 5] {
                { 1, 2, 0, 6, 7 },
                { 3, 4, 0, 4, 6 },
                { 5, 6, 0, 6, 2 },
                { 7, 8, 0, 2, 6 },
                { 7, 8, 0, 2, 6 },
            };

            var start  = new Location(0, 0);
            var finish = new Location(4, 4);

            var pathFinder = new AStarPathFinder();

            var path = pathFinder.Find(map, start, finish)?.ToList();

            Assert.Null(path);
        }
示例#8
0
        public override Path InitiateTurn()
        {
            Random  rnd      = new Random();
            MapNode goal     = null;
            int     attempts = 0;

            while (goal == null || goal.OccupiedBy != null)
            {
                goal = Monster.Tile.Neighbors[rnd.Next(0, Monster.Tile.Neighbors.Count)];

                if (attempts++ > 10)
                {
                    return(null);
                }
            }

            AStarPathFinder pf   = new AStarPathFinder(Path.PathAction.Move);
            Path            path = pf.Find(Monster.Tile, goal);

            Monster.Tile.OccupiedBy = null;
            Monster.Tile            = null;

            return(path);
        }
示例#9
0
    private void Show(Pos start, Pos goal, int[][] cost)
    {
        var objs = GameObject.FindGameObjectsWithTag("Unit");

        foreach (var o in objs)
        {
            Destroy(o);
        }

        // ----- BFS -----

        var         gridGraph  = new GridGraph(16, 16, cost);
        IPathFinder pathFinder = new BfsPathFinder();
        var         path       = pathFinder.Find(gridGraph, start, goal);

        Show(gridGraph, new Vector2(0, 0), Color.white, path);

        var sumCost = 0;

        foreach (var p in path)
        {
            sumCost += cost[p.X][p.Y];
        }

        if (sumCost == 0)
        {
            Debug.LogError("BFS 没有找到路径");
        }
        else
        {
            Debug.LogError($"BFS 总成本: {sumCost}, 总步数: {path.Count}");
        }

        // ----- Dijkstra -----

        pathFinder = new DijkstraPathFinder();
        path       = pathFinder.Find(gridGraph, start, goal);

        Show(gridGraph, new Vector2(10, 0), Color.yellow, path);

        sumCost = 0;
        foreach (var p in path)
        {
            sumCost += cost[p.X][p.Y];
        }

        if (sumCost == 0)
        {
            Debug.LogError("Dijkstra 没有找到路径");
        }
        else
        {
            Debug.LogError($"Dijkstra 总成本: {sumCost}, 总步数: {path.Count}");
        }

        // ----- GreedyBestFirst -----

        pathFinder = new GreedyBestFirstPathFinder();
        path       = pathFinder.Find(gridGraph, start, goal);

        Show(gridGraph, new Vector2(0, 10), Color.grey, path);

        sumCost = 0;
        foreach (var p in path)
        {
            sumCost += cost[p.X][p.Y];
        }

        if (sumCost == 0)
        {
            Debug.LogError("GreedyBestFirst 没有找到路径");
        }
        else
        {
            Debug.LogError($"GreedyBestFirst 总成本: {sumCost}, 总步数: {path.Count}");
        }

        // ----- AStar -----

        pathFinder = new AStarPathFinder();
        path       = pathFinder.Find(gridGraph, start, goal);

        Show(gridGraph, new Vector2(10, 10), Color.magenta, path);

        sumCost = 0;
        foreach (var p in path)
        {
            sumCost += cost[p.X][p.Y];
        }

        if (sumCost == 0)
        {
            Debug.LogError("AStar 没有找到路径");
        }
        else
        {
            Debug.LogError($"AStar 总成本: {sumCost}, 总步数: {path.Count}");
        }
    }