Пример #1
0
        // todo: keep track of the last generation of ants that were alive... then average out
        //       all of their characteristics at the end, and analyze the difference between
        //       the starting 10 ants and the last generation of ants

        //  todo: implement DISEASE factor; it's a green spot that when stepped on produces disease
        //  that wears down an ant's health. it can be passed on randomly to adjacent ants
        //             and it becomes more severe with time until the ants die.


        protected override void Initialize()
        {
            debugMessage      = "";
            lastFoodSpawnTime = 0;

            //seeded by time
            rng = new Random((int)DateTime.Now.Ticks);

            //  TODO: store generations in an array in Statistics

            //  TODO: represent ants that are dead with a new icon

            foodSpawnInterval = 10; // how many seconds before food should respawn
            GRID_WIDTH        = (3 * ((int)(7 * (rng.NextDouble() * .7 + .3))));
            GRID_HEIGHT       = (int)((2f / 3f) * GRID_WIDTH);

            STARTING_ANTS = (int)((rng.NextDouble() * .15) * GRID_WIDTH * GRID_HEIGHT) + 2;
            if (STARTING_ANTS > 20)
            {
                STARTING_ANTS = 20;
            }

            numberOfFoodsSpawned = (int)((rng.NextDouble() * .10) * GRID_WIDTH * GRID_HEIGHT) + 1; // how many foods made

            Statistics.EXTREME_MUTATION_CHANCE = rng.NextDouble() * .5;
            Statistics.runTimeInSeconds        = 0;

            LINE_THICKNESS = 0;
            gameState      = Statistics.GameState.ANTS_SCREEN;
            secondsCounter = 30.0;

            cursor = new SpriteSheet(Content.Load <Texture2D>("cursorSheet"), 50, 50);
            cursor.SetScale(TILE_WIDTH, TILE_HEIGHT);
            Statistics.birthEffects = new List <BirthEffect>();
            Statistics.foodEffects  = new List <FoodEffect>();
            Statistics.foodFades    = new List <FoodFade>();

            numberOfSecondsBeforeRoundEnds = 100;

            // TODO: remember to check that ALL statistics.attributes are refreshed
            // TODO: have a Dictionary that returns a list of ants associated with a particular generation number
            Statistics.numberOfMovements         = 0;
            Statistics.longestAgeLived           = 0;
            Statistics.largestNumberOfChildren   = 0;
            Statistics.largestNumberOfFoodsEaten = 0;
            Statistics.topFiveAncestors          = new List <Ant>();
            Statistics.largestPopulation         = 0;
            Statistics.longestGenerationLived    = 0;

            Statistics.timeOfLastMovement = 0;
            Statistics.systemHasMoved     = false;

            Statistics.totalFoods        = 0;
            Statistics.totalNumberOfAnts = 0;

            grid = new Entity[GRID_WIDTH, GRID_HEIGHT];

            SIDE_PANEL_WIDTH = (int)(graphics.GraphicsDevice.Viewport.Width * .2f);

            SCREEN_WIDTH  = graphics.GraphicsDevice.Viewport.Width - SIDE_PANEL_WIDTH;
            SCREEN_HEIGHT = graphics.GraphicsDevice.Viewport.Height;

            TILE_WIDTH  = SCREEN_WIDTH / GRID_WIDTH;
            TILE_HEIGHT = SCREEN_HEIGHT / GRID_HEIGHT;

            attributes = new Dictionary <string, double>();

            Statistics.attributeRange = new Dictionary <string, Vector2>();
            attributeRange            = Statistics.attributeRange;

            Statistics.firstAverages = new Dictionary <string, double>();
            Statistics.currentSum    = new Dictionary <string, double>();

            attributes["redColor"]     = 100; //RGB color scheme
            attributeRange["redColor"] = new Vector2(0, 255);

            attributes["blueColor"]     = 50;
            attributeRange["blueColor"] = new Vector2(0, 255);

            attributes["greenColor"]     = 70;
            attributeRange["greenColor"] = new Vector2(0, 255);

            attributes["mutationFactor"]     = .2;
            attributeRange["mutationFactor"] = new Vector2(0, 1);
            attributes["walkSpeed"]          = 1000.0; //  how many milliseconds it takes to move a single step
            attributeRange["walkSpeed"]      = new Vector2(100, 2000);

            attributes["desireForFood"]          = 100.0; //  how much this ant prioritizes collecting food
            attributeRange["desireForFood"]      = new Vector2(-4000, 4000);
            attributes["desireToFollowAnts"]     = 10.0;  //  how much this ant is willing to follow/avoid ants
            attributeRange["desireToFollowAnts"] = new Vector2(-300, 300);
            attributes["desireToExplore"]        = 1.0;   //  how much this ant is willing to explore new places
            attributeRange["desireToExplore"]    = new Vector2(-200, 200);
            attributes["desireToMate"]           = 500.0; // influenced by number of children
            attributeRange["desireToMate"]       = new Vector2(-600, 600);

            attributes["desireToContinueInSameDirection"]     = 1500.0; //  prevents equal-sum scenarios
            attributeRange["desireToContinueInSameDirection"] = new Vector2(-2000, 2000);
            attributes["desireToGoBackwards"]     = -1000.0;            //  prevents oscillation
            attributeRange["desireToGoBackwards"] = new Vector2(-1500, 1500);

            attributes["timeToReexplore"]     = 10.0;  //  how long (seconds) an ant remembers a spot
            attributeRange["timeToReexplore"] = new Vector2(1, 30);
            attributes["decayFactor"]         = 4.0;   //  analogous to the ant's sense of smell
            attributeRange["decayFactor"]     = new Vector2(1, 8);
            attributes["healthThreshold"]     = 200.0; //  if another ant meets this health threshold,
                                                       //   then the two will mate and produce offspring
            attributeRange["healthThreshold"] = new Vector2(1, 400);

            attributes["childbirthPercentage"]     = 21.0; // % chance of having child when threshold met
            attributeRange["childbirthPercentage"] = new Vector2(1, 100);
            attributes["childbirthCost"]           = 50.0; //  how much the parent pays to raise child
            attributeRange["childbirthCost"]       = new Vector2(1, 300);
            attributes["childbirthCooldown"]       = 10.0; //  how many seconds before having a child again
            attributeRange["childbirthCooldown"]   = new Vector2(5, 30);

            //attributes["health"] = 150.0;     //  health is restored by eating food,
            //  and it is lowered by moving around and taking damage
            //attributeRange["health"] = new Vector2(0, 300);

            //attributes["strength"] = 10.0; //  TODO: damage dealt in a hit to a predator. influences
            //  construction of buildings, too

            attributes["oldestPossibleAge"]     = 200.0; //  number of moves this ant can make before dying
            attributeRange["oldestPossibleAge"] = new Vector2(30, 400);

            attributes["eyesightRange"]     = 100.0; //  number of tiles this ant can see
            attributeRange["eyesightRange"] = new Vector2(3, 150);

            //attributes["resistance"] = 5.0; //  TODO: immunity to cold, poison, and disease

            //       also, social model vs individualistic model. social model is a shared diffusion.

            //attributes["shelterShape"] = 22.0; // TODO: this number gets rounded down when used in calculation.
            // base-2 representation of the truncated version is
            // used. each digit represents having or not having
            // a block in a certain location in a 5x5 grid.
            // digit ordering as follows: (1 = first digit's block location)
            // and alphabetical chars correspond to numbers beyond 9

            //  22 = 10110(b2) = _
            //                 _|  shape

            /*   PLDEM
             *   KC56F
             *   B4127
             *   JA38G
             *   OI9HN
             */

            line = new Texture2D(graphics.GraphicsDevice, 1, 1);
            line.SetData(new Color[] { Color.White });

            base.Initialize();
        }
