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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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}"); } }