locked
Zeigt her Eure Ameisen! Hilfe bei Tutorials gesucht!

    Frage

  • Hallo liebe Ameisenprofis!

    Ich suche Freiwillige, die Ihre selbstgebauten Ameisenvölker für Tutorials zur Verfügung stellen, zusammen mit Erläuterungen was die "Tricks" und vielleicht auch die Schwächen des einzelnen Volks sind.

    Ihr braucht ja nicht Eure Elite-Völker einsenden (wenn Ihr Eure besten Völker noch bis zum Multiplayer-Modus geheimhalten wollt  -  auch frühe Versionen tun's völlig.

    Wichtig ist halt viel Text, der beschreibt wo Ihr Probleme hattet, was gut funktioniert, und was Eure grundlegenden Ideen bei der Entwicklung des jeweiligen Volks waren - damit andere Ameisen-Einstieger daraus lernen können.

    Ihr könnt die Antworten entweder hier posten, oder an antmetshirt@hotmail.de schicken. Natürlich werdet Ihr überall genannt, wo Euer Ameisenvolk vorkommt - wenn Ihr wollt, könnt Ihr auch Eure Homepage oder Messenger-Account usw. nennen, dann schreibe ich das immer dazu (ist aber freiwillig). Bitte auch sagen, wenn Ihr anonym bleiben wollt.

    Ich freue mich schon auf einen Volksauflauf !

    Viele Grüße, Uwe

    Dienstag, 21. November 2006 08:55
    Moderator

Alle Antworten

  • Hm? soll ich gleich als eine der ersten Antworten hier wieder Öl ins Feuer der Diskussion um die statischen Variablen gießen? - Ich werde es einmal wagen

    hier ein paar Codeschnipsel aus meinen "extremen Käferkillern"

    zunächst habe ich eine statisches Array für alle Ameisen angelegt:

            private static ArrayList ameisen;

    im Konstruktor wird es initialisiert:

                    if (ameisen == null)
                    {
                        ameisen = new ArrayList();
                    }
    und die mit dem Konstruktor erzeugte Ameise eingetragen:
                    ameisen.Add(this);

    Jetzt wollte ich von der statischen/globalen Sicht wieder einen Schritt zurück - Die Ameisen sollen ihre "Nachbarn" kennen lernen. Dafür habe ich eine Methode implementiert, die ein nach der Distanz sortiertes Array der Ameisen zurückgibt.

    Doch wie sortiere ich die Ameisen am einfachsten? - Sortierverfahren selber implementieren? - nicht nötig!

    Zunächst habe ich eine innere Klasse "AmeisenDistanz" eingeführt, die lediglich eine Instanz der Ameise und eine Distanz-Information enthält und das "IComparable" Interface implementiert.


            private class AmeisenDistanz : IComparable
            {
                public MeineAmeise1 ameise;
                public int distanz;
                public AmeisenDistanz(MeineAmeise1 ameise, int distanz)
                {
                    this.ameise = ameise;
                    this.distanz = distanz;
                }

                int IComparable.CompareTo(object obj)
                {
                    AmeisenDistanz ameisenDistanz = (AmeisenDistanz)obj;
                    if (this.distanz < ameisenDistanz.distanz)
                    {
                        return 1;
                    }
                    if (this.distanz > ameisenDistanz.distanz)
                    {
                        return -1;
                    }
                    return 0;
                }
            }

    Nun also zur Methode der Ameise:

            private ArrayList AmeisenInReichweite()
            {
                ArrayList ameisenInReichweite = new ArrayList();
                ArrayList ameisenDistanzen = new ArrayList();
                foreach (MeineAmeise1 ameise in ameisen)
                {
                    ameisenDistanzen.Add(new AmeisenDistanz(ameise, Koordinate.BestimmeEntfernung(this,ameise)));
                }
                ameisenDistanzen.Sort();
                foreach (AmeisenDistanz ameisenDistanz in ameisenDistanzen)
                {
                    ameisenInReichweite.Add(ameisenDistanz.ameise);
                }
                return ameisenInReichweite;
            }

    kurz erklärt: Ich übertrage das Array aller Ameisen in ein Array der AmeisenDistanzen, sortiere es und übertrage es zurück in ein Array von Ameisen.

    Wenn jetzt also eine Ameise einen Käfer sieht, kann sie sich das Array der Nachbarn holen und so zum Beispiel die ersten 15, oder alle in einem bestimmten Radius (in Falle der "extremen Käferkiller" - ist es ein Radius von 200) benachrichtigen.

    Performacetechnisch fällt vielleicht auf, dass gestorbene Ameisen nicht aus dem Array gelöscht werden. Das ist auch mir bewusst. In einem Durchlauf mit meinem aktuellen Volk ( Energie +2) sterben allerdings weniger Ameisen als Käfer und ich nehme diesen Nachteil ganz einfach in Kauf.

    PS: Auf ähnliche Art und Weise lassen sich nicht nur die Ameisen in einem Array speichern, sondern auch Käfer, Äpfel und Zuckerhaufen - mehr verrat' ich dazu aber nicht.

    Ich bin ja schonmal gespannt, was hier noch alles landet.

    mfG
    Felix Woitzel
    Dienstag, 21. November 2006 11:11
  • Hi,

    kannst du darauf evtl. etwas näher eingehen? Hatte was ähnliches vor und bin an dem Array gescheitert. Habe in C# gerade erst angefangen, programmiere aber schon etwas Länger in anderen serverbasierten sprachen. Auf der suche nach ner Lösung bin ich auf deinen Post hier gestoßen und dies erstmal versucht ein wenig nachzubauen. Bekomme aber schon anfangs folgende Fehler:

    Fehler    1    Ungültiges Token "if" in Klasse, Struktur oder Schnittstellenmemberdeklaration.
    Fehler    2    Ungültiges Token "==" in Klasse, Struktur oder Schnittstellenmemberdeklaration.

    Ich habe nur folgenden Code übernommen:

            ArrayList ameisen = new ArrayList();
            private static ArrayList ameisen;
            if(ameisen == null) {
          
            }

    und diesen unter "public class MeineAmeise1 : Ameise   {" eingefügt.

    Wäre dir sehr dankbar wenn du mir ein par Hinweise geben könntest wie ich vorgehen muss dass es klappt.

    Gruß
    Sonntag, 26. November 2006 19:45
  • Das kann leider nicht gehen.
    Die Deklarationen
            ArrayList ameisen = new ArrayList();
            private static ArrayList ameisen;
    sind natürlich in der Klasse möglich. Die IF-Bedingung, also Code, kannst du aber nur in Methoden (und Properties) schreiben. Also musst du vorher eine der Methoden auswählen, z.B. Sieht(Zucker zucker) und dort deine IF abfrage einbauen. Z.B. so: (nachfolgender code ist ohne sinn ;-)
    public override void Sieht(Zucker zucker)
    {
        if(zucker==null)
        {
        }
    }

    Hoffe dir geholfen zu haben.

    marco

    Sonntag, 26. November 2006 20:36
  • Vielen Dank! Nun kanns endlich weiter gehen :)

    Morgen erstmal die nötige Literatur besorgen.

    Gruß
    Sonntag, 26. November 2006 20:50
  • Um dich vielleicht etwas zu erleichtern. Ich hatte bis ich Antme kennen gelernt habe auch lediglich mal ein "hallo welt" mit C# programmiert (, als erste alktion nach dem installieren des VisualStudio).
    Benutz mal google und die Stichwörter "galileo openbook c#"

    Felix
    Montag, 27. November 2006 00:04
  • Habe mir nun vom Galileo Verlag ein Buch bestellt :) Habe noch viele andere Bücher von dem Verlag und bin davon recht überzeugt.

     Hätte da direkt noch 2 Verständnissfragen. Seh ich dsa richtig das der komplette Code in der "vorlage.cs" in jeder Runde neu "abgearbeitet" wird? Und gibt es schon eine funktion in der sich ermitteln lässt  was die Ameise gerade genau tut? Also wenn man sich im 2D Modus befindet und eine Ameise markiert bekommt man ja angezeigt welche Aufgabe diese z.Z. ausführt, kann man diesen status in ner Variablen/Funktion abfragen?

    Gruß
    Montag, 27. November 2006 19:11
  • Hallo,

    Theoretisch kannst du den "Zustand" der Ameise abrufen. Allerdings ein etwas "abenteuerliches" konstrukt und man müsste das Plugin Assembly als Referenz mit einbinden, um Zugriff auf die Klasse "AmeisenInfo" zu bekommen..oder aber mit wirren Reflection dingen...
    Ok, aber um es kurz zu machen:

    Du kannst dir eine solche Funktion leicht selbst bauen. Dazu erstellst du in deiner Ameisenklasse eine neue Methode, z.b. so:

    private string WieIstMeinZustand()
    {

       string zustand = "";

       if (Ziel is Bau) {
         if (GetragenesObst != null)
                   zustand =
    "TrägtObstZuBau";
         else if (AktuelleLast > 0)
               zustand = "TrägtZuckerZuBau";
          else
            zustand =
    "GehtZuBau";
       }
       else if (Ziel is Zucker)
             zustand = "GehtZuZucker";
       else if (Ziel is Obst)
             zustand = "GehtZuObst";
       else if (Ziel is Käfer)
             zustand = "GreiftKäferAn";
       else
               zustand = "ErkundetUmgebung";

       return zustand;

    }

    Diese kannst du dann aufrufen und bekommst den Zustand als string zurück:
    string status = WieIstMeinZustand();

    viel spaß,
    marco

    Montag, 27. November 2006 20:27
  • Cool Danke!

    Habe heute mal wieder ein wenig weiter an meinen Ameisen gearbeitet, aber leider ohne Erfolg :(
    Irgendwie fehlts mir noch ein wenig am Verständniss der ganzen Sache. Mein Buch ist leider auch noch nicht angekommen um mich ein wenig mehr mit der Grundstruktur vertraut zu machen.

    In jeder Runde wird ja die Klasse MeineAmeise(X) aufgerunfen und dann eben die Funktion zb. "public override void Sieht(X x) ...". Wie aber führe ich dazwischen etwas aus? Das ganze sollte evtl. auch in das Tutorial um ein wenig beim Thema zu bleiben -g-.

    Gruß

    Dienstag, 28. November 2006 20:46
  • Ein "dazwischen" gibt es bisher nicht, denn das geht gegen das Konzept der Ereignisse. Sofern die Ameise ein Ziel hat, wird die Methode IstUnterwegs() in jeder Runde aufgerufen, das könnte man als "dazwischen" mißbrauchen. In der nächsten Version wird diese Methode warscheinlich durch eine neue ersetzt, die (unabhängig vom Ziel) in jeder Runde aufgerufen wird und zusätzliche Informationen über die Umgebung der Ameise liefert. Dann kann man sich entscheiden, ob man über die Ereignisse programmieren möchte, oder seine komplette Intelligenz in diese eine Methode steckt.
    Mittwoch, 29. November 2006 22:26
  • Achso ok. Dann werd ich wohl ein wenig umdenken müssen.

    Gruß
    Donnerstag, 30. November 2006 19:55