Ejemplo n.º 1
0
    public void MoveAnt(AntInfo ant, HexInfo hex)
    {
        var oldHex = ant.Hex;

        oldHex.HasAnt    = false;
        hex.HasAnt       = true;
        ant.Hex          = hex;
        ant.LastLocation = oldHex.Coordinates;

        // move ant
        ant.Ant.transform.DOMove(Master.MasterHex.CalculatePosition(hex.Coordinates.x, hex.Coordinates.y), Master.CoreGameLoopFrequency).SetEase(Ease.Linear);

        // move food if ant is carrying
        if (ant.Food != null)
        {
            ant.Food.transform.DOMove(Master.MasterHex.CalculatePosition(hex.Coordinates.x, hex.Coordinates.y), Master.CoreGameLoopFrequency).SetEase(Ease.Linear);
        }

        // uncomment this if you want to see where the ants have been
        //Master.MasterHex.HighlightHex(hex.Coordinates, Color.green);

        ant.Energy--; // spend energy
        ant.LastTurn = Master.GameTurn;

        hex.LastTouched = Master.GameTurn;
    }
Ejemplo n.º 2
0
        private void Solve()
        {
            _antThread = Thread.CurrentThread;
            InitializeMatrixes();
            List <AntInfo> allAnts = new List <AntInfo>();

            while (true)
            {
                allAnts.Clear();
                for (int i = 0; i < _ants; i++)
                {
                    bool    findingRoute = true;
                    AntInfo ant          = new AntInfo(_data.Vertexes.Count);

                    while (findingRoute)
                    {
                        bool isTruckFull = CheckCurrentCapacity(ant);
                        ant.NextVertex = isTruckFull == false?FindNewVertex(ant) : 0;

                        ActualizeCurrentRoute(ant);
                        if (ant.DepotVisiting == _data.TrucksNumber || CheckEndOfRoute(ant))
                        {
                            findingRoute = false;
                        }
                    }
                    allAnts.Add(ant);
                }
                AverageRouteInfo(allAnts);
                ActualizePheromones(allAnts);
            }
        }
Ejemplo n.º 3
0
 private bool CheckCurrentCapacity(AntInfo ant)
 {
     for (int i = 1; i < ant.Visited.Length; i++)
     {
         if (ant.Visited[i] == false && _data.TruckCapacity >= ant.CurrentCapacity + _data.Vertexes[i].Demand)
         {
             return(false);
         }
     }
     return(true);
 }
Ejemplo n.º 4
0
        private bool CheckEndOfRoute(AntInfo ant)
        {
            for (int i = 1; i < ant.Visited.Length; i++)
            {
                if (ant.Visited[i] == false)
                {
                    return(false);
                }
            }

            return(ant.CurrentVertex == 0);
        }
Ejemplo n.º 5
0
    public GameObject RespawnAntAt(AntInfo ant, Vector2Int coords)
    {
        ant.Ant.transform.DOMove(Master.MasterHex.CalculatePosition(coords.x, coords.y), 0F);

        HexInfo hex = Master.MasterHex.GetHexInfoAt(coords);

        ant.InitializeAnt(ant.Ant, hex, Master.GameTurn, MaxAntEnergy);
        CurrentAnts.Add(ant);

        var antHex = Master.MasterHex.GetHexInfoAt(coords);

        MoveAnt(ant, antHex);
        return(ant.Ant);
    }
Ejemplo n.º 6
0
        private void ActualizeCurrentRoute(AntInfo ant)
        {
            if (ant.NextVertex == 0)
            {
                ant.CurrentCapacity = 0;
                ant.DepotVisiting  += 1;
            }
            else
            {
                ant.Visited[ant.NextVertex] = true;
            }

            ant.CurrentRoute.Add(ant.NextVertex);
            ant.CurrentDistance += _distances[ant.CurrentVertex, ant.NextVertex];
            ant.CurrentCapacity += _data.Vertexes[ant.NextVertex].Demand;
            ant.CurrentVertex    = ant.NextVertex;
        }
