/// <summary> /// Returns an int based on a comparison between creatures /// </summary> /// <param name="c1">The first creature to compare</param> /// <param name="c2">The second creature to compare</param> /// <returns>An int, 1 if the first creature is better and -1 if the second is better</returns> public static int judgeCreatures(Creature c1, Creature c2) { int ret; int c1Health = (int)c1.getHealth() * Simulation.getHealthWeight(); int c1Energy = (int)c1.getEnergy() * Simulation.getEnergyWeight(); int c2Health = (int)c2.getHealth() * Simulation.getHealthWeight(); int c2Energy = (int)c2.getEnergy() * Simulation.getEnergyWeight(); ; if (c1Health + c1Energy > c2Health + c2Energy) { ret = -1; } else if (c1Health + c1Energy == c2Health + c2Energy) { int c1Stats = c1.getStatValue(); int c2Stats = c2.getStatValue(); if (c1Stats > c2Stats) { ret = -1; } else if (c2Stats < c1Stats) { ret = 1; } else { ret = 0; //in this case they are equal } } else //if c1stuff < c2stuff { ret = -1; } return ret; }
/// <summary> /// Clears the tile, sets all the variables for tile contents to null, sets isBlocked to false. /// </summary> public void clearTile() { creature = null; plant = null; remains = null; obstacle = null; isBlocked = false; }
/// <summary> /// Stalks another creature, trying to stay outside of its view radius, with the ideal position being just outside the view radius /// </summary> /// <param name="creature">The creature to stalk</param> private void stalk(Creature creature) { if (creature.getAwareness() < this.awareness) { if (getDistanceFrom(creature) > creature.getAwareness() + 1) { moveTowards(creature); } else if (getDistanceFrom(creature) == creature.getAwareness() + 1) { //stay still } else { moveAwayFrom(creature); } } else { ambush(creature); } }
/// <summary> /// Attacks another creature, comparing strength to defence and moving towards the other creature if it is not adjacent /// </summary> /// <param name="otherCreature">The creature to attack</param> public void attack(Creature otherCreature) { if (isAdjacent(otherCreature)) { int winnerEnergy = 10; int loserEnergy = 20; otherCreature.attacked(this); inCombat = true; inCombatWith = otherCreature; int attackVal = this.getStrength() + rand(10); int defVal = otherCreature.getDefence() + rand(10); if (attackVal > defVal) { otherCreature.damage(attackVal - defVal); this.drainEnergy(winnerEnergy); otherCreature.drainEnergy(loserEnergy); } else if (attackVal < defVal) { this.damage((defVal - attackVal) / 2); this.drainEnergy(loserEnergy); otherCreature.drainEnergy(winnerEnergy); } else { this.drainEnergy(loserEnergy); otherCreature.drainEnergy(loserEnergy); } } else { moveTowards(otherCreature); } }
/// <summary> /// A method to sort the creatures by their speed /// </summary> /// <returns></returns> public static int sortCreaturesBySpeed(Creature c1, Creature c2) { int val = 0; if (c1 == null && c2 == null) { val = 0; } else if (c1 == null) { val = 1; } else if (c2 == null) { val = -1; } else { if (c1.getSpeed() < c2.getSpeed()) { val = 1; } else if (c1.getSpeed() > c2.getSpeed()) { val = -1; } else { val = 0; } } return val; }
/// <summary> /// A method that takes a creature and returns a 10 x 10 texture representation of the creature's genome /// </summary> /// <param name="creature"></param> /// <returns></returns> public static Texture2D drawGenome(Creature creature) { return drawGenome(creature.getDna()); }
/// <summary> /// Updates the judge, moving one step foward through the judginf process /// </summary> /// <param name="t">The time since the update method was last called, not used in this method</param> public override void update(GameTime t) { if (!isJudged) //should run through once { aliveCreatures.Sort(judgeCreatures); isJudged = true; status = "Eliminating creatures..."; } else if (!isEliminated) //should run through once { creatureList = new List<Creature>(); if (aliveCreatures.Count > 0) { creatureList.AddRange(aliveCreatures.ToArray<Creature>()); } //enclose this in an IF statement if you want to prevent dead creatures from being included while(deadCreatures.Count > 0) { Creature c = deadCreatures.Pop(); creatureList.Add(c); } //upon loop exit creatureList should be a list of creatures sorted by success in the world total = creatureList.Count; //find indexes for certain percentages of the list lowerFix = total / 100 * (100 - Simulation.getElimPercentage()); //index to eliminate all after upperFix = total / 100 * Simulation.getTopPercentage(); //index to treat all before as top creatureList.RemoveRange(lowerFix, total - lowerFix); for (int i = 0; i < upperFix; i++) { top.Add(creatureList[i]); } for (int i = upperFix; i < creatureList.Count; i++) { bottom.Add(creatureList[i]); } creatureList.Clear(); status = "Breeding next generation: " + numBred + "/" + Simulation.getPopulation(); isEliminated = true; } else if (!isBred) //should run through x times where x = number of creatures we need { if (numBred > Simulation.getPopulation()) { status = "Done!"; isBred = true; } else { Random rand = WorldState.RandomNumberGenerator; if (childList.Count < (Simulation.getPopulation() / 100) * Simulation.getTopPercentage()) { int c1 = rand.Next(top.Count); int c2 = rand.Next(top.Count); int attempts = 0; while (c1 == c2 && attempts < 10) { c2 = rand.Next(upperFix); attempts++; } Creature creature1 = top[c1]; Creature creature2 = top[c2]; Creature child = new Creature(creature1.getDna().breedWith(creature2.getDna())); childList.Add(child); } else if (childList.Count < Simulation.getPopulation()) { int c1 = rand.Next(bottom.Count); int c2 = rand.Next(bottom.Count); int attempts = 0; while (c1 == c2 && attempts < 10) { c2 = rand.Next(upperFix); attempts++; } Creature creature1 = bottom[c1]; Creature creature2 = bottom[c2]; Creature child = new Creature(creature1.getDna().breedWith(creature2.getDna())); childList.Add(child); } status = "Breeding next generation: " + numBred + "/" + Simulation.getPopulation(); numBred++; } } else { Simulation.judgingDone(childList); } }
/// <summary> /// A routing method to decide on the creature's action, using a provided creature /// </summary> /// <param name="c">The creature to act upon</param> private void creatureAct(Creature c) { switch (behaviour[Scenario.CREATURE]) { case Response.ATTACK: attack(c); break; case Response.EVADE: moveAwayFrom(c); break; case Response.IGNORE: randomAction(); break; case Response.HIDE: hide(); break; case Response.DEFEND: break; case Response.STALK: stalk(c); break; case Response.AMBUSH: ambush(c); break; } }
/// <summary> /// Clones this creature and adds it at a random location in the world /// </summary> /// <returns>The creature that has just been created</returns> public Creature userCloneCreature() { Creature c = new Creature(this.getDna()); c.setWorld(this.world); world.addCreature(c); return c; }
/// <summary> /// Adds a creature to the tile, sets the creature variable to the specified creature and sets the tile to be blocked /// </summary> /// <param name="c">The creature to add to the tile</param> public void addCreature(Creature c) { creature = c; isBlocked = true; }
/// <summary> /// The update method of the Simulation, calls the update method of the current state of the simulation /// </summary> /// <param name="gameTime">The time since update was last called</param> protected override void Update(GameTime gameTime) { #region testing #if CELLTEST int[][] colours = new int[6][]; colours[0] = new int[] { 0, 0 }; //Check the same colours[1] = new int[] { 7, 7 }; //Check the same colours[2] = new int[] { 1, 3 }; //Check different colours[3] = new int[] { 3, 1 }; //Check different but the other way around colours[4] = new int[] { 7, 1 }; //Check different and wrapping colours[5] = new int[] { 1, 7 }; //Check different and wrapping but the other way around foreach(int[] i in colours) { Cell c = new Cell(i[0], i[1]); Console.WriteLine("C1: " + i[0] + " C2: " + i[1] + " DOM: " + c.getDomColour()); } Environment.Exit(0); #endif #if PATTERNTEST //Code for checking various things Cell[][] c = new Cell[3][]; c[0] = new Cell[] { new Cell(1, 1), new Cell(0, 0), new Cell(0, 0) }; c[1] = new Cell[] { new Cell(0, 0), new Cell(1, 1), new Cell(0, 0) }; c[2] = new Cell[] { new Cell(0, 0), new Cell(0, 0), new Cell(1, 1) }; geneTest(new Gene(c)); c[0] = new Cell[] { new Cell(1, 1), new Cell(0, 0), new Cell(0, 0) }; c[1] = new Cell[] { new Cell(0, 0), new Cell(1, 1), new Cell(0, 0) }; c[2] = new Cell[] { new Cell(0, 0), new Cell(0, 0), new Cell(0, 0) }; geneTest(new Gene(c)); c[0] = new Cell[] { new Cell(0, 0), new Cell(0, 0), new Cell(1, 1) }; c[1] = new Cell[] { new Cell(0, 0), new Cell(1, 1), new Cell(0, 0) }; c[2] = new Cell[] { new Cell(1, 1), new Cell(0, 0), new Cell(0, 0) }; geneTest(new Gene(c)); c[0] = new Cell[] { new Cell(1, 1), new Cell(0, 0), new Cell(1, 1) }; c[1] = new Cell[] { new Cell(0, 0), new Cell(1, 1), new Cell(0, 0) }; c[2] = new Cell[] { new Cell(1, 1), new Cell(0, 0), new Cell(1, 1) }; geneTest(new Gene(c)); c[0] = new Cell[] { new Cell(0, 0), new Cell(6, 6), new Cell(1, 1), new Cell(1, 1) }; c[1] = new Cell[] { new Cell(1, 1), new Cell(0, 0), new Cell(6, 6), new Cell(1, 1) }; c[2] = new Cell[] { new Cell(1, 1), new Cell(1, 1), new Cell(0, 0), new Cell(6, 6) }; geneTest(new Gene(c)); c[0] = new Cell[] { new Cell(0, 0), new Cell(0, 0), new Cell(0, 0) }; c[1] = new Cell[] { new Cell(0, 0), new Cell(0, 0), new Cell(0, 0) }; c[2] = new Cell[] { new Cell(0, 0), new Cell(0, 0), new Cell(1, 1) }; Cell[][] rCells = new Cell[1][]; rCells[0] = new Cell[] { new Cell(1, 1) }; List<ParamToken> rMods = new List<ParamToken>(); rMods.Add(ParamToken.STRENGTH); recognisedShapes = new List<Shape>(); recognisedShapes.Add(new Shape(rCells, rMods, new List<ParamToken>())); geneTest(new Gene(c)); Environment.Exit(0); #endif #if POLLTEST Cell[][] newGene = new Cell[10][]; for (int colour = 0; colour < 7; colour++) { for (int i = 0; i < newGene.Length; i++) { newGene[i] = new Cell[10]; for (int j = 0; j < newGene[i].Length; j++) { newGene[i][j] = new Cell(colour, colour); } } creatureTest(newGene); } for (int i = 0; i < newGene.Length; i++) { newGene[i] = new Cell[10]; for (int j = 0; j < newGene[i].Length; j++) { newGene[i][j] = new Cell(0, 0); } } newGene[0][0] = new Cell(0, 0); newGene[0][1] = new Cell(0, 0); newGene[0][2] = new Cell(0, 0); newGene[1][0] = new Cell(0, 0); newGene[1][1] = new Cell(0, 0); newGene[1][2] = new Cell(0, 0); newGene[2][0] = new Cell(0, 0); newGene[2][1] = new Cell(0, 0); newGene[2][2] = new Cell(1, 1); creatureTest(newGene); newGene[0][0] = new Cell(0, 0); newGene[0][1] = new Cell(0, 0); newGene[0][2] = new Cell(0, 0); newGene[1][0] = new Cell(0, 0); newGene[1][1] = new Cell(2, 2); newGene[1][2] = new Cell(1, 1); newGene[2][0] = new Cell(1, 1); newGene[2][1] = new Cell(1, 1); newGene[2][2] = new Cell(1, 1); creatureTest(newGene); newGene[0][0] = new Cell(1, 1); newGene[0][1] = new Cell(0, 0); newGene[0][2] = new Cell(0, 0); newGene[1][0] = new Cell(0, 0); newGene[1][1] = new Cell(2, 2); newGene[1][2] = new Cell(1, 1); newGene[2][0] = new Cell(1, 1); newGene[2][1] = new Cell(1, 1); newGene[2][2] = new Cell(0, 0); creatureTest(newGene); Environment.Exit(0); #endif #if DIETTEST Cell[][] cc = new Cell[10][]; Cell[][] ch = new Cell[10][]; for (int i = 0; i < 10; i++) { cc[i] = new Cell[10]; ch[i] = new Cell[10]; for (int j = 0; j < 10; j++) { cc[i][j] = new Cell(0, 0); ch[i][j] = new Cell(6, 6); } } Creature carn = new Creature(new Gene(cc)); Creature herb = new Creature(new Gene(ch)); List<FoodSource> foodToSort = new List<FoodSource>(); plantFoodValue = 1000; remainsFoodValue = 1000; foodToSort.Add(new Plant(new Random())); foodToSort.Add(new Remains(new Random())); FoodSource carnChoice = carn.pubGetMostNourishing(foodToSort); FoodSource herbChoice = herb.pubGetMostNourishing(foodToSort); Console.WriteLine("Diet: Carnivore : " + carn.getDiet() + " Herbivore: " + herb.getDiet()); Console.WriteLine("Actual values: Plant: " + foodToSort[0].getFoodValue() + " Remains: " + foodToSort[1].getFoodValue()); Console.WriteLine("Carnivore sees plant as: " + carn.pubGetNourishmentAmt(foodToSort[0]) + " and remains as " + carn.pubGetNourishmentAmt(foodToSort[1])); Console.WriteLine("Herbivore sees plant as: " + herb.pubGetNourishmentAmt(foodToSort[0]) + " and remains as " + herb.pubGetNourishmentAmt(foodToSort[1])); Console.WriteLine("Carnivore chooses meat: " + !carnChoice.isPlant()); Console.WriteLine("Herbivore chooses plant: " + herbChoice.isPlant()); Environment.Exit(0); #endif #if BREEDTEST Cell[][] newGene = new Cell[10][]; for (int i = 0; i < newGene.Length; i++) { newGene[i] = new Cell[10]; for (int j = 0; j < newGene[i].Length; j++) { newGene[i][j] = new Cell(0, 0); } } Gene g = new Gene(newGene, new Random()); for (int i = 0; i < 100; i++) { g.breedWith(g); } Environment.Exit(0); #endif #endregion base.Update(gameTime); state.update(gameTime); }
private void creatureTest(Cell[][] newGene) { Creature cret = new Creature(new Gene(newGene)); Dictionary<Scenario, Response> beh = cret.getBehaviour(); foreach (Scenario s in beh.Keys) { Console.WriteLine("Scen: " + s + " Resp: " + beh[s]); } }
/// <summary> /// Cancels views, sets viewing to be false and all the viewing variables etc. to be null /// </summary> private void deView() { viewing = false; creatureView = null; plantView = null; remainsView = null; following = false; dataViewed = 0; buttons[3].setVisible(false); buttons[4].setVisible(false); buttons[5].setVisible(false); }
/// <summary> /// Views a creature, sets viewing to be true and sets up the information viewing commands /// </summary> /// <param name="c">The Creature to be viewed</param> public void viewCreature(Creature c) { viewing = true; maxInfo = creatureMaxInfo; buttons[4].setVisible(true); buttons[5].setVisible(true); creatureView = c; }
/// <summary> /// Gets an array of strings that contain information about the creature /// </summary> /// <param name="c">The creature to get information about</param> /// <returns>An array of strings containing a set of information about the creature</returns> public string[] getCreatureInfo(Creature c) { string[] status = new string[1]; switch (DataViewed) { case 0: status = new string[] { "Health: " + c.getHealth(), "Energy :" + c.getEnergy(), "Current Scenario: " + c.CurrentScenario, "Response: " + c.CurrentResponse, "Stamina: " + c.getStamina() + "/" + c.getMaxStamina(), "Location: (" + c.getLocationXY()[0] + "," + c.getLocationXY()[1] + ")" }; break; case 1: int[] colours = c.getDna().getColourCount(); status = new string[] { "Number of...", "0s: " + colours[0], "1s: " + colours[1], "2s: " + colours[2], "3s: " + colours[3], "4s: " + colours[4], "5s: " + colours[5], "6s: " + colours[6] }; break; case 2: Color[] cols = Simulation.getColours(); status = new string[cols.Length]; for (int i = 0; i < cols.Length; i++ ) { status[i] = i + ": " + cols[i].ToString(); } break; case 3: string dietString = "Diet: " + c.getDiet(); if (c.getDiet() < 0.5) { dietString += " (HERBIVORE)"; } else { dietString += " (CARNIVORE)"; } status = new string[] { "Stats:", "STR: " + c.getStrength(), "SPD: " + c.getSpeed(), "STL: " + c.getStealthVal(), "AWA: " + c.getAwareness(), "DEF: " + c.getDefence(), dietString }; break; } return status; }
/// <summary> /// Tells the creature it is being attacked and updates the variables related to that /// </summary> /// <param name="c"></param> public void attacked(Creature c) { inCombat = true; inCombatWith = c; }
/// <summary> /// Updates the flags to tell the creature it is not in combat /// </summary> public void outOfCombat() { inCombat = false; inCombatWith = null; }
/// <summary> /// Adds a creature at the specified location /// </summary> /// <param name="x">The x index to add the creature at</param> /// <param name="y">The y index to add the creature at</param> /// <param name="c">The creature to add</param> public void addCreature(int x, int y, Creature c) { getTile(y, x).addCreature(c); c.setLocation(x, y); }
/// <summary> /// A method used to check if you can detect a creature that is trying to be stealthy /// </summary> /// <param name="c">The creature in the scan radius that we are checking we can see</param> /// <returns>True if the creature is not hidden, false if the creature is hidden</returns> private bool canSee(Creature c) { bool b = true; double i = getEuclideanDistanceFrom(c); if (i > awareness) { b = false; } else if(random.Next(100) < c.getStealthVal() + (i - awareness)) { b = false; } return b; }
/// <summary> /// Adds a creature at a random clear location /// </summary> /// <param name="c">The creature to add</param> public void addCreature(Creature c) { int[] clearTile = getRandomClearTile(); addCreature(clearTile[0], clearTile[1], c); if (!creatureList.Contains(c)) { creatureList.Add(c); } }
/// <summary> /// Controls ambush behaviour, where a creature tries to sneak up next to another to get a high damage special attack /// </summary> /// <param name="c"></param> public void ambush(Creature c) { if (isStealthy()) { if (!c.canSee(this)) { if (isAdjacent(c)) { c.damage((getStrength() / 2) + getStealthVal()); spotted(); } else { moveTowards(c); } } else { spotted(); } } else { hide(); } }
/// <summary> /// Adds creatures to the world. 1 Override to allow the user to provide a list of creatures to add /// </summary> public void addCreatures() { creatureList = new List<Creature>(); for (int i = 0; i < Simulation.getPopulation(); i++) { Creature c = new Creature(); creatureList.Add(c); } placeCreatures(); }
/// <summary> /// Handles the code for killing a specified creature /// </summary> /// <param name="c">The creature to kill</param> public void killCreature(Creature c) { int[] loc = c.getLocationXY(); creatureList.Remove(c); getTile(loc[1], loc[0]).clearTile(); c.setLocation(-1, -1); Remains r = new Remains(randomNumberGenerator); r.setLocation(loc[0], loc[1]); remainsList.Add(r); getTile(loc[1], loc[0]).addRemains(r); deadList.Push(c); #if DEBUG Console.WriteLine("Remains added at: " + loc[0] + "," + loc[1]); #endif }
/// <summary> /// Draws the creature viewing window /// </summary> /// <param name="c">The creature to draw the viewing window for</param> private void drawCreatureView(Creature c) { drawBack(); Simulation.getGraphicsDeviceManager().GraphicsDevice.SamplerStates[0] = SamplerState.PointWrap; spriteBatch.Begin(0, null, SamplerState.PointWrap, null, null); Texture2D tex = c.getDna().getTexture(); Rectangle r = new Rectangle((Display.getWindowWidth() - 800) / 2 + 10, Display.getWindowHeight() - 130, 120, 120); spriteBatch.Draw(tex, r, Color.White); String title = "Creature"; if (c.isStealthy()) { title += " (hiding)"; } string[] status = inputHandler.getCreatureInfo(c); Vector2 topLeft = new Vector2((Display.getWindowWidth() - 800) / 2 + 10 + 120 + 10, Display.getWindowHeight() - 130); spriteBatch.End(); drawStrings(topLeft, title, status, 4); }