public List <FlatHexPoint> GetGridPath(FlatHexPoint start, FlatHexPoint end) { List <FlatHexPoint> result = new List <FlatHexPoint> (); var path = Algorithms.AStar <JKCell, FlatHexPoint> (grid, start, end , (p, q) => p.DistanceFrom(q), c => true, (p, q) => (grid [p].Cost + grid [q].Cost / 2) ); result = path.ToList(); // foreach(var step in path.ToList ()) // { // if(grid[step].isAccessible) // { // result.Add (step); // } // } return(result); }
public Direction MoveSnake() { Coordinate coordinate; //coordinate = Algorithms.AStar(_grid as Grid, _you.Head, GetClosestFood(out var distance)); //if (distance == -1) // coordinate = Algorithms.AStar(_grid as Grid, _you.Head, _you.Tail); if (IsLowHealth(_you.Health, out var foodLocation) || _you.Head == _you.Tail) { coordinate = Algorithms.AStar(_grid as Grid, _you.Head, foodLocation); } else if (IsBiggest()) { coordinate = Algorithms.AStar(_grid as Grid, _you.Head, _enemySnakes[0].Head); } else { coordinate = Algorithms.AStar(_grid as Grid, _you.Head, _you.Tail); } var choice = Direction.All.ToList() .Where(x => _you.Head.ApplyDirection(x) == coordinate) .FirstOrDefault(); Console.WriteLine($"Choice is {choice}"); Console.WriteLine(); return(choice ?? Direction.Up); }
/// <summary> /// /// </summary> /// <param name="destination"></param> /// <param name="checkForEnemies"></param> /// <returns></returns> private bool Move(Coord destination, bool checkForEnemies = false) { // initialise var moveRange = Speed / 5; var path = Algorithms.AStar(Coordinate, destination, Map); if (path == null) { return(false); } var i = 1; var diagonalCount = 0; // TODO: Implement the exact movement rule in the manual while (moveRange > 0) { // check if we have an enemy in fov if (checkForEnemies && CombatState == CombatState.None) { // check field of view positions for enemies foreach (var entity in Map.EntitiesOnCoords(FovCoords).Where(p => p.IsAlive)) { if (entity.Faction == Faction.None) { continue; } if (Faction != entity.Faction) { CombatState = CombatState.Initiation; entity.CombatState = CombatState.Initiation; } } // break if we have found an enemy if (CombatState == CombatState.Initiation) { break; } } if (path.Length <= i) { break; } var next = path[i++]; if (next == destination && !Map.WalkabilityMap[next]) { break; } MoveAtomic(next, ref moveRange, ref diagonalCount); } return(true); }
private IEnumerable <RectPoint> GetGridPath() { RectTileGridBuilder builder = GetComponent <RectTileGridBuilder>(); var path = Algorithms.AStar(builder.Grid, start, goal, (p, q) => p.DistanceFrom(q), c => ((ShipCell)c).IsAccessible, CalculateCost); return(path); }
public static IEnumerator SummonSatanCoroutine(GOAPEntity ent) { Node startingPoint = NodeList.allNodes.OrderBy(a => { return(Vector3.Distance(a.transform.position, ent.transform.position)); }).First(); HouseNode target = NodeList.allNodes .Select(a => { return(a.GetComponent <HouseNode>()); }) .Where(a => a != null && !a.owned && !a.constructed) .OrderBy(a => { return(Vector3.Distance(a.transform.position, ent.transform.position)); }) .First(); var path = Algorithms.AStar( startingPoint, a => a == target, a => Vector3.Distance(target.transform.position, a.transform.position), a => { return(a.neighbors.Where(b => b.gameObject.activeSelf).Select(n => new Arc <Node>().SetArc(n, Vector3.Distance(n.transform.position, a.transform.position)))); } ); while (path.Count > 0) { ent.transform.forward = new Vector3(path.Peek().transform.position.x - ent.transform.position.x, ent.transform.forward.y, path.Peek().transform.position.z - ent.transform.position.z); ent.transform.position += ent.transform.forward * Mathf.Min(Vector3.Distance(path.Peek().transform.position, ent.transform.position), ent.speed * Time.deltaTime); if (Vector3.Distance(path.Peek().transform.position, ent.transform.position) <= 2f) { path.Pop(); } yield return(new WaitForEndOfFrame()); } var satanSymbol = ent.transform.GetChild(0).gameObject; satanSymbol.SetActive(true); target.constructed = true; target.owned = true; while (true) { satanSymbol.transform.eulerAngles += satanSymbol.transform.forward * 50f * Time.deltaTime; satanSymbol.transform.localScale += (Vector3.one * Time.deltaTime); yield return(new WaitForEndOfFrame()); } ent.Sequence.First().Effects(ent.Current, ent.Current); ent.Sequence = ent.Sequence.Skip(1); if (ent.Sequence.Count() > 0) { ent.Sequence.First().Act(ent); } }
private void UpdatePath() { if (Application.isPlaying) { pathRoot.transform.DestroyChildren(); } else { pathRoot.transform.DestroyChildrenImmediate(); } //We use the original grid here, and not the //copy, to preserve neighbor relationships. Therefore, we //have to cast the cell in the lambda expression below. var path = Algorithms.AStar( Grid, start, goal, EuclideanDistance, c => ((WalkableCell)c).IsWalkable, EuclideanDistance); if (path == null) { return; //then there is no path between the start and goal. } foreach (var point in path) { var pathNode = Instantiate(pathPrefab); pathNode.transform.parent = pathRoot.transform; pathNode.transform.localScale = Vector3.one * 0.5f; pathNode.transform.localPosition = Map[point]; if (point == start) { pathNode.Color = ExampleUtils.Colors[1]; } else if (point == goal) { pathNode.Color = ExampleUtils.Colors[3]; } else { pathNode.Color = ExampleUtils.Colors[2]; } } }
public static IEnumerable <GOAPAction> RunGOAPOld(GOAPEntity entity, GOAPState from, IEnumerable <GOAPAction> actions, int watchdog = 6000) { int watchdogCount = watchdog; var sequence = Algorithms.AStar <GOAPState>( from, current => entity.Satisfies(current), current => entity.Heuristics(current), current => { var arcs = new List <Arc <GOAPState> >(); if (watchdogCount == 0) { return(arcs); } else { watchdogCount--; } foreach (GOAPAction act in actions) { if (act.Preconditions(current)) { var st = new GOAPState(current); st.generatingAction = act; act.Effects(current, st); st.stepId = current.stepId + 1; arcs.Add(new Arc <GOAPState>().SetArc(st, act.Cost)); } } return(arcs); } ); if (sequence == null) { return(null); } foreach (var step in sequence) { Debug.Log(step.generatingAction.Name); } Debug.Log("Watchdog: " + watchdogCount); return(sequence.Select(x => x.generatingAction)); }
public static IEnumerator KillEnemyCoroutine(GOAPEntity ent) { Node startingPoint = NodeList.allNodes.OrderBy(a => { return(Vector3.Distance(a.transform.position, ent.transform.position)); }).First(); var houses = NodeList.allNodes .Select(a => { return(a.GetComponent <HouseNode>()); }) .Where(a => a != null && a.owned && a.constructed) .Select(a => a.keyId); EnemyWaypoint target = NodeList.allNodes .Select(a => { return(a.GetComponent <EnemyWaypoint>()); }) .Where(a => a != null && a.gameObject.activeSelf && houses.Contains(a.keyId)) .OrderBy(a => { return(Vector3.Distance(a.transform.position, ent.transform.position)); }) .First(); var path = Algorithms.AStar( startingPoint, a => a == target, a => Vector3.Distance(target.transform.position, a.transform.position), a => { return(a.neighbors.Where(b => b.gameObject.activeSelf).Select(n => new Arc <Node>().SetArc(n, Vector3.Distance(n.transform.position, a.transform.position)))); } ); while (path.Count > 0) { ent.transform.forward = new Vector3(path.Peek().transform.position.x - ent.transform.position.x, ent.transform.forward.y, path.Peek().transform.position.z - ent.transform.position.z); ent.transform.position += ent.transform.forward * Mathf.Min(Vector3.Distance(path.Peek().transform.position, ent.transform.position), ent.speed * Time.deltaTime); if (Vector3.Distance(path.Peek().transform.position, ent.transform.position) <= 2f) { path.Pop(); } yield return(new WaitForEndOfFrame()); } ent.Current.Keys.Add(target.keyId); target.gameObject.SetActive(false); ent.Sequence.First().Effects(ent.Current, ent.Current); ent.Sequence = ent.Sequence.Skip(1); if (ent.Sequence.Count() > 0) { ent.Sequence.First().Act(ent); } }
/** * Returns a list of Flat Hex Points including the start and end points * accounting for isAccesible and cost for each cell along the path * */ public List <FlatHexPoint> getGridPath(FlatHexPoint start, FlatHexPoint end) { List <FlatHexPoint> path = new List <FlatHexPoint> (); var _path = Algorithms.AStar <SectorCell, FlatHexPoint> (Grid, start, end, (p, q) => p.DistanceFrom(q), c => c.isAccessible, (p, q) => (Grid [p].Cost + Grid [q].Cost / 2) ); foreach (var step in _path) { path.Add(step); } return(path); }
private void SelectLastPoint(RectPoint point) { cellSelectionState = 0; point1 = point; var path = Algorithms.AStar(grid, point0, point1, (p, q) => p.DistanceFrom(q), cell => !cell.HighlightOn, (p, q) => p.DistanceFrom(q)); foreach (var pathPoint in path.ButFirst()) { var bigPathPoint = grid.GetBigPoint(pathPoint); var smallPathPoint = grid.GetSmallPoint(pathPoint); var pathMarker = Instantiate(pathPrefab); pathMarker.name = (""); pathMarker.Color = Color.black; pathMarker.transform.parent = pathRoot.transform; pathMarker.transform.localScale = Vector3.one * 4; pathMarker.transform.localPosition = bigMap[bigPathPoint] + smallMap[smallPathPoint] - Vector3.forward; } }
public static IEnumerator GetToolCoroutine(GOAPEntity ent, ToolType type) { Node startingPoint = NodeList.allNodes.OrderBy(a => { return(Vector3.Distance(a.transform.position, ent.transform.position)); }).First(); ToolNode target = NodeList.allNodes .Select(a => { return(a.GetComponent <ToolNode>()); }) .Where(a => a != null && a.gameObject.activeSelf && a.type == type) .OrderBy(a => { return(Vector3.Distance(a.transform.position, ent.transform.position)); }) .First(); var path = Algorithms.AStar( startingPoint, a => a == target, a => Vector3.Distance(target.transform.position, a.transform.position), a => { return(a.neighbors.Where(b => b.gameObject.activeSelf).Select(n => new Arc <Node>().SetArc(n, Vector3.Distance(n.transform.position, a.transform.position)))); } ); while (path.Count > 0) { ent.transform.forward = new Vector3(path.Peek().transform.position.x - ent.transform.position.x, ent.transform.forward.y, path.Peek().transform.position.z - ent.transform.position.z); ent.transform.position += ent.transform.forward * Mathf.Min(Vector3.Distance(path.Peek().transform.position, ent.transform.position), ent.speed * Time.deltaTime); if (Vector3.Distance(path.Peek().transform.position, ent.transform.position) <= 2f) { path.Pop(); } yield return(new WaitForEndOfFrame()); } target.transform.GetChild(0).parent = ent.transform; target.gameObject.SetActive(false); ent.Sequence.First().Effects(ent.Current, ent.Current); ent.Sequence = ent.Sequence.Skip(1); if (ent.Sequence.Count() > 0) { ent.Sequence.First().Act(ent); } }
public void ExploreDungeon(bool checkEnemies) { // expMap // -1 : impassable // 0 : uncharted (WHITE) // 1 : observed through FOV (GREY) // 2 : Visited or having no explorable tiles (BLACK) var expMap = Map.ExplorationMap; var moveRange = Speed / 5; var diagonalCount = 0; //bool foundLootable = false; //AdventureEntity currentLoot = null; while (moveRange > 0) { // check if we have an enemy in fov if (checkEnemies && CombatState == CombatState.None) { // check field of view positions for enemies foreach (var entity in Map.EntitiesOnCoords(FovCoords).Where(p => p.IsAlive)) { if (entity.Faction == Faction.None) { continue; } if (Faction != entity.Faction) { CombatState = CombatState.Initiation; entity.CombatState = CombatState.Initiation; } } // break if we have found an enemy if (CombatState == CombatState.Initiation) { break; } } // check if we have lootable entities in fov if (!_foundLootable && LootablesInSight(out var lootableEntities)) { // Searching for the nearest reachable loot. Coord[] nearestPath = null; foreach (var loot in lootableEntities) { //System.Console.WriteLine($"Is in reach {loot.Name}? {IsInReach(loot)}"); if (IsInReach(loot)) { //System.Console.WriteLine($"looting {loot.Name}"); Loot(loot); continue; } var path = Algorithms.AStar(Coordinate, loot.Coordinate, Map); if (nearestPath == null) { nearestPath = path; _currentLoot = loot; } else if (path != null && nearestPath.Length > path.Length) { nearestPath = path; _currentLoot = loot; } } if (nearestPath != null) { // Set a path for the objective. _foundLootable = true; _lastPath = nearestPath; _pathIndex = 2; if (!MoveAtomic(nearestPath[1], ref moveRange, ref diagonalCount)) { return; } continue; } } else if (_foundLootable && IsInReach(_currentLoot)) { Loot(_currentLoot); _foundLootable = false; _currentLoot = null; } // check if already have a path if (_pathIndex > 0) { if (_pathIndex != _lastPath.Length) { if (Coordinate == _lastPath[_pathIndex - 1]) { if (!MoveAtomic(_lastPath[_pathIndex++], ref moveRange, ref diagonalCount)) { return; } continue; } } else if (_foundLootable) { // This branch means this entity follows a proper path to the current loot, // and in terms of path there is only 1 step left to the loot // but the one step is diagonal so that it is not reachable from the current coordinate. // To handle this problem, set the next coordinate as one of the cardinally adjacent tiles // of the loot. if (Math.Abs(Coord.EuclideanDistanceMagnitude(_currentLoot.Coordinate - Coordinate) - 2) < float.Epsilon) { var loot = _currentLoot.Coordinate; var projected = loot.Translate(0, -(loot - Coordinate).Y); // Prefer X direction for now; can be randomized if (Map.WalkabilityMap[projected]) { MoveAtomic(projected, ref moveRange, ref diagonalCount); } else { projected = loot.Translate(-(loot - Coordinate).X, 0); if (Map.WalkabilityMap[projected]) { MoveAtomic(projected, ref moveRange, ref diagonalCount); } else { _foundLootable = false; _currentLoot = null; } } } else { _foundLootable = false; _currentLoot = null; } } } _pathIndex = -1; // Atomic movement; consider adjacent tiles first var adjs = Algorithms.GetReachableNeighbors(Map.WalkabilityMap, Coordinate); var max = 0; var maxIndex = -1; for (var i = 0; i < adjs.Length; i++) { // Not consider Black tiles if (expMap[adjs[i]] == 2) { continue; } var c = Map.ExpectedFovNum[adjs[i].X, adjs[i].Y]; // Calculate which adjacent tile has the greatest number of expected FOV tiles if (max < c) { max = c; maxIndex = i; } } Coord next; // If all adjacent tiles are Black, explorer have to find the nearest grey tile. if (maxIndex < 0) { Coord[] nearest; // Consider grey tiles in FOV first. If not any, check the whole map var inFov = FovCoords .Where(c => expMap[c] == 1) .ToArray(); if (inFov.Length > 0) { nearest = inFov .Select(c => Algorithms.AStar(Coordinate, c, Map)) .OrderBy(p => p.Length) .First(); } else { nearest = expMap.Positions() .Where(c => expMap[c] == 1) .OrderBy(p => Distance.EUCLIDEAN.Calculate(Coordinate, p)) .Take(5) .Where(p => p != Coord.NONE) .Select(p => Algorithms.AStar(Coordinate, p, Map)) .OrderBy(p => p.Length) .First(); } if (nearest?.Length < 2) { for (int i = 0; i < expMap.Width; i++) { for (int j = 0; j < expMap.Height; j++) { expMap[i, j] = 2; } } return; } next = nearest[1]; // Save the path _lastPath = nearest; _pathIndex = 2; } else { next = adjs[maxIndex]; } if (!MoveAtomic(next, ref moveRange, ref diagonalCount)) { return; } } }
public void WalkTo(Coord coord, bool checkForEnemies) { // expMap // -1 : impassable // 0 : uncharted (WHITE) // 1 : observed through FOV (GREY) // 2 : Visited or having no explorable tiles (BLACK) var moveRange = Speed / 5; var diagonalCount = 0; while (moveRange > 0) { // check if we have an enemy in fov if (checkForEnemies && CombatState == CombatState.None) { // check field of view positions for enemies foreach (var entity in Map.EntitiesOnCoords(FovCoords).Where(p => p.IsAlive)) { if (entity.Faction == Faction.None) { continue; } if (Faction != entity.Faction) { CombatState = CombatState.Initiation; entity.CombatState = CombatState.Initiation; } } // break if we have found an enemy if (CombatState == CombatState.Initiation) { break; } } // check if already have a path if (_pathIndex > 0 && _pathIndex != _lastPath.Length) { if (Coordinate == _lastPath[_pathIndex - 1]) { if (!MoveAtomic(_lastPath[_pathIndex++], ref moveRange, ref diagonalCount)) { return; } continue; } } _pathIndex = -1; var nearest = Algorithms.AStar(Coordinate, coord, Map); var next = nearest[1]; // Save the path _lastPath = nearest; _pathIndex = 2; if (!MoveAtomic(next, ref moveRange, ref diagonalCount)) { return; } } }