Ejemplo n.º 7
0
    private bool MoveToTarget(AntInfo ant, HexInfo target)
    {
        if (target == null)
        {
            return(false);
        }

        if (!target.IsEmpty || ant.Hex == target ||
            Vector2Int.Distance(ant.Hex.Coordinates, target.Coordinates) >= 2)
        {
            return(false);
        }

        MoveAnt(ant, target);

        return(true);
    }
Ejemplo n.º 8
0
        private double[] CalculateProbabilities(AntInfo ant)
        {
            double sum   = 0.0;
            int    count = _data.Vertexes.Count;

            double[] probabilities = new double[count];
            bool[]   available     = new bool[count];
            int      currentVertex = ant.CurrentVertex;

            for (int i = 0; i < count; i++)
            {
                if (i == 0 || i == currentVertex || ant.Visited[i] ||
                    _data.TruckCapacity < ant.CurrentCapacity + _data.Vertexes[i].Demand)
                {
                    available[i] = false;
                }
                else
                {
                    available[i] = true;
                    sum         += Math.Pow(_pheromones[currentVertex, i], alfa) * Math.Pow(_heuristics[currentVertex, i], beta);
                }
            }

            for (int i = 0; i < count; i++)
            {
                if (available[i])
                {
                    probabilities[i] = (Math.Pow(_pheromones[currentVertex, i], alfa) * Math.Pow(_heuristics[currentVertex, i], beta)) / sum;
                }
                else
                {
                    probabilities[i] = 0;
                }
            }

            return(probabilities);
        }
Ejemplo n.º 9
0
        private int FindNewVertex(AntInfo ant)
        {
            bool notFound   = true;
            int  nextVertex = ant.CurrentVertex;

            double[] probabilities = CalculateProbabilities(ant);
            int      tries         = 1;
            int      maxTries      = 10;
            int      count         = ant.Visited.Length;
            int      i             = _rand.Next(0, count - 1);

            while (notFound)
            {
                i++;

                if (i >= count)
                {
                    i = 1;
                    tries++;
                }

                if (ant.CurrentVertex == i || ant.Visited[i])
                {
                    continue;
                }

                if (MyRandom(probabilities[i]) || tries > maxTries)
                {
                    nextVertex = i;
                    notFound   = false;
                    break;
                }
            }

            return(nextVertex);
        }
Ejemplo n.º 10
0
    private bool MoveToFarTarget(AntInfo ant, HexInfo target)
    {
        if (target == null)
        {
            return(false);
        }

        var farTargets = target.AdjacentSpaces.NonAdjacentTo(target.Coordinates);

        foreach (var space in farTargets)
        {
            var hex = Master.MasterHex.GetHexInfoAt(space);
            if (hex == null)
            {
                continue;
            }
            if (MoveToTarget(ant, hex))
            {
                return(true);
            }
        }

        return(false);
    }
Ejemplo n.º 11
0
    private bool MoveToAnyTarget(AntInfo ant, List <HexInfo> area)
    {
        var hex = area.Where(x => x.IsEmpty).RandomElement();

        return(MoveToTarget(ant, hex));
    }
Ejemplo n.º 12
0
    private void AntAct(AntInfo ant)
    {
        var myHex         = ant.Hex;
        var myLocation    = myHex.Coordinates;
        var adjacentHexes = Master.MasterHex.GetNeighboringHexInfo(myLocation.x, myLocation.y, false);
        var preferHexes   = adjacentHexes.Where(x => x.IsPathable).ToList();

        HexInfo moveTarget = null;

        // GENERAL
        // are we standing next to food?
        var foodHex = adjacentHexes.FirstOrDefault(x => x.HasPellet);

        if (foodHex != null)
        {
            myHex.FoodInfo.Distance    = 1;
            myHex.FoodInfo.Coordinates = foodHex.Coordinates;
            myHex.FoodInfo.LastUpdated = Master.GameTurn;
        }
        else
        {
            var bestFoodHex = adjacentHexes.Where(x => x.FoodInfo.Distance > 0 &&
                                                  x.FoodInfo.Coordinates != myHex.Coordinates &&
                                                  x.FoodInfo.Coordinates != ant.LastLocation &&
                                                  (myHex.FoodInfo.Distance == 0 || myHex.FoodInfo.Distance > x.FoodInfo.Distance))
                              .OrderBy(x => x.FoodInfo.Distance)
                              .FirstOrDefault();

            myHex.FoodInfo.Distance    = bestFoodHex == null ? 0 : bestFoodHex.FoodInfo.Distance + 1;
            myHex.FoodInfo.Coordinates = bestFoodHex == null ? myHex.Coordinates : bestFoodHex.Coordinates;
            myHex.FoodInfo.LastUpdated = Master.GameTurn;
        }

        // can we drop off food?
        if (ant.HasFood && adjacentHexes.Any(x => x.IsColony))
        {
            // made it home! store the food
            Destroy(ant.Food);
            ant.Food    = null;
            ant.HasFood = false;
            FoodStored++;
        }

        // are we standing next to the colony?
        var homeHex = adjacentHexes.FirstOrDefault(x => x.IsColony);

        if (homeHex != null)
        {
            myHex.HomeInfo.Distance    = 1;
            myHex.HomeInfo.Coordinates = homeHex.Coordinates;
            myHex.HomeInfo.LastUpdated = Master.GameTurn;
        }
        else
        {
            var bestHomeHex = adjacentHexes.Where(x => x.HomeInfo.Distance > 0 &&
                                                  x.HomeInfo.Coordinates != myHex.Coordinates &&
                                                  x.HomeInfo.Coordinates != ant.LastLocation &&
                                                  (myHex.HomeInfo.Distance == 0 || myHex.HomeInfo.Distance > x.HomeInfo.Distance))
                              .OrderBy(x => x.HomeInfo.Distance)
                              .FirstOrDefault();

            myHex.HomeInfo.Distance    = bestHomeHex == null ? 0 : bestHomeHex.HomeInfo.Distance + 1;
            myHex.HomeInfo.Coordinates = bestHomeHex == null ? myHex.Coordinates : bestHomeHex.Coordinates;
            myHex.HomeInfo.LastUpdated = Master.GameTurn;
        }

        // EAT
        if (ant.AllowedEat && ant.IsHungry && FoodStored > 0)
        {
            if (adjacentHexes.Any(x => x.IsColony))
            {
                // made it home! de-spawn
                DespawnAnts.Add(ant);
                RestingOccupany++;
                return; // this ant is done
            }
            moveTarget = FindHomeTarget(preferHexes);
        }


        // GATHER
        if (ant.AllowedGather && moveTarget == null)
        {
            // can we pickup food?
            if (!ant.HasFood && foodHex != null)
            {
                // Pickup the food
                var food = Master.MasterFood.CurrentFood[foodHex.Coordinates];
                Master.MasterFood.CurrentFood.Remove(foodHex.Coordinates);

                ant.Food          = food;
                ant.HasFood       = true;
                foodHex.HasPellet = false;

                ant.Food.transform.DOMove(Master.MasterHex.CalculatePosition(ant.Hex.Coordinates.x, ant.Hex.Coordinates.y), 0F)
                .SetEase(Ease.Linear);
            }

            // are we carrying food?
            if (ant.HasFood)
            {
                moveTarget = FindHomeTarget(preferHexes);
            }

            // are we looking for food?
            if (!ant.HasFood)
            {
                moveTarget = FindFoodTarget(preferHexes);

                if (moveTarget != null && myHex.FoodInfo.Distance > 0 && moveTarget.FoodInfo.Distance > 0 &&
                    moveTarget.FoodInfo.Distance > myHex.FoodInfo.Distance)
                {
                    moveTarget = null; // prefer exploration instead of backtracking for food
                }
            }
        }


        // EXPLORE
        if (ant.AllowedExplore && moveTarget == null)
        {
            moveTarget = FindSearchTarget(preferHexes);
        }


        // ANARCHY
        if (moveTarget == null)
        {
            moveTarget = preferHexes.RandomElement();
        }

        // attempt to move to target
        if (!MoveToTarget(ant, moveTarget))
        {
            // attempt to move near target
            if (!MoveToNearTarget(ant, moveTarget))
            {
                // move far from target
                if (!MoveToFarTarget(ant, moveTarget))
                {
                    // move anywhere!
                    MoveToAnyTarget(ant, adjacentHexes);
                }
            }
        }
    }