private void CreateAgents() { Random rnd = new Random(); for (int i = 0; i < AIModifiers.initialAgentCount; i++) { foreach (AgentFactory x in factories) { PropertyProvider p = new PropertyProvider(); pproviders.Add(p.Id.ToString(), p); Agent a = x.CreateAgent(p); p.Hitpoints = a.Health; p.Hunger = 0; p.ProcreationCountDown = AIModifiers.initialProcreationCount; if (a.Invarient()) { p.Hitpoints = a.Health; p.Hunger = 0; p.ProcreationCountDown = AIModifiers.initialProcreationCount; p.Position = new AIVector(rnd.Next((int)surfaceWidth), rnd.Next((int)surfaceHeight)); entities.Add(a); } } //Added to make more randomness between agents Thread.Sleep(rnd.Next(10)); } for (int i = 0; i < AIModifiers.initialPlants * factories.Count; i++) { Plant p = new Plant(); p.Position = new AIVector(rnd.Next((int)surfaceWidth), rnd.Next((int)surfaceHeight)); entities.Add(p); } }
private bool DoAction(Agent agent, TimeSpan gameTime) { PropertyProvider p = pproviders[agent.Id.ToString()]; p.Defending = false; bool status = false; List <IEntity> sightEntities = entities.FindAll(e => AIVector.Distance(p.Position, e.Position) <= agent.Eyesight); IAction action = agent.GetNextAction(sightEntities); switch (action.GetType().Name) { case "Attack": { Attack att = (Attack)action; if (att.Defender != null) { PropertyProvider pDefender = pproviders[att.Defender.Id.ToString()]; if (AIVector.Distance(p.Position, pDefender.Position) <= AIModifiers.maxMeleeAttackRange) //If { Random rnd = new Random(); int currentSuccessChance = AIModifiers.baseChanceOfAttackSuccess - (pDefender.Defending ? pDefender.Dodge : 0); if (currentSuccessChance < AIModifiers.minChanceOfAttackSuccess) { currentSuccessChance = AIModifiers.minChanceOfAttackSuccess; } if (rnd.Next(100) < currentSuccessChance) //Attack was an success { pDefender.Hitpoints -= p.Strength * (float)gameTime.TotalSeconds; status = true; } } } } break; case "Move": { Move m = (Move)action; AIVector v = m.Direction.Normalize(); if (float.IsNaN(v.X) || float.IsNaN(v.Y)) { v.X = 0; v.Y = 0; } v = v * p.MovementSpeed * (float)gameTime.TotalSeconds; p.Position.X += v.X; p.Position.Y += v.Y; status = true; if (p.Position.X < 0) { status = false; p.Position.X = 0; } if (p.Position.X > (int)surfaceWidth) { status = false; p.Position.X = (int)surfaceWidth; } if (p.Position.Y < 0) { status = false; p.Position.Y = 0; } if (p.Position.Y > (int)surfaceHeight) { status = false; p.Position.Y = (int)surfaceHeight; } } break; case "Procreate": { Procreate procreation = (Procreate)action; if (procreation.Mate != null) { PropertyProvider pMate = pproviders[procreation.Mate.Id.ToString()]; //Both agents should be ready to procreate and within distance if (agent != procreation.Mate && agent.GetType() == procreation.Mate.GetType() && p.ProcreationCountDown <= 0 && pMate.ProcreationCountDown <= 0 && AIVector.Distance(p.Position, pMate.Position) <= AIModifiers.maxProcreateRange) { //A random parent factory is chosen Random rnd = new Random(); string randomParentType = rnd.Next(2) == 0 ? agent.EntityType : procreation.Mate.EntityType; foreach (AgentFactory factory in factories) { if (factory.ProvidedAgentTypeName == randomParentType) { p.ProcreationCountDown = 100; pMate.ProcreationCountDown = 100; PropertyProvider pNew = new PropertyProvider(); pproviders.Add(pNew.Id.ToString(), pNew); Agent newAgent = factory.CreateAgent(agent, procreation.Mate, pNew); if (newAgent.Invarient()) { pNew.Hitpoints = newAgent.Health; pNew.Hunger = 0; pNew.ProcreationCountDown = AIModifiers.initialProcreationCount; pNew.Position = new AIVector(agent.Position.X, agent.Position.Y); toBeAdded.Add(newAgent); status = true; } else { //throw new Exception("Invarient exception"); } break; } } } } } break; case "Feed": { Feed f = (Feed)action; if (f.FoodSource != null) { if (AIVector.Distance(agent.Position, f.FoodSource.Position) <= AIModifiers.maxFeedingRange) { int removed = entities.RemoveAll(x => x.Id.ToString() == f.FoodSource.Id.ToString()); if (removed > 0) { p.Hunger -= AIModifiers.hungerReductionPerFeeding; if (p.Hunger < 0) { p.Hunger = 0; } status = true; } } } } break; case "Defend": p.Defending = true; status = true; break; default: break; } if (status) { effects.Add(new VisualEffect(agent, action)); } return(status); }
/// <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> void Update(TimeSpan gameTime) { effects.RemoveAll(e => e.ShouldBeRemoved); float secondsSinceLastFrame = (float)gameTime.TotalSeconds; plantCounter += secondsSinceLastFrame; runningSeconds += secondsSinceLastFrame; List <IEntity> agents = entities.FindAll(e => e is Agent); if (!gameRunning) { return; } else if (gameRunning && (runningSeconds > AIModifiers.maxRunningTimeInSeconds || agents.Count < 1)) { gameRunning = false; agents.ForEach(a => deadAgents.Push((Agent)a)); Dictionary <AgentFactory, int> endingAgents = new Dictionary <AgentFactory, int>(); foreach (Agent a in agents) { foreach (AgentFactory f in factories) { if (f.ProvidedAgentTypeName == a.EntityType) { if (endingAgents.ContainsKey(f)) { endingAgents[f] += 1; } else { endingAgents.Add(f, 1); } } } } List <Agent> dead = deadAgents.ToList(); Agent winningAgent = deadAgents.Peek(); AgentFactory winningAgentFactory = null; int currentCount = 0; foreach (AgentFactory f in factories) { try { f.RegisterWinners(dead); } catch { } } foreach (KeyValuePair <AgentFactory, int> f in endingAgents) { if (f.Value > currentCount) { winningAgentFactory = f.Key; currentCount = f.Value; } } return; } //Reset tmp lists toBeAdded.Clear(); toBeRemoved.Clear(); Random rnd = new Random(); //Create plant if (plantCounter > 1) { plantCounter = 0; for (int i = 0; i < AIModifiers.newPlantsPerSecond; i++) { Plant p = new Plant(); p.Position = new AIVector(rnd.Next((int)surfaceWidth), rnd.Next((int)surfaceHeight)); entities.Add(p); } } int agentCount = 0; foreach (IEntity e in agents) { agentCount++; Agent a = (Agent)e; PropertyProvider p = pproviders[a.Id.ToString()]; //Increment hunger p.Hunger += AIModifiers.hungerIncrementPerSecond * secondsSinceLastFrame; //Do action a.ActionResultCallback(DoAction(a, gameTime)); //Reduce hitpoints due to hunger if (p.Hunger > AIModifiers.maxHungerBeforeHitpointsDamage) { p.Hitpoints -= AIModifiers.hungerHitpointsDamagePerSecond * secondsSinceLastFrame; } //Remove agent if under 0 hitpoints = agent is dead if (p.Hitpoints <= 0) { toBeRemoved.Add(a); } else if (p.Hunger <= p.Endurance) //Hitpoint regenration due to endurance higher then hunger { p.Hitpoints += AIModifiers.hitpointRegenPerSecond * secondsSinceLastFrame; if (p.Hitpoints > p.Health) { p.Hitpoints = p.Health; } } //Procreation reduction if (p.ProcreationCountDown > 0) { p.ProcreationCountDown -= AIModifiers.procreationReductionPerSecond * secondsSinceLastFrame; if (p.ProcreationCountDown < 0) { p.ProcreationCountDown = 0; } } } entities.AddRange(toBeAdded); toBeRemoved.ForEach(a => { entities.Remove(a); deadAgents.Push((Agent)a); }); }