/// <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> /// Findet die Markierung, die die gegebene Ameise noch nicht gerochen hat /// und die der Ameise am nächsten liegt. /// </summary> /// <remarks> /// Die Simulation legt ein Gitter mit dem maximalen Radius einer Markierung als /// Seitenlänge an und benutzt diese Methode auf dieser Instanz zum Finden von /// Markierungen. In dieses Gitter werden nur Markierungen einsortiert. /// </remarks> /// <param name="ant">Die Referenzameise.</param> /// <returns>Eine Markierung.</returns> public CoreMarker FindMarker(CoreAnt ant) { CoreMarker nearestMarker = null; int nearestMarkerDistance = int.MaxValue; // Bestimme die Zelle in der die übergebene Ameise sich befindet. int col = ant.CoordinateBase.X / sideLength; int row = ant.CoordinateBase.Y / sideLength; // Betrachte die Zelle und die acht Zellen daneben. for (int c = -1; c <= 1; c++) { if (col + c >= 0 && col + c < columns) { for (int r = -1; r <= 1; r++) { if (row + r >= 0 && row + r < rows) { List <T> cell = cells[col + c, row + r]; // Betrachte alle Markierungen in der aktuellen Zelle. for (int i = 0; i < cell.Count; i++) { CoreMarker marker = cell[i] as CoreMarker; Debug.Assert(marker != null); // Bestimme die Entfernung der Mittelpunkte und der Kreise. int distance = CoreCoordinate.BestimmeEntfernungDerMittelpunkteI(ant.CoordinateBase, marker.CoordinateBase); int circleDistance = distance - ant.CoordinateBase.Radius - marker.CoordinateBase.Radius; // Die neue Markierung wurde noch nicht gerochen und // liegt näher als die gemerkte. if (circleDistance <= 0 && distance < nearestMarkerDistance && !ant.SmelledMarker.Contains(marker)) { nearestMarkerDistance = distance; nearestMarker = marker; } } } } } } return(nearestMarker); }
/// <summary> /// Berechnet die Bewegung des Insekts. /// </summary> internal void Bewegen() { reached = false; // Insekt dreht sich. if (restWinkel != 0) { // Zielwinkel wird erreicht. if (Math.Abs(restWinkel) < colony.Drehgeschwindigkeit[CasteIndexBase]) { koordinate.Richtung += restWinkel; restWinkel = 0; } // Insekt dreht sich nach rechts. else if (restWinkel >= colony.Drehgeschwindigkeit[CasteIndexBase]) { koordinate.Richtung += colony.Drehgeschwindigkeit[CasteIndexBase]; RestWinkelBase -= colony.Drehgeschwindigkeit[CasteIndexBase]; } // Insekt dreht sich nach links. else if (restWinkel <= -colony.Drehgeschwindigkeit[CasteIndexBase]) { koordinate.Richtung -= colony.Drehgeschwindigkeit[CasteIndexBase]; RestWinkelBase += colony.Drehgeschwindigkeit[CasteIndexBase]; } } // Insekt geht. else if (restStreckeI > 0) { if (GetragenesObstBase == null) { int strecke = Math.Min(restStreckeI, aktuelleGeschwindigkeitI); restStreckeI -= strecke; zurückgelegteStreckeI += strecke; koordinate.X += SimulationEnvironment.Cos[strecke, koordinate.Richtung]; koordinate.Y += SimulationEnvironment.Sin[strecke, koordinate.Richtung]; } } // Insekt geht auf Ziel zu. else if (ziel != null) { int entfernungI; if (ZielBase is CoreMarker) { entfernungI = CoreCoordinate.BestimmeEntfernungDerMittelpunkteI(koordinate, ziel.CoordinateBase); } else { entfernungI = CoreCoordinate.BestimmeEntfernungI(koordinate, ziel.CoordinateBase); } reached = entfernungI <= SimulationEnvironment.PLAYGROUND_UNIT; if (!reached) { int richtung = CoreCoordinate.BestimmeRichtung(koordinate, ziel.CoordinateBase); // Ziel ist in Sichtweite oder Insekt trägt Obst. if (entfernungI < colony.SichtweiteI[CasteIndexBase] || getragenesObst != null) { restStreckeI = entfernungI; } // Ansonsten Richtung verfälschen. else { richtung += RandomBase.Next(-18, 18); restStreckeI = colony.SichtweiteI[CasteIndexBase]; } dreheInRichtung(richtung); } } // Koordinaten links begrenzen. if (koordinate.X < 0) { koordinate.X = -koordinate.X; if (koordinate.Richtung > 90 && koordinate.Richtung <= 180) { koordinate.Richtung = 180 - koordinate.Richtung; } else if (koordinate.Richtung > 180 && koordinate.Richtung < 270) { koordinate.Richtung = 540 - koordinate.Richtung; } } // Koordinaten rechts begrenzen. else if (koordinate.X > colony.BreiteI) { koordinate.X = colony.BreiteI2 - koordinate.X; if (koordinate.Richtung >= 0 && koordinate.Richtung < 90) { koordinate.Richtung = 180 - koordinate.Richtung; } else if (koordinate.Richtung > 270 && koordinate.Richtung < 360) { koordinate.Richtung = 540 - koordinate.Richtung; } } // Koordinaten oben begrenzen. if (koordinate.Y < 0) { koordinate.Y = -koordinate.Y; if (koordinate.Richtung > 180 && koordinate.Richtung < 360) { koordinate.Richtung = 360 - koordinate.Richtung; } } // Koordinaten unten begrenzen. else if (koordinate.Y > colony.HöheI) { koordinate.Y = colony.HöheI2 - koordinate.Y; if (koordinate.Richtung > 0 && koordinate.Richtung < 180) { koordinate.Richtung = 360 - 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); } }); }); //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(); }