Example #1
0
    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);
        }
Example #3
0
        /// <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);
        }
Example #4
0
        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);
        }
Example #5
0
    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);
        }
    }
Example #6
0
    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];
            }
        }
    }
Example #7
0
    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));
    }
Example #8
0
    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);
        }
    }
Example #9
0
    /**
     * 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);
    }
Example #10
0
    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;
        }
    }
Example #11
0
    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);
        }
    }
Example #12
0
        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;
                }
            }
        }
Example #13
0
        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;
                }
            }
        }