private Board CreateBoard(Settings settings) { var board = new Board { Size = new Location { X = settings.Width, Y = settings.Height }, Tiles = new Tile[settings.Width, settings.Height], Pieces = new List <IPiece>(), //MaxAge = settings.MaxAge }; int xpos = 0; int ypos = 0; for (int i = 0; i < settings.Width * settings.Height; i++) { var grass = new Grass { Location = new Location { X = xpos, Y = ypos }, Energy = Rando.Next(50) //+ 50 }; board.Tiles[xpos, ypos] = new nimble_life.Tile { Grass = grass, Location = new Location { X = xpos, Y = ypos } }; if (Rando.Next(settings.OneInThisIsHerby) == 1) { var herby = new Herbivore() { Location = new nimble_life.Location { X = xpos, Y = ypos }, Energy = Rando.Next(75), Species = "Electric Sheep", Color = System.Drawing.Color.Black, Age = Rando.Next(30), AgeOfMaturity = Settings.AgeOfMaturity, Genes = new Dictionary <string, float>() }; herby.Genes = Clone(greatestGenes); board.Pieces.Add(herby); board.Tiles[xpos, ypos].Animal = herby; } else if (Rando.Next(settings.OneInThisIsRobot) == 1) { var robby = new Robot() { Location = new nimble_life.Location { X = xpos, Y = ypos }, Energy = Rando.Next(75), Species = "Robot", Color = System.Drawing.Color.Black, Age = Rando.Next(30), AgeOfMaturity = Settings.AgeOfMaturity, Genes = new Dictionary <string, float>() }; robby.Genes = Clone(greatestGenes); board.Pieces.Add(robby); board.Tiles[xpos, ypos].Animal = robby; } xpos++; if (xpos >= settings.Width) { xpos = 0; ypos++; } } return(board); }
public IPiece TakeTurn(Board board) { if (this.IsDead) { return(null); } IPiece result = null; var moveDone = false; var currentTile = board.Tiles[this.Location.X, this.Location.Y]; var neighbors = board.GetNeighbors(this.Location.X, this.Location.Y); var bestNeighbor = currentTile; foreach (var t in neighbors) { if (t.Animal == null && t.Grass.Energy > bestNeighbor.Grass.Energy) { bestNeighbor = t; } } if (!moveDone && bestNeighbor != currentTile && (bestNeighbor.Grass.Energy > this.Genes[hg.WorthMovingTo.ToString()])) { // Move to it! currentTile.Animal = null; bestNeighbor.Animal = this; this.Location.X = bestNeighbor.Location.X; this.Location.Y = bestNeighbor.Location.Y; this.Energy -= 5; //TAKES energy to move... currentTile = board.Tiles[this.Location.X, this.Location.Y]; moveDone = true; } else { // Takes energy to stand still! this.Energy -= 1; } if (!moveDone && currentTile.Grass.Energy > 15 && this.Energy < 100) { // Chew some. currentTile.Grass.Energy -= 15; this.Energy += 10; // Note inefficiency } this.Energy = Math.Min(100, this.Energy); // Consider trying to mate... if (Rando.Next() < this.Genes[hg.MatingProbability.ToString()] && this.Age >= this.AgeOfMaturity) { var hottestNeighbor = this as IAnimal; foreach (var t in neighbors) { if (t.Animal != null && t.Animal.Species == this.Species && // picky t.Animal.IsDead == false && // picky! t.Animal.Age > t.Animal.AgeOfMaturity && // picky t.Animal.Energy >= hottestNeighbor.Energy) //picky { hottestNeighbor = t.Animal; } } if (hottestNeighbor != this) // picky { if (hottestNeighbor.MatingOffers == null) { hottestNeighbor.MatingOffers = new List <IAnimal>(); } // swipe right hottestNeighbor.MatingOffers.Add(this); } } if (this.MatingOffers != null && this.Energy > this.Genes[hg.EnergyRequiredBeforeConsideringOffspring.ToString()]) { var bestOffer = this.MatingOffers .Where(p => p.IsDead == false && p.Species == this.Species && p.Age > p.AgeOfMaturity) .OrderByDescending(p => p.Energy).FirstOrDefault(); if (bestOffer != null) { // Find an empty neighboring square to plonk a baby on... bestNeighbor = null; foreach (var t in neighbors) { if (t.Animal == null && (bestNeighbor == null || t.Grass.Energy > bestNeighbor.Grass.Energy) && t.Grass.Energy > this.Genes[hg.MinFoodAvailableForBaby.ToString()]) // what kind of a world are we bringing this child into... { bestNeighbor = t; } } if (bestNeighbor != null) { var baby = new Herbivore { Species = this.Species, Energy = (int)(this.Energy * this.Genes[hg.EnergyToBaby.ToString()]), Age = 0, AgeOfMaturity = this.AgeOfMaturity, Genes = new Dictionary <string, float>() }; var MaxMutationFactor = this.Genes[hg.MaxMutationFactor.ToString()]; foreach (var d in this.Genes.Keys) { var mutationFactor = (float)1 + (float)((Rando.Next() * MaxMutationFactor) - (MaxMutationFactor / 2)); // Cross over and mutation baby.Genes[d] = Rando.Either(bestOffer.Genes[d], this.Genes[d]) * mutationFactor; } // Having babies really takes something out of you. this.Energy -= baby.Energy; baby.Location = new Location() { X = bestNeighbor.Location.X, Y = bestNeighbor.Location.Y }; bestNeighbor.Animal = baby; result = baby; // Get rid of all mating offers. this.MatingOffers = null; } else { Debug.WriteLine("No empty tile found."); } } } // shade of gray depends on energy levels var gray = Math.Max(0, Math.Min((int)(Energy * (256.0 / 100.0)), 255)); this.Color = Color.FromArgb(gray, gray, gray); return(result); }