Пример #1
0
        protected virtual void CheckState()
        {
            //refresh state to take new variables state
            ChangeState(state);

            switch (state)
            {
            case AntState.lookForFood:
                if (food != null)
                {
                    ChangeState(AntState.goToFood);
                }
                break;

            case AntState.goToFood:
                if (food.Amount == 0 && Vector2.Distance(foodPosition, Position) < ConstantsHolder.Singleton.Vision)
                {
                    food = null;
                    ChangeState(AntState.lookForFood);
                    break;
                }
                if (Vector2.Distance(foodPosition, Position) < ConstantsHolder.Singleton.EatingRadius)
                {
                    foodCarried  = ConstantsHolder.Singleton.CarryMax;
                    food.Amount -= ConstantsHolder.Singleton.CarryMax;
                    ChangeState(AntState.bringBackFood);
                }
                break;

            case AntState.bringBackFood:
                if (Vector2.Distance(AntHill.Position, Position) < ConstantsHolder.Singleton.EatingRadius)
                {
                    game.AntHill.Food += foodCarried;
                    foodCarried        = 0;
                    ChangeState(AntState.goToFood);
                }
                break;

            case AntState.transportCorpse:
                cadaver.Position = position;
                //if the ant don't know a cemetery it will just put the corpse at a sanitary distance of the anthill
                if (cemeteryBest == null)
                {
                    if (Vector2.Distance(position, antHill.Position) > ConstantsHolder.Singleton.SainityDistance)
                    {
                        //double tap!
                        cadaver.Kill();
                        if (leftToClean > 0)
                        {
                            ChangeState(AntState.backToClean);
                        }
                        else
                        {
                            ChangeState(previousState);
                        }
                    }
                }
                else
                {
                    // the ant reaches the biggest known cemetery it put the cadaver in the cemetery
                    if (Vector2.Distance(goal, Position) < ConstantsHolder.Singleton.EatingRadius)
                    {
                        //if the best known have desapeared the ant just put the corpse at a sanitary distance from the anthill
                        if (cemeteryBest.Count == 0)
                        {
                            cemeteryBest = null;
                            //double tap!
                            cadaver.Kill();
                        }
                        else
                        {
                            cemeteryBest.Add(cadaver);
                        }
                        cadaver = null;
                        //go back to clean the previous cemetery if it is not known as empty
                        if (leftToClean > 0)
                        {
                            ChangeState(AntState.backToClean);
                        }
                        else
                        {
                            ChangeState(previousState);
                        }
                        break;
                    }
                }

                break;

            case AntState.goToCorpse:
                if (Vector2.Distance(goal, Position) < ConstantsHolder.Singleton.EatingRadius)
                {
                    //take a cadaver in a cemetery when it reach it
                    if (cemeteryToClean.Contains(cadaver))
                    {
                        cemeteryToClean.Remove(cadaver);
                        leftToClean = cemeteryToClean.Count;
                        //if taking the corpse clean the cemetery it will be destroyed
                        if (cemeteryToClean.Count == 0)
                        {
                            game.Cemeteries.Remove(cemeteryToClean);
                            cemeteryToClean = null;
                        }

                        ChangeState(AntState.transportCorpse);
                    }
                    //if the corpse have been taken by an other ant, it return to normal activity
                    else
                    {
                        ChangeState(previousState);
                    }
                }
                break;

            //go back the previous cemetery to clean it
            case AntState.backToClean:
                //if the cemetery is empty the ant remove it and go back to its activity
                //if it's full the ant will automatically change state to goforCorpse from the cemetery scan in the update function
                if (Vector2.Distance(goal, Position) < ConstantsHolder.Singleton.Vision)
                {
                    if (cemeteryToClean == null || cemeteryToClean.Count == 0)
                    {
                        leftToClean     = 0;
                        cemeteryToClean = null;
                        if (previousState == AntState.backToClean)
                        {
                            previousState = AntState.lookForFood;
                        }
                        ChangeState(previousState);
                    }
                }
                break;
            }
        }