Пример #2
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            KeyboardState keyboardState = Keyboard.GetState();
            if (keyboardState.IsKeyDown(Keys.Escape))
            {
                Exit();
            }
            else if (keyboardState.IsKeyDown(Keys.Space))
            {
                Statistics.totalNumberOfAnts = 0;
            }

            if (gameState == Statistics.GameState.ANTS_SCREEN)
            {
                numberOfSecondsBeforeRoundEnds -= gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0;

                Statistics.runTimeInSeconds += gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0;

                if (lastFoodSpawnTime == 0 || gameTime.TotalGameTime.TotalSeconds - lastFoodSpawnTime >= foodSpawnInterval)
                {
                    for (int i = 0; i < numberOfFoodsSpawned; i++)
                    {
                        Vector2 pos = new Vector2((int)rng.Next(GRID_WIDTH), (int)rng.Next(GRID_HEIGHT));

                        //  don't spawn food on top of other ants or foods
                        if (grid[(int)pos.X, (int)pos.Y] == null)
                        {
                            grid[(int)pos.X, (int)pos.Y] = new Food(rng);

                            grid[(int)pos.X, (int)pos.Y].SetPosition(pos);
                            grid[(int)pos.X, (int)pos.Y].SetSprite(foodSprite);

                            Statistics.totalFoods++;
                        }
                    }

                    lastFoodSpawnTime = gameTime.TotalGameTime.TotalSeconds;
                }

                foreach (Entity e in grid)
                {
                    if (e is Ant)
                    {
                        ((Ant)e).Update(grid, gameTime, rng);
                        //  note: update will null an ant that is dead
                    }

                    if (e != null)
                    {
                        char move = e.CreateMovement(grid, gameTime.TotalGameTime.TotalMilliseconds);
                        MoveInDirection(e, move);
                    }
                }

                if (Statistics.totalNumberOfAnts == 0 ||
                    (Math.Abs(gameTime.TotalGameTime.TotalSeconds - Statistics.timeOfLastMovement) > 30 && Statistics.systemHasMoved))
                {
                    //  if there have been 30 seconds w/o movement, then end
                    gameState = Statistics.GameState.STATISTICS_SCREEN;
                }
            }

            base.Update(gameTime);
        }
