internal override void Init(CoreColony colony, Random random, Dictionary <string, int> availableInsects) { base.Init(colony, random, availableInsects); koordinate.Radius = 2; // Bestimme die Kaste der neuen Ameise. int casteIndex = -1; string casteName = string.Empty; if (availableInsects != null) { casteName = BestimmeKasteBase(availableInsects); for (int i = 0; i < colony.Player.Castes.Count; i++) { if (colony.Player.Castes[i].Name == casteName) { casteIndex = i; break; } } } // Check, if caste is available if (casteIndex == -1) { throw new InvalidOperationException(string.Format(Resource.SimulationCoreChooseWrongCaste, casteName)); } // Setze die von der Kaste abhängigen Werte. CasteIndexBase = casteIndex; AktuelleEnergieBase = colony.Energie[casteIndex]; aktuelleGeschwindigkeitI = colony.GeschwindigkeitI[casteIndex]; AngriffBase = colony.Angriff[casteIndex]; }
/// <summary> /// Erntfernt Ameisen die keine Energie mehr haben. /// </summary> /// <param name="colony">betroffenes Volk</param> private void removeAnt(CoreColony colony) { List <CoreAnt> liste = new List <CoreAnt>(); for (int i = 0; i < colony.VerhungerteInsekten.Count; i++) { CoreAnt ant = colony.VerhungerteInsekten[i] as CoreAnt; if (ant != null && !liste.Contains(ant)) { liste.Add(ant); colony.Statistik.StarvedAnts++; PlayerCall.HasDied(ant, CoreKindOfDeath.Starved); } } for (int i = 0; i < colony.EatenInsects.Count; i++) { CoreAnt ant = colony.EatenInsects[i] as CoreAnt; if (ant != null && !liste.Contains(ant)) { liste.Add(ant); colony.Statistik.EatenAnts++; PlayerCall.HasDied(ant, CoreKindOfDeath.Eaten); } } for (int i = 0; i < colony.BeatenInsects.Count; i++) { CoreAnt ant = colony.BeatenInsects[i] as CoreAnt; if (ant != null) { if (!liste.Contains(ant)) { liste.Add(ant); colony.Statistik.BeatenAnts++; PlayerCall.HasDied(ant, CoreKindOfDeath.Beaten); } } } for (int i = 0; i < liste.Count; i++) { CoreAnt ant = liste[i]; if (ant != null) { colony.EntferneInsekt(ant); for (int j = 0; j < Playground.Fruits.Count; j++) { CoreFruit fruit = Playground.Fruits[j]; fruit.TragendeInsekten.Remove(ant); } } } colony.VerhungerteInsekten.Clear(); colony.EatenInsects.Clear(); colony.BeatenInsects.Clear(); }
internal override void Init(CoreColony colony, Dictionary <string, int> vorhandeneInsekten) { base.Init(colony, vorhandeneInsekten); koordinate.Radius = 4; AktuelleEnergieBase = colony.Energie[0]; aktuelleGeschwindigkeitI = colony.GeschwindigkeitI[0]; AngriffBase = colony.Angriff[0]; }
/// <summary> /// Der abstrakte Insekt-Basiskonstruktor. /// </summary> /// <param name="colony">Das Volk zu dem das neue Insekt gehört.</param> /// <param name="vorhandeneInsekten">Hier unbenutzt!</param> internal virtual void Init(CoreColony colony, Random random, Dictionary <string, int> vorhandeneInsekten) { id = neueId; neueId++; this.colony = colony; this.RandomBase = random; koordinate.Richtung = RandomBase.Next(0, 359); // Zufällig auf dem Spielfeldrand platzieren. if (colony.AntHills.Count == 0) // Am oberen oder unteren Rand platzieren. { if (RandomBase.Next(2) == 0) { koordinate.X = RandomBase.Next(0, colony.Playground.Width); koordinate.X *= SimulationEnvironment.PLAYGROUND_UNIT; if (RandomBase.Next(2) == 0) { koordinate.Y = 0; } else { koordinate.Y = colony.Playground.Height * SimulationEnvironment.PLAYGROUND_UNIT; } } // Am linken oder rechten Rand platzieren. else { if (RandomBase.Next(2) == 0) { koordinate.X = 0; } else { koordinate.X = colony.Playground.Width * SimulationEnvironment.PLAYGROUND_UNIT; } koordinate.Y = RandomBase.Next(0, colony.Playground.Height); koordinate.Y *= SimulationEnvironment.PLAYGROUND_UNIT; } } // In einem zufälligen Bau platzieren. else { int i = RandomBase.Next(colony.AntHills.Count); koordinate.X = colony.AntHills[i].CoordinateBase.X + SimulationEnvironment.Cosinus( colony.AntHills[i].CoordinateBase.Radius, koordinate.Richtung); koordinate.Y = colony.AntHills[i].CoordinateBase.Y + SimulationEnvironment.Sinus( colony.AntHills[i].CoordinateBase.Radius, koordinate.Richtung); } }
/// <summary> /// Entfernt abgelaufene Markierungen und erzeugt neue Markierungen. /// </summary> /// <param name="colony">betroffenes Volk</param> private static void aktualisiereMarkierungen(CoreColony colony) { // TODO: Settings berücksichtigen // Markierungen aktualisieren und inaktive Markierungen löschen. List <CoreMarker> gemerkteMarkierungen = new List <CoreMarker>(); foreach (CoreMarker markierung in colony.Marker) { if (markierung.IstAktiv) { markierung.Aktualisieren(); } else { gemerkteMarkierungen.Add(markierung); } } gemerkteMarkierungen.ForEach(delegate(CoreMarker marker) { colony.Insects.ForEach(delegate(CoreInsect insect) { CoreAnt ant = insect as CoreAnt; if (ant != null) { ant.SmelledMarker.Remove(marker); } }); }); colony.Marker.Remove(gemerkteMarkierungen); // Neue Markierungen überprüfen und hinzufügen. gemerkteMarkierungen.Clear(); colony.NewMarker.ForEach(delegate(CoreMarker newMarker) { bool zuNah = false; foreach (CoreMarker markierung in colony.Marker) { int entfernung = CoreCoordinate.BestimmeEntfernungDerMittelpunkteI (markierung.CoordinateBase, newMarker.CoordinateBase); if (entfernung < SimulationSettings.Custom.MarkerDistance * PLAYGROUND_UNIT) { zuNah = true; break; } } if (!zuNah) { colony.Marker.Add(newMarker); } }); colony.NewMarker.Clear(); }
/// <summary> /// Erzeugt neue Ameisen. /// </summary> /// <param name="colony">betroffenes Volk</param> private void spawnAnt(CoreColony colony) { if (colony.Insects.Count < antLimit && colony.insectDelay < 0 && colony.insectCountDown > 0) { colony.NeuesInsekt(random); colony.insectDelay = SimulationSettings.Custom.AntRespawnDelay; colony.insectCountDown--; } colony.insectDelay--; }
/// <summary> /// Bestimmt, ob das Stück Obst für das angegebene Volk noch tragende /// Insekten benötigt, um die maximale Geschwindigkeit beim Tragen zu /// erreichen. /// </summary> /// <param name="colony">Das Volk.</param> internal bool BrauchtNochTräger(CoreColony colony) { int last = 0; foreach (CoreInsect insekt in TragendeInsekten) { if (insekt.colony == colony) { last += insekt.AktuelleLastBase; } } return(last * SimulationSettings.Custom.FruitLoadMultiplier < Menge); }
/// <summary> /// Removes fruit from list. /// </summary> /// <param name="colony">winning colony</param> private void removeFruit(CoreColony colony) { //List<CoreFruit> gemerktesObst = new List<CoreFruit>(); for (int j = 0; j < Playground.Fruits.Count; j++) { CoreFruit obst = Playground.Fruits[j]; for (int i = 0; i < colony.AntHills.Count; i++) { CoreAnthill bau = colony.AntHills[i]; if (bau != null) { int entfernung = CoreCoordinate.BestimmeEntfernungI(obst.CoordinateBase, bau.CoordinateBase); if (entfernung <= PLAYGROUND_UNIT) { //gemerktesObst.Add(obst); // Löschen colony.Statistik.CollectedFood += obst.Menge; colony.Statistik.CollectedFruits++; obst.Menge = 0; for (int z = 0; z < obst.TragendeInsekten.Count; z++) { CoreInsect insect = obst.TragendeInsekten[z]; if (insect != null) { insect.GetragenesObstBase = null; insect.AktuelleLastBase = 0; insect.RestStreckeI = 0; insect.RestWinkelBase = 0; insect.GeheZuBauBase(); } } obst.TragendeInsekten.Clear(); Playground.EntferneObst(obst); j--; } } } } }
/// <summary> /// Initialisiert die Simulation um mit Runde 1 zu beginnen /// </summary> /// <param name="configuration">Konfiguration der Simulation</param> /// <throws><see cref="ArgumentException"/></throws> /// <throws><see cref="ArgumentNullException"/></throws> /// <throws><see cref="PathTooLongException"/></throws> /// <throws><see cref="DirectoryNotFoundException"/></throws> /// <throws><see cref="IOException"/></throws> /// <throws><see cref="UnauthorizedAccessException"/></throws> /// <throws><see cref="FileNotFoundException"/></throws> /// <throws><see cref="NotSupportedException"/></throws> /// <throws><see cref="SecurityException"/></throws> /// <throws><see cref="FileLoadException"/></throws> /// <throws><see cref="BadImageFormatException"/></throws> /// <throws><see cref="RuleViolationException"/></throws> /// <throws><see cref="TypeLoadException"/></throws> public void Init(SimulatorConfiguration configuration) { // Init some varialbes currentRound = 0; if (configuration.MapInitialValue != 0) { random = new Random(configuration.MapInitialValue); } else { random = new Random(); } // count players playerCount = 0; foreach (TeamInfo team in configuration.Teams) { playerCount += team.Player.Count; } // Sugar-relevant stuff sugarDelay = 0; sugarCountDown = (int)(SimulationSettings.Custom.SugarTotalCount * (1 + (SimulationSettings.Custom.SugarTotalCountPlayerMultiplier * playerCount))); sugarLimit = (int)(SimulationSettings.Custom.SugarSimultaneousCount * (1 + (SimulationSettings.Custom.SugarCountPlayerMultiplier * playerCount))); // Fruit-relevant stuff fruitDelay = 0; fruitCountDown = (int)(SimulationSettings.Custom.FruitTotalCount * (1 + (SimulationSettings.Custom.FruitTotalCountPlayerMultiplier * playerCount))); fruitLimit = (int)(SimulationSettings.Custom.FruitSimultaneousCount * (1 + (SimulationSettings.Custom.FruitCountPlayerMultiplier * playerCount))); // Ant-relevant stuff int antCountDown = (int)(SimulationSettings.Custom.AntTotalCount * (1 + (SimulationSettings.Custom.AntTotalCountPlayerMultiplier * playerCount))); antLimit = (int)(SimulationSettings.Custom.AntSimultaneousCount * (1 + (SimulationSettings.Custom.AntCountPlayerMultiplier * playerCount))); // Spielfeld erzeugen float area = SimulationSettings.Custom.PlayGroundBaseSize; area *= 1 + (playerCount * SimulationSettings.Custom.PlayGroundSizePlayerMultiplier); int playgroundWidth = (int)Math.Round(Math.Sqrt(area * 4 / 3)); int playgroundHeight = (int)Math.Round(Math.Sqrt(area * 3 / 4)); Playground = new CorePlayground(playgroundWidth, playgroundHeight, random, playerCount); // Bugs-relevant stuff Bugs = new CoreColony(Playground); Bugs.insectCountDown = (int)(SimulationSettings.Custom.BugTotalCount * (1 + (SimulationSettings.Custom.BugTotalCountPlayerMultiplier * playerCount))); bugLimit = (int)(SimulationSettings.Custom.BugSimultaneousCount * (1 + (SimulationSettings.Custom.BugCountPlayerMultiplier * playerCount))); // Völker erzeugen Teams = new CoreTeam[configuration.Teams.Count]; for (int i = 0; i < configuration.Teams.Count; i++) { TeamInfo team = configuration.Teams[i]; Teams[i] = new CoreTeam(i, team.Guid, team.Name); Teams[i].Colonies = new CoreColony[team.Player.Count]; // Völker erstellen for (int j = 0; j < team.Player.Count; j++) { PlayerInfo player = team.Player[j]; CoreColony colony = new CoreColony(Playground, player, Teams[i]); Teams[i].Colonies[j] = colony; colony.AntHills.Add(Playground.NeuerBau(colony.Id)); colony.insectCountDown = antCountDown; } } }
/// <summary> /// Berechnet einen neuen Spielschritt /// </summary> /// <returns>Zustandskopie des Simulationsstandes nachdem der Schritt ausgeführt wurde</returns> /// <throws>RuleViolationException</throws> /// <throws>Exception</throws> public void Step(SimulationState simulationState) { currentRound++; #region Food removeSugar(); spawnSugar(); spawnFruit(); #endregion #region Bugs Bugs.Grids[0].Clear(); for (int i = 0; i < Teams.Length; i++) { for (int j = 0; j < Teams[i].Colonies.Length; j++) { Bugs.Grids[0].Add(Teams[i].Colonies[j].Insects); } } // Lasse die Wanzen von der Spiel Befehle entgegen nehmen. //foreach (CoreBug wanze in Bugs.Insects) { // wanze.NimmBefehleEntgegen = true; //} // Schleife über alle Wanzen. for (int bugIndex = 0; bugIndex < Bugs.Insects.Count; bugIndex++) { CoreBug bug = Bugs.Insects[bugIndex] as CoreBug; Debug.Assert(bug != null); bug.NimmBefehleEntgegen = true; // Finde Ameisen in Angriffsreichweite. List <CoreInsect> ants = Bugs.Grids[0].FindAnts(bug); // Bestimme wie der Schaden auf die Ameisen verteilt wird. if (ants.Count >= SimulationSettings.Custom.BugAttack) { // Es sind mehr Ameisen in der SpielUmgebung als die Wanze // Schadenpunke verteilen kann. Daher werden den Ameisen am // Anfang der Liste jeweils ein Energiepunkt abgezogen. for (int index = 0; index < SimulationSettings.Custom.BugAttack; index++) { ants[index].AktuelleEnergieBase--; //((Ameise)ameisen[i]).WirdAngegriffen(wanze); PlayerCall.UnderAttack((CoreAnt)ants[index], bug); if (ants[index].AktuelleEnergieBase <= 0) { ants[index].colony.EatenInsects.Add(ants[index]); } } } else if (ants.Count > 0) { // Bestimme die Energie die von jeder Ameise abgezogen wird. // Hier können natürlich Rundungsfehler auftreten, die die Wanze // abschwächen, die ignorieren wir aber. int schaden = SimulationSettings.Custom.BugAttack / ants.Count; for (int index = 0; index < ants.Count; index++) { ants[index].AktuelleEnergieBase -= schaden; //((Ameise)ameisen[i]).WirdAngegriffen(wanze); PlayerCall.UnderAttack((CoreAnt)ants[index], bug); if (ants[index].AktuelleEnergieBase <= 0) { ants[index].colony.EatenInsects.Add(ants[index]); } } } // Während eines Kampfes kann die Wanze sich nicht bewegen. if (ants.Count > 0) { continue; } // Bewege die Wanze. bug.Bewegen(); if (bug.RestStreckeBase == 0) { bug.DreheInRichtungBase(random.Next(360)); bug.GeheGeradeausBase(random.Next(160, 320)); } bug.NimmBefehleEntgegen = false; } // Verhindere, daß ein Spieler einer gesichteten Wanze Befehle gibt. //for(int i = 0; i < Bugs.Insects.Count; i++) { // CoreBug wanze = Bugs.Insects[i] as CoreBug; // if(wanze != null) { // wanze.NimmBefehleEntgegen = false; // } //} #endregion #region Ants // Loop through all teams. for (int teamIndex = 0; teamIndex < Teams.Length; teamIndex++) { // Loop through all colonies in that team. for (int colonyIndex = 0; colonyIndex < Teams[teamIndex].Colonies.Length; colonyIndex++) { CoreColony colony = Teams[teamIndex].Colonies[colonyIndex]; // Leere alle Buckets. for (int casteIndex = 0; casteIndex < colony.AnzahlKasten; casteIndex++) { colony.Grids[casteIndex].Clear(); } // Fülle alle Buckets, aber befülle keinen Bucket doppelt. for (int casteIndex = 0; casteIndex < colony.AnzahlKasten; casteIndex++) { if (colony.Grids[casteIndex].Count == 0) { colony.Grids[casteIndex].Add(Bugs.Insects); for (int j = 0; j < Teams.Length; j++) { for (int i = 0; i < Teams[j].Colonies.Length; i++) { CoreColony v = Teams[j].Colonies[i]; colony.Grids[casteIndex].Add(v.Insects); } } } } // Schleife über alle Ameisen. for (int antIndex = 0; antIndex < colony.Insects.Count; antIndex++) { CoreAnt ameise = colony.Insects[antIndex] as CoreAnt; Debug.Assert(ameise != null); // Finde und Zähle die Insekten im Sichtkreis der Ameise. CoreBug wanze; CoreAnt feind; CoreAnt freund; CoreAnt teammember; int bugCount, enemyAntCount, colonyAntCount, casteAntCount, teamAntCount; colony.Grids[ameise.CasteIndexBase].FindAndCountInsects( ameise, out wanze, out bugCount, out feind, out enemyAntCount, out freund, out colonyAntCount, out casteAntCount, out teammember, out teamAntCount); ameise.BugsInViewrange = bugCount; ameise.ForeignAntsInViewrange = enemyAntCount; ameise.FriendlyAntsInViewrange = colonyAntCount; ameise.FriendlyAntsFromSameCasteInViewrange = casteAntCount; ameise.TeamAntsInViewrange = teamAntCount; // Bewege die Ameise. ameise.Bewegen(); #region Reichweite // Ameise hat ihre Reichweite überschritten. if (ameise.ZurückgelegteStreckeI > colony.ReichweiteI[ameise.CasteIndexBase]) { ameise.AktuelleEnergieBase = 0; colony.VerhungerteInsekten.Add(ameise); continue; } // Ameise hat ein Drittel ihrer Reichweite zurückgelegt. else if (ameise.ZurückgelegteStreckeI > colony.ReichweiteI[ameise.CasteIndexBase] / 3) { if (ameise.IstMüdeBase == false) { ameise.IstMüdeBase = true; PlayerCall.BecomesTired(ameise); } } #endregion #region Kampf // Rufe die Ereignisse auf, falls die Ameise nicht schon ein // entsprechendes Ziel hat. if (wanze != null && !(ameise.ZielBase is CoreBug)) { PlayerCall.SpotsEnemy(ameise, wanze); } if (feind != null && !(ameise.ZielBase is CoreAnt) || (ameise.ZielBase is CoreAnt && ((CoreAnt)ameise.ZielBase).colony == colony)) { PlayerCall.SpotsEnemy(ameise, feind); } if (freund != null && !(ameise.ZielBase is CoreAnt) || (ameise.ZielBase is CoreAnt && ((CoreAnt)ameise.ZielBase).colony != colony)) { PlayerCall.SpotsFriend(ameise, freund); } if (teammember != null && !(ameise.ZielBase is CoreAnt) || (ameise.ZielBase is CoreAnt && ((CoreAnt)ameise.ZielBase).colony != colony)) { PlayerCall.SpotsTeamMember(ameise, teammember); } // Kampf mit Wanze. if (ameise.ZielBase is CoreBug) { CoreBug k = (CoreBug)ameise.ZielBase; if (k.AktuelleEnergieBase > 0) { int entfernung = CoreCoordinate.BestimmeEntfernungI(ameise.CoordinateBase, ameise.ZielBase.CoordinateBase); if (entfernung < SimulationSettings.Custom.BattleRange * PLAYGROUND_UNIT) { k.AktuelleEnergieBase -= ameise.AngriffBase; if (k.AktuelleEnergieBase <= 0) { Bugs.EatenInsects.Add(k); colony.Statistik.KilledBugs++; ameise.BleibStehenBase(); } } } else { ameise.ZielBase = null; } } // Kampf mit feindlicher Ameise. else if (ameise.ZielBase is CoreAnt) { CoreAnt a = (CoreAnt)ameise.ZielBase; if (a.colony != colony && a.AktuelleEnergieBase > 0) { int entfernung = CoreCoordinate.BestimmeEntfernungI(ameise.CoordinateBase, ameise.ZielBase.CoordinateBase); if (entfernung < SimulationSettings.Custom.BattleRange * PLAYGROUND_UNIT) { PlayerCall.UnderAttack(a, ameise); a.AktuelleEnergieBase -= ameise.AngriffBase; if (a.AktuelleEnergieBase <= 0) { a.colony.BeatenInsects.Add(a); colony.Statistik.KilledAnts++; ameise.BleibStehenBase(); } } } else { ameise.ZielBase = null; } } #endregion // Prüfe ob die Ameise an ihrem Ziel angekommen ist. if (ameise.AngekommenBase) { ameiseUndZiel(ameise); } // Prüfe ob die Ameise einen Zuckerhaufen oder ein Obststück sieht. ameiseUndZucker(ameise); if (ameise.GetragenesObstBase == null) { ameiseUndObst(ameise); } // Prüfe ob die Ameise eine Markierung bemerkt. ameiseUndMarkierungen(ameise); if (ameise.ZielBase == null && ameise.RestStreckeBase == 0) { PlayerCall.Waits(ameise); } PlayerCall.Tick(ameise); } removeAnt(colony); spawnAnt(colony); aktualisiereMarkierungen(colony); removeFruit(colony); } } #endregion #region Bugs again removeBugs(); healBugs(); spawnBug(); #endregion bewegeObstUndInsekten(); erzeugeZustand(simulationState); }
/// <summary> /// Entfernt abgelaufene Markierungen und erzeugt neue Markierungen. /// </summary> /// <param name="colony">betroffenes Volk</param> private static void aktualisiereMarkierungen(CoreColony colony) { // TODO: Settings berücksichtigen // Markierungen aktualisieren und inaktive Markierungen löschen. List <CoreMarker> gemerkteMarkierungen = new List <CoreMarker>(); foreach (CoreMarker markierung in colony.Marker) { if (markierung.IstAktiv) { markierung.Aktualisieren(); } else { gemerkteMarkierungen.Add(markierung); } } gemerkteMarkierungen.ForEach(delegate(CoreMarker marker) { colony.Insects.ForEach(delegate(CoreInsect insect) { CoreAnt ant = insect as CoreAnt; if (ant != null) { ant.SmelledMarker.Remove(marker); } }); }); //for(int i = 0; i < gemerkteMarkierungen.Count; i++) { // CoreMarker markierung = gemerkteMarkierungen[i]; // for(int j = 0; j < volk.Insects.Count; j++) { // CoreAnt ameise = volk.Insects[j] as CoreAnt; // if(ameise != null) { // ameise.GerocheneMarkierungen.Remove(markierung); // } // } //} colony.Marker.Remove(gemerkteMarkierungen); // Neue Markierungen überprüfen und hinzufügen. gemerkteMarkierungen.Clear(); colony.NewMarker.ForEach(delegate(CoreMarker newMarker) { bool zuNah = false; //for(int i = 0; i < volk.Marker.Count; i++) { // CoreMarker marker = volk.Marker[i]; // if(marker != null) { // int distance = // CoreCoordinate.BestimmeEntfernungDerMittelpunkteI // (marker.Coordinate, newMarker.Coordinate); // if(distance < SimulationSettings.Settings.MarkerDistance * SPIELFELD_EINHEIT) { // zuNah = true; // break; // } // } //} foreach (CoreMarker markierung in colony.Marker) { int entfernung = CoreCoordinate.BestimmeEntfernungDerMittelpunkteI (markierung.CoordinateBase, newMarker.CoordinateBase); if (entfernung < SimulationSettings.Custom.MarkerDistance * PLAYGROUND_UNIT) { zuNah = true; break; } } if (!zuNah) { colony.Marker.Add(newMarker); } }); //foreach (CoreMarker neueMarkierung in volk.NewMarker) { // bool zuNah = false; // foreach (CoreMarker markierung in volk.Marker) { // int entfernung = // CoreCoordinate.BestimmeEntfernungDerMittelpunkteI // (markierung.Coordinate, neueMarkierung.Coordinate); // if (entfernung < SimulationSettings.Settings.MarkerDistance * SPIELFELD_EINHEIT) { // zuNah = true; // break; // } // } // if (!zuNah) { // volk.Marker.Add(neueMarkierung); // } //} colony.NewMarker.Clear(); }