Пример #2
0
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
            //the ant have a certain probability to die each frame
            double ran = game.Random.NextDouble();

            if (ran < 0.5f / ConstantsHolder.Singleton.HalfLife)
            {
                Kill();
            }
            CheckState();
            if (Vector2.Distance(AntHill.Position, Position) < ConstantsHolder.Singleton.EatingRadius)
            {
                if (AntHill.Food >= 0)
                {
                    AntHill.Food -= Hungry;
                    Hungry        = 0;
                }
            }
            if (Hungry > ConstantsHolder.Singleton.Starvation)
            {
                Kill();
            }

            //find closest food point
            foreach (Food possibleFood in game.Foods)
            {
                if (Vector2.Distance(possibleFood.Position, Position) < ConstantsHolder.Singleton.Vision &&
                    (food == null || Vector2.Distance(possibleFood.Position, AntHill.Position) < Vector2.Distance(food.Position, AntHill.Position)))
                {
                    food         = possibleFood;
                    foodPosition = possibleFood.Position;
                    if (state == AntState.goToFood)
                    {
                        goal = food.Position;
                    }
                }
            }

            //find bigest cemetery around
            for (int i = 0; i < game.Cemeteries.Count; i++)
            {
                Cemetery possibleCemetery = game.Cemeteries[i];
                //within view range
                if (Vector2.Distance(possibleCemetery.Position, Position) < ConstantsHolder.Singleton.Vision &&
                    possibleCemetery.Count != 0)
                {
                    //find bigest cemetery
                    if (Vector2.Distance(possibleCemetery.Position, antHill.Position) >= ConstantsHolder.Singleton.SainityDistance &&
                        (cemeteryBest == null || possibleCemetery.Count > cemeterySmell))
                    {
                        //if the ant had a previous best cemetery, it decided to move it in the new one
                        bool needToClean = false;
                        if (cemeteryBest != null &&
                            cemeteryBest != possibleCemetery &&
                            state != AntState.goToCorpse &&
                            state != AntState.transportCorpse)
                        {
                            cemeteryToClean    = cemeteryBest;
                            cemeteryToCleanPos = cemeteryToClean.Position;
                            previousState      = state;
                            needToClean        = true;
                        }
                        //update the biggest known cemetery
                        cemeteryBest  = possibleCemetery;
                        cemeterySmell = possibleCemetery.Count;
                        if (state == AntState.transportCorpse)
                        {
                            goal      = possibleCemetery.Position;
                            goalLover = ConstantsHolder.Singleton.TransportGoal;
                        }
                        //start to clean the old cemetery
                        if (needToClean)
                        {
                            ChangeState(AntState.backToClean);
                        }
                    }
                    ////with a decent distance to the hill
                    //if (Vector2.Distance(possibleCemetery.Position, antHill.Position) >= ConstantsHolder.Singleton.SainityDistance
                    //    && (cemeteryBest == null || possibleCemetery.Count > cemeterySmell))
                    //{
                    //    bool needToClean = false;
                    //    if (cemeteryBest != null
                    //        && cemeteryBest != possibleCemetery
                    //        && state != AntState.goToCorpse
                    //        && state != AntState.transportCorpse)
                    //    {
                    //        cemeteryToClean = cemeteryBest;
                    //        cemeteryToCleanPos = cemeteryToClean.Position;
                    //        previousState = state;
                    //        needToClean = true;
                    //    }
                    //    cemeteryBest = possibleCemetery;
                    //    cemeterySmell = possibleCemetery.Count;
                    //    if (state == AntState.transportCorpse)
                    //    {
                    //        goal = possibleCemetery.Position;
                    //        goalLover = ConstantsHolder.Singleton.TransportGoal;
                    //    }
                    //    if (needToClean)
                    //    {
                    //        ChangeState(AntState.backToClean);
                    //    }
                    //}

                    //Update the size of the biggest known cemetery
                    if (possibleCemetery == cemeteryBest)
                    {
                        cemeterySmell = possibleCemetery.Count;
                    }
                    //if the cemetery seen is not the biggest the ant start to clean it
                    //if the ant is not already carrying a corpse a going to a corpse
                    else if (state != AntState.goToCorpse && state != AntState.transportCorpse)
                    {
                        cadaver = possibleCemetery.Last();
                        //handle a little bug that sometime the cemetery have one null cadaver instead of nothing
                        //it would be maybe cleaner to prevent that
                        if (cadaver != null)
                        {
                            cemeteryToClean    = possibleCemetery;
                            cemeteryToCleanPos = cemeteryToClean.Position;
                            previousState      = state;
                            //remember the size to know if there is a need to come back to clean
                            leftToClean = cemeteryToClean.Count;
                            ChangeState(AntState.goToCorpse);
                        }
                        else
                        {
                            //we don't keep empty cemeteries
                            game.Cemeteries.Remove(possibleCemetery);
                            if (state == AntState.backToClean)
                            {
                                cemeteryToClean = null;
                                ChangeState(previousState);
                            }
                        }
                    }
                }
            }

            this.previousPosition = this.position;
        }