Пример #3
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            {
                this.Exit();
            }

            KeyboardState keyboardState = Keyboard.GetState();

            if (keyboardState.IsKeyDown(Keys.Escape))
            {
                Exit();
            }
            else if (keyboardState.IsKeyDown(Keys.Space))
            {
                Statistics.totalNumberOfAnts = 0;
            }

            if (gameState == Statistics.GameState.ANTS_SCREEN)
            {
                numberOfSecondsBeforeRoundEnds -= gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0;

                Statistics.runTimeInSeconds += gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0;

                if (lastFoodSpawnTime == 0 || gameTime.TotalGameTime.TotalSeconds - lastFoodSpawnTime >= foodSpawnInterval)
                {
                    for (int i = 0; i < numberOfFoodsSpawned; i++)
                    {
                        Vector2 pos = new Vector2((int)rng.Next(GRID_WIDTH), (int)rng.Next(GRID_HEIGHT));

                        //  don't spawn food on top of other ants or foods
                        if (grid[(int)pos.X, (int)pos.Y] == null)
                        {
                            grid[(int)pos.X, (int)pos.Y] = new Food(rng);

                            grid[(int)pos.X, (int)pos.Y].SetPosition(pos);
                            grid[(int)pos.X, (int)pos.Y].SetSprite(foodSprite);

                            Statistics.totalFoods++;
                        }
                    }

                    lastFoodSpawnTime = gameTime.TotalGameTime.TotalSeconds;
                }

                foreach (Entity e in grid)
                {
                    if (e is Ant)
                    {
                        ((Ant)e).Update(grid, gameTime, rng);
                        //  note: update will null an ant that is dead
                    }

                    if (e != null)
                    {
                        char move = e.CreateMovement(grid, gameTime.TotalGameTime.TotalMilliseconds);
                        MoveInDirection(e, move);
                    }
                }

                if (Statistics.totalNumberOfAnts == 0 ||
                    (Math.Abs(gameTime.TotalGameTime.TotalSeconds - Statistics.timeOfLastMovement) > 30 && Statistics.systemHasMoved))
                {
                    //  if there have been 30 seconds w/o movement, then end
                    gameState = Statistics.GameState.STATISTICS_SCREEN;
                }
            }

            base.Update(gameTime);
        }
Пример #4
0
        // todo: keep track of the last generation of ants that were alive... then average out
        //       all of their characteristics at the end, and analyze the difference between
        //       the starting 10 ants and the last generation of ants
        //  todo: implement DISEASE factor; it's a green spot that when stepped on produces disease
        //  that wears down an ant's health. it can be passed on randomly to adjacent ants
        //             and it becomes more severe with time until the ants die.
        protected override void Initialize()
        {
            debugMessage = "";
            lastFoodSpawnTime = 0;

            //seeded by time
            rng = new Random((int)DateTime.Now.Ticks);

            //  TODO: store generations in an array in Statistics

            //  TODO: represent ants that are dead with a new icon

            foodSpawnInterval = 10; // how many seconds before food should respawn
            GRID_WIDTH = (3 * ((int) (7* (rng.NextDouble() * .7 + .3))));
            GRID_HEIGHT = (int)((2f/3f)*GRID_WIDTH);

            STARTING_ANTS = (int)((rng.NextDouble()*.15)*GRID_WIDTH*GRID_HEIGHT) + 2;
            if (STARTING_ANTS > 20) STARTING_ANTS = 20;

            numberOfFoodsSpawned = (int)((rng.NextDouble()*.10)*GRID_WIDTH*GRID_HEIGHT)+1; // how many foods made

            Statistics.EXTREME_MUTATION_CHANCE = rng.NextDouble() * .5;
            Statistics.runTimeInSeconds = 0;

            LINE_THICKNESS = 0;
            gameState = Statistics.GameState.ANTS_SCREEN;
            secondsCounter = 30.0;

            cursor = new SpriteSheet(Content.Load<Texture2D>("cursorSheet"), 50, 50);
            cursor.SetScale(TILE_WIDTH, TILE_HEIGHT);
            Statistics.birthEffects = new List<BirthEffect>();
            Statistics.foodEffects = new List<FoodEffect>();
            Statistics.foodFades = new List<FoodFade>();

            numberOfSecondsBeforeRoundEnds = 100;

            // TODO: remember to check that ALL statistics.attributes are refreshed
            // TODO: have a Dictionary that returns a list of ants associated with a particular generation number
            Statistics.numberOfMovements = 0;
            Statistics.longestAgeLived = 0;
            Statistics.largestNumberOfChildren = 0;
            Statistics.largestNumberOfFoodsEaten = 0;
            Statistics.topFiveAncestors = new List<Ant>();
            Statistics.largestPopulation = 0;
            Statistics.longestGenerationLived = 0;

            Statistics.timeOfLastMovement = 0;
            Statistics.systemHasMoved = false;

            Statistics.totalFoods = 0;
            Statistics.totalNumberOfAnts = 0;

            grid = new Entity[GRID_WIDTH, GRID_HEIGHT];

            SIDE_PANEL_WIDTH = (int) (graphics.GraphicsDevice.Viewport.Width * .2f);

            SCREEN_WIDTH = graphics.GraphicsDevice.Viewport.Width - SIDE_PANEL_WIDTH;
            SCREEN_HEIGHT = graphics.GraphicsDevice.Viewport.Height;

            TILE_WIDTH = SCREEN_WIDTH / GRID_WIDTH;
            TILE_HEIGHT = SCREEN_HEIGHT / GRID_HEIGHT;

            attributes = new Dictionary<string, double>();

            Statistics.attributeRange = new Dictionary<string, Vector2>();
            attributeRange = Statistics.attributeRange;

            Statistics.firstAverages = new Dictionary<string, double>();
            Statistics.currentSum = new Dictionary<string, double>();

            attributes["redColor"] = 100; //RGB color scheme
            attributeRange["redColor"] = new Vector2(0, 255);

            attributes["blueColor"] = 50;
            attributeRange["blueColor"] = new Vector2(0, 255);

            attributes["greenColor"] = 70;
            attributeRange["greenColor"] = new Vector2(0, 255);

            attributes["mutationFactor"] = .2;
            attributeRange["mutationFactor"] = new Vector2(0, 1);
            attributes["walkSpeed"] = 1000.0; //  how many milliseconds it takes to move a single step
            attributeRange["walkSpeed"] = new Vector2(100, 2000);

            attributes["desireForFood"] = 100.0; //  how much this ant prioritizes collecting food
            attributeRange["desireForFood"] = new Vector2(-4000, 4000);
            attributes["desireToFollowAnts"] = 10.0; //  how much this ant is willing to follow/avoid ants
            attributeRange["desireToFollowAnts"] = new Vector2(-300, 300);
            attributes["desireToExplore"] = 1.0; //  how much this ant is willing to explore new places
            attributeRange["desireToExplore"] = new Vector2(-200, 200);
            attributes["desireToMate"] = 500.0;   // influenced by number of children
            attributeRange["desireToMate"] = new Vector2(-600, 600);

            attributes["desireToContinueInSameDirection"] = 1500.0; //  prevents equal-sum scenarios
            attributeRange["desireToContinueInSameDirection"] = new Vector2(-2000, 2000);
            attributes["desireToGoBackwards"] = -1000.0; //  prevents oscillation
            attributeRange["desireToGoBackwards"] = new Vector2(-1500, 1500);

            attributes["timeToReexplore"] = 10.0; //  how long (seconds) an ant remembers a spot
            attributeRange["timeToReexplore"] = new Vector2(1, 30);
            attributes["decayFactor"] = 4.0;  //  analogous to the ant's sense of smell
            attributeRange["decayFactor"] = new Vector2(1, 8);
            attributes["healthThreshold"] = 200.0; //  if another ant meets this health threshold,
                                                   //   then the two will mate and produce offspring
            attributeRange["healthThreshold"] = new Vector2(1, 400);

            attributes["childbirthPercentage"] = 21.0; // % chance of having child when threshold met
            attributeRange["childbirthPercentage"] = new Vector2(1, 100);
            attributes["childbirthCost"] = 50.0; //  how much the parent pays to raise child
            attributeRange["childbirthCost"] = new Vector2(1, 300);
            attributes["childbirthCooldown"] = 10.0; //  how many seconds before having a child again
            attributeRange["childbirthCooldown"] = new Vector2(5, 30);

            //attributes["health"] = 150.0;     //  health is restored by eating food,
                                              //  and it is lowered by moving around and taking damage
            //attributeRange["health"] = new Vector2(0, 300);

            //attributes["strength"] = 10.0; //  TODO: damage dealt in a hit to a predator. influences
                                           //  construction of buildings, too

            attributes["oldestPossibleAge"] = 200.0; //  number of moves this ant can make before dying
            attributeRange["oldestPossibleAge"] = new Vector2(30, 400);

            attributes["eyesightRange"] = 100.0; //  number of tiles this ant can see
            attributeRange["eyesightRange"] = new Vector2(3, 150);

            //attributes["resistance"] = 5.0; //  TODO: immunity to cold, poison, and disease

            //       also, social model vs individualistic model. social model is a shared diffusion.

            //attributes["shelterShape"] = 22.0; // TODO: this number gets rounded down when used in calculation.
                                               // base-2 representation of the truncated version is
                                               // used. each digit represents having or not having
                                               // a block in a certain location in a 5x5 grid.
                                               // digit ordering as follows: (1 = first digit's block location)
                                               // and alphabetical chars correspond to numbers beyond 9

            //  22 = 10110(b2) = _
            //                 _|  shape

            /*   PLDEM
             *   KC56F
             *   B4127
             *   JA38G
             *   OI9HN
             */

            line = new Texture2D(graphics.GraphicsDevice, 1, 1);
            line.SetData(new Color[] { Color.White });

            base.Initialize();
        }