Ejemplo n.º 1
0
        /// <summary>
        /// Findet alle Spielelemente innerhalb des Sichtkreis der gegebenen Wanze.
        /// </summary>
        /// <remarks>
        /// Die Simulation legt ein Gitter mit der maximalen Sichtweite der Wanzen als
        /// Seitenlänge an und benutzt diese Methode auf dieser Instanz zum Finden von
        /// Ameisen. In dieses Gitter werden nur Ameisen einsortiert.
        /// </remarks>
        /// <param name="bug">Die Referenzwanze.</param>
        /// <returns>Eine Liste von Ameisen.</returns>
        public List <T> FindAnts(CoreBug bug)
        {
            // Speichert alle gefundenen Ameisen.
            List <T> ants = new List <T>();

            // Bestimme die Zelle in der die übergebene Wanze sich befindet.
            int col = bug.CoordinateBase.X / sideLength;
            int row = bug.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];
                            for (int i = 0; i < cell.Count; i++)
                            {
                                int distance = CoreCoordinate.BestimmeEntfernungI(bug.CoordinateBase, cell[i].CoordinateBase);
                                if (distance <= sideLength)
                                {
                                    ants.Add(cell[i]);
                                }
                            }
                        }
                    }
                }
            }

            return(ants);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Remove dead bugs.
 /// </summary>
 private void removeBugs()
 {
     for (int i = 0; i < Bugs.EatenInsects.Count; i++)
     {
         CoreBug bug = Bugs.EatenInsects[i] as CoreBug;
         if (bug != null)
         {
             Bugs.Insects.Remove(bug);
         }
     }
     Bugs.EatenInsects.Clear();
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Heals the bugs, if its time.
 /// </summary>
 private void healBugs()
 {
     if (currentRound % SimulationSettings.Custom.BugRegenerationDelay == 0)
     {
         for (int i = 0; i < Bugs.Insects.Count; i++)
         {
             CoreBug bug = Bugs.Insects[i] as CoreBug;
             if (bug != null)
             {
                 if (bug.AktuelleEnergieBase < bug.MaximaleEnergieBase)
                 {
                     bug.AktuelleEnergieBase += SimulationSettings.Custom.BugRegenerationValue;
                 }
             }
         }
     }
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Perform call to "Spots(Bug)" on given ant.
        /// </summary>
        /// <param name="ant">ant</param>
        /// <param name="bug">bug</param>
        public static void SpotsEnemy(CoreAnt ant, CoreBug bug)
        {
            AreaChanged(
                null, new AreaChangeEventArgs(ant.colony.Player, Area.SpotsBug));
            playerRights.PermitOnly();
            ant.NimmBefehleEntgegen = true;
            try {
                ant.SiehtFeindBase(bug);
            }
            catch (Exception ex) {
                throw new AiException("KI-Fehler in der SiehtFeind(Wanze)-Methode", ex);
            }

            ant.NimmBefehleEntgegen = false;
            AreaChanged(
                null, new AreaChangeEventArgs(null, Area.Unknown));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Perform call to "UnderAttack(Bug)" on given ant.
        /// </summary>
        /// <param name="ant">ant</param>
        /// <param name="bug">bug</param>
        public static void UnderAttack(CoreAnt ant, CoreBug bug)
        {
            AreaChanged(
                null,
                new AreaChangeEventArgs(
                    ant.colony.Player, Area.UnderAttackByBug));
            playerRights.PermitOnly();
            ant.NimmBefehleEntgegen = true;
            try {
                ant.WirdAngegriffenBase(bug);
            }
            catch (Exception ex) {
                throw new AiException("KI-Fehler in der WirdAngegriffen(Wanze)-Methode", ex);
            }

            ant.NimmBefehleEntgegen = false;
            AreaChanged(
                null, new AreaChangeEventArgs(null, Area.Unknown));
        }
Ejemplo n.º 6
0
        /// <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);
        }
Ejemplo n.º 7
0
 /// <summary>
 /// Wird wiederholt aufgerufen, wenn die Ameise von einer Wanze angegriffen
 /// wird.
 /// </summary>
 /// <param name="wanze">Die angreifende Wanze.</param>
 internal virtual void WirdAngegriffenBase(CoreBug wanze)
 {
 }
Ejemplo n.º 8
0
 /// <summary>
 /// Wird wiederholt aufgerufen, wenn die Ameise mindestens eine Wanze
 /// sieht.
 /// </summary>
 /// <param name="wanze">Die nächstgelegene Wanze.</param>
 internal virtual void SiehtFeindBase(CoreBug wanze)
 {
 }
Ejemplo n.º 9
0
        /// <summary>
        /// Findet die Wanze, die feindliche Ameise und die befreundete Ameise mit der
        /// geringsten Entfernung innerhalb des Sichtkreis der gegebenen Ameise und
        /// zählt die Anzahl an Wanzen, feindlichen und befreundeten Ameisen im Sichtkreis.
        /// </summary>
        /// <remarks>
        /// Wird für Ameisen verwendet. Die Simulation legt für jeden vorkommenden Sichtradius
        /// eine eigenes Gitter an und benutzt diese Methode auf der passenden Instanz zum Finden
        /// von Insekten. Die Seitenlänge dieses Gitters ist also der Sichradius der Ameise.
        /// In diese Gitter werden Wanzen und Ameisen einsortiert.
        /// </remarks>
        /// <param name="ant">Die Referenzameise.</param>
        /// <param name="nearestBug">Eine Wanze.</param>
        /// <param name="bugCount">Die Anzahl an Wanzen.</param>
        /// <param name="nearestEnemyAnt">Eine feindliche Ameise.</param>
        /// <param name="enemyAntCount">Die Anzahl an feindlichen Ameisen.</param>
        /// <param name="nearestColonyAnt">Eine befreundete Ameise.</param>
        /// <param name="colonyAntCount">Die Anzahl an befreundeten Ameisen.</param>
        /// <param name="casteAntCount">Die Anzahl an befreundeten Ameisen der selben Kaste.</param>
        public void FindAndCountInsects(CoreAnt ant, out CoreBug nearestBug, out int bugCount,
                                        out CoreAnt nearestEnemyAnt, out int enemyAntCount, out CoreAnt nearestColonyAnt,
                                        out int colonyAntCount, out int casteAntCount, out CoreAnt nearestTeamAnt,
                                        out int teamAntCount)
        {
            // Die nächstliegenden gefundenen Wanzen und Ameisen.
            nearestBug       = null;
            nearestEnemyAnt  = null;
            nearestColonyAnt = null;
            nearestTeamAnt   = null;

            // Die Entfernungen zu den nächstliegenden gefundenen Wanzen und Ameisen.
            int nearestBugDistance       = int.MaxValue;
            int nearestEnemyAntDistance  = int.MaxValue;
            int nearestColonyAntDistance = int.MaxValue;
            int nearestTeamAntDistance   = int.MaxValue;

            // Die Anzahlen der gefundenen Wanzen und Ameisen.
            bugCount       = 0;
            enemyAntCount  = 0;
            colonyAntCount = 0;
            casteAntCount  = 0;
            teamAntCount   = 0;

            // 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)
                        {
                            // Betrachte alle Insekten in der aktuellen Zelle.
                            List <T> cell = cells[col + c, row + r];
                            for (int i = 0; i < cell.Count; i++)
                            {
                                CoreInsect insect = cell[i] as CoreInsect;
                                Debug.Assert(insect != null);

                                if (insect == ant)
                                {
                                    continue;
                                }

                                // Vergleiche die Entfernung zum aktuellen Insekt mit der
                                // Sichtweite der Ameise bzw. der Seitenlänge des Gitters.
                                int distance = CoreCoordinate.BestimmeEntfernungI(ant.CoordinateBase, insect.CoordinateBase);
                                if (distance > sideLength)
                                {
                                    continue;
                                }

                                // Selbes Volk. Die Abfrage "insect is CoreAnt" ist unnötig.
                                if (insect.colony == ant.colony)
                                {
                                    colonyAntCount++;
                                    if (insect.CasteIndexBase == ant.CasteIndexBase)
                                    {
                                        casteAntCount++;
                                    }

                                    // Die neue Ameise liegt näher als die gemerkte.
                                    if (distance < nearestColonyAntDistance)
                                    {
                                        nearestColonyAntDistance = distance;
                                        nearestColonyAnt         = (CoreAnt)insect;
                                    }
                                }

                                // Selbes Team.
                                else if (insect.colony.Team == ant.colony.Team)
                                {
                                    teamAntCount++;

                                    // Die neue Ameise liegt näher als die gemerkte.
                                    if (distance < nearestTeamAntDistance)
                                    {
                                        nearestTeamAntDistance = distance;
                                        nearestTeamAnt         = (CoreAnt)insect;
                                    }
                                }

                                // Wanze.
                                else if (insect is CoreBug)
                                {
                                    bugCount++;

                                    // Die neue Wanze liegt näher als die gemerkte.
                                    if (distance < nearestBugDistance)
                                    {
                                        nearestBugDistance = distance;
                                        nearestBug         = (CoreBug)insect;
                                    }
                                }

                                // Feindliche Ameise.
                                else
                                {
                                    enemyAntCount++;

                                    // Die neue Ameise liegt näher als die gemerkte.
                                    if (distance < nearestEnemyAntDistance)
                                    {
                                        nearestEnemyAntDistance = distance;
                                        nearestEnemyAnt         = (CoreAnt)insect;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }