Gesprühte Markierungen mit mehr Informationen anreichern

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Gesprühte Markierungen mit mehr Informationen anreichern

      Hallo Zusammen

      Ich habe nach einer Möglichkeit gesucht, mehr Informationen durch das benutzen von SprüheMarkierung() an andere Ameisen zu verteilen als nur einen Wert.
      Den Quell-Code zur Kernfunktionsweise zu AntMe! wollte ich nicht ändern. Das Ergbniss ist nun folgendes:

      Ich habe 4 funktionen zu meiner abgeleiteten Basisameise hinzugefügt:

      KombiniereMarkerRichtungEntfernung
      (enMarker iMarker, int iRichtung, int iEntfernung)
      ExtrahiereMarker(int iInformation)
      ExtrahiereEntfernung(int iInformation)
      ExtrahiereRichtung(int iInformation)

      Mit der ersten Funktion kann ich die Informationen Richtung, Entfernung und einen Wert zwischen 1-63 (aus einem enum) zu einem Integer zusammenrechnen.
      Diesen Integer kann ich dann der Funktion SprüheMarkierung() übergeben.
      Die anderen 3 funktionen extrahieren die gewünschte Information wieder.

      Kann folgendermassen benutzt werden:

      Quellcode

      1. SprüheMarkierung(KombiniereMarkerRichtungEntfernung(enMarker.Zucker, Koordinate.BestimmeRichtung(this, zuLetzterZuckerhaufen), Koordinate.BestimmeEntfernung(this, zuLetzterZuckerhaufen)), 20);


      Quellcode

      1. public override void RiechtFreund(Markierung markierung)
      2. {
      3. enMarker MarkerID = ExtrahiereMarker(markierung.Information);
      4. int iRichtung = ExtrahiereRichtung(markierung.Information);
      5. int iEntfernung = ExtrahiereEntfernung(markierung.Information);
      6. if (MarkerID == enMarker.Zucker)
      7. { // Aha! Ameisenkollege hat Spur zu Zucker gelegt }
      8. }


      Der Quellcode dazu ist folgender (benögtigt ein bisschen Logik und Binärkentnisse):

      Quellcode

      1. #region Markierungen
      2. // Marker IDs die die Ameise versprüht
      3. // Marker IDs werden aufsteigend nummeriert: Zucker = 1, Obst = 2, etc.
      4. // Kann beliebig erweitert werden:
      5. private enum enMarker { Zucker = 1, Obst, Wanze, FeindlicheAmeise, LeuchtfeuerZucker, LeuchtfeuerObst };
      6. /// <summary>
      7. /// Kombiniert einen Marker mit Richtung und Entfernung und gibt einen Integer zurück der von einer Ameise versprüht werden kann
      8. /// Die Entfernung muss zwischen 131071 und 0 sein (max. 17Bit)
      9. /// Die Richtung muss zwischen 360 und 0 sein (max. 9bit)
      10. /// Die ID des Markers muss zwischen 1 und 63 sein (max. 6bit)
      11. /// Summe max. 32Bit = Maximale Integerlänge
      12. /// </summary>
      13. /// <param name="iMarker">Der Marker</param>
      14. /// <param name="iRichtung">Die Richtung</param>
      15. /// <param name="iEntfernung">Die Entfernung</param>
      16. private int KombiniereMarkerRichtungEntfernung(enMarker iMarker, int iRichtung, int iEntfernung)
      17. {
      18. // Eingaben validieren, sollte ein Wert ausserhalb des erwünschten Wertebereich liegen,
      19. // so wird die Eingabe auf den maximalen, bzw. minimalen Wert gesetzt.
      20. iEntfernung = (iEntfernung > 131071) ? 131071 : iEntfernung;
      21. iEntfernung = (iEntfernung < 0) ? 0 : iEntfernung;
      22. iRichtung = (iRichtung > 360) ? 360 : iRichtung;
      23. iRichtung = (iRichtung < 0) ? 0 : iRichtung;
      24. iMarker = ((int)iMarker < 0) ? (enMarker)1 : iMarker;
      25. iMarker = ((int)iMarker > 63) ? (enMarker)63 : iMarker;
      26. // Marker und Entfernung kombinieren:
      27. /// z.B: Marker = 6 = 110 / Entfernung = 120 = 1111000
      28. /// Marker um 17 Bit nach links verschieben (weil die Enfernung maximal 17 Bits darstellt): 11000000000000000000
      29. /// Zu diesem neuen Wert die Entfernung hinzurechnen: 11000000000000000000 + 1111000 = 11000000000001111000
      30. /// Das selbe Spiel wiederholen um die Richtung hinzuzufügen
      31. int iKombination = ((int)iMarker << 17) + iEntfernung;
      32. iKombination = (iKombination << 9) + iRichtung;
      33. return iKombination;
      34. }
      35. /// <summary>
      36. /// Rechnet den Marker aus einer Markierung die mit KombiniereMarkerRichtungEntfernung erstellt wurde heraus
      37. /// </summary>
      38. /// <param name="iInformation">Die Information die die Ameise gerochen hat</param>
      39. private enMarker ExtrahiereMarker(int iInformation)
      40. {
      41. // Die ersten 26Bit entfernen, weil dort Entfernung und Richtung gespeichert ist, der Rest ist dann der Marker
      42. int iMarker = iInformation >> 26;
      43. return (enMarker)iMarker;
      44. }
      45. /// <summary>
      46. /// Rechnet die Richtung aus einer Markierung die mit KombiniereMarkerRichtungEntfernung erstellt wurde heraus
      47. /// </summary>
      48. /// <param name="iInformation">Die Information die die Ameise gerochen hat</param>
      49. private int ExtrahiereRichtung(int iInformation)
      50. {
      51. // Nur die ersten 9 Bit enthalten die richtigen Informationen
      52. // 511 = 111111111 -> alle 9 Bit auf. 511 mit der Information UND-Verknüpfen um alle Bits auf 0 zu setzen,
      53. // die nicht zu den ersten 9 Bit gehören
      54. return iInformation & 511;
      55. }
      56. /// <summary>
      57. /// Rechnet die Entfernung aus einer Markierung die mit KombiniereMarkerRichtungEntfernung erstellt wurde heraus
      58. /// </summary>
      59. /// <param name="iInformation">Die Information die die Ameise gerochen hat</param>
      60. private int ExtrahiereEntfernung(int iInfromation)
      61. {
      62. // Um den Wert (der sich in der "Mitte" befindet) herauszurechnen,
      63. // können die Methoden aus ExtrahiereMarker und ExtrahiereRichtung kombiniert werden
      64. // 1. Die ersten 9 Bit entfernen
      65. // 2. UND-Verknüpfen mit 131072 = 11111111111111111 (17 Bit, die alle auf 1 sind)
      66. int iEntfernung = iInfromation >> 9;
      67. return iEntfernung & 131071;
      68. }
      69. #endregion
      Alles anzeigen


      Möglicherweise hat jemand von euch noch Verbesserungsvorschläge?
      Die Code kann natürlich so angepasst werden, um andere Information zum kombinieren.

      Gibt es ein Syntax highlighting?

      Gruss WorldOfDon