Ejemplo n.º 1
0
 public Mapstate RootState(PlanetWars pw)
 {
     MijnPlaneten = pw.MyPlanets();
     MijnAantalSchepen = pw.NumShips(1);
     VijandigePlaneten = pw.EnemyPlanets();
     NietMijnPlaneten = pw.NotMyPlanets();
     MijnPlaneten = pw.MyPlanets();
     VijandigeVloten = pw.EnemyFleets();
     Knoopstrategie = new List<Strategyfleet>();
     MijnVloten = pw.MyFleets();
     return this;
 }
Ejemplo n.º 2
0
    public static void DoTurn(PlanetWars pw)
    {
        // (1) If we current have a fleet in flight, then do nothing until it
        // arrives.
        if (pw.MyFleets().Count >= 1)
        {
            return;
        }
        // (2) Pick one of my planets at random.
        Random        r      = new Random();
        Planet        source = null;
        List <Planet> p      = pw.MyPlanets();

        if (p.Count > 0)
        {
            source = p[(int)(r.NextDouble() * p.Count)];
        }
        // (3) Pick a target planet at random.
        Planet dest = null;

        p = pw.Planets();
        if (p.Count > 0)
        {
            dest = p[(int)(r.NextDouble() * p.Count)];
        }
        // (4) Send half the ships from source to dest.
        if (source != null && dest != null)
        {
            int numShips = source.NumShips() / 2;
            pw.IssueOrder(source, dest, numShips);
        }
    }
Ejemplo n.º 3
0
 public static void DoTurn(PlanetWars pw)
 {
     foreach (Planet source in pw.MyPlanets())
     {
         if (source.NumShips() < 10 * source.GrowthRate())
         {
             continue;
         }
         Planet dest         = null;
         int    bestDistance = 999999;
         foreach (Planet p in pw.EnemyPlanets())
         {
             int dist = pw.Distance(source.PlanetID(), p.PlanetID());
             if (dist < bestDistance)
             {
                 bestDistance = dist;
                 dest         = p;
             }
         }
         if (dest != null)
         {
             pw.IssueOrder(source, dest, source.NumShips());
         }
     }
 }
Ejemplo n.º 4
0
    // The DoTurn function is where your code goes. The PlanetWars object
    // contains the state of the game, including information about all planets
    // and fleets that currently exist. Inside this function, you issue orders
    // using the pw.IssueOrder() function. For example, to send 10 ships from
    // planet 3 to planet 8, you would say pw.IssueOrder(3, 8, 10).
    //
    // There is already a basic strategy in place here. You can use it as a
    // starting point, or you can throw it out entirely and replace it with
    // your own. Check out the tutorials and articles on the contest website at
    // http://www.ai-contest.com/resources.
    public static void DoTurn(PlanetWars pw)
    {
        _spaceFile = new StreamWriter("C:\\Users\\Public\\Spacelist.txt", true);
        _openFile = new StreamWriter("C:\\Users\\Public\\Openlist.txt", true);
        _closedFile = new StreamWriter("C:\\Users\\Public\\Closedlist.txt", true);

        //bij iedere beurt wordt de root knoop opnieuw gelijk gezet aan de huidige (ongemuteerde) map state
        Mapstate root = new Mapstate(pw.MyPlanets(), pw.NumShips(1), pw.EnemyPlanets(), pw.NotMyPlanets(), pw.MyFleets(),
            pw.EnemyFleets(), new List<Strategyfleet>());
        root = root.RootState(pw);

        List<Strategyfleet> ordersWillBe = strategize(root);

        //loop door de lijst van orders
        foreach (Strategyfleet move in ordersWillBe)
        {
            pw.IssueOrder(move.Bron, move.Doel, move.Sterkte);
        }

        _spaceFile.Close();
        _openFile.Close();
        _closedFile.Close();

        //pw.IssueOrder(1, 2, 2000); //onmogelijke zet zodat we de boom op beurt 1 kunnen bekijken in de log file
    }
Ejemplo n.º 5
0
Archivo: MyBot.cs Proyecto: minskowl/MY
    private static void InitSituation(PlanetWars pw)
    {
        _readyForEcspancion.Clear();
        _needForHelp.Clear();
        log.WriteLine("========== My planets ====");

        foreach (var myPlanet in pw.MyPlanets())
        {
            var id = myPlanet.PlanetID;

            myPlanet.FleetSheeps = pw.Fleets()
                                   .Where(e => e.DestinationPlanet() == id)
                                   .Sum(e => e.Owner() == 1 ? e.NumShips() : -e.NumShips());

            if (myPlanet.TotalSheeps > redyForEcsCount)
            {
                _readyForEcspancion.Add(myPlanet);
            }
            if (myPlanet.TotalSheeps <= 0)
            {
                _needForHelp.Add(myPlanet);
            }
            log.WriteLine(string.Format("#{0} Sheeps {1} TotalSheeps {2}",
                                        myPlanet.PlanetID, myPlanet.NumShips, myPlanet.TotalSheeps));
        }
    }
Ejemplo n.º 6
0
 // The DoTurn function is where your code goes. The PlanetWars object
 // contains the state of the game, including information about all planets
 // and fleets that currently exist. Inside this function, you issue orders
 // using the pw.IssueOrder() function. For example, to send 10 ships from
 // planet 3 to planet 8, you would say pw.IssueOrder(3, 8, 10).
 //
 // There is already a basic strategy in place here. You can use it as a
 // starting point, or you can throw it out entirely and replace it with
 // your own. Check out the tutorials and articles on the contest website at
 // http://www.ai-contest.com/resources.
 public static void DoTurn(PlanetWars pw)
 {
     // (1) If we currently have a fleet in flight, just do nothing.
     if (pw.MyFleets().Count >= 1) {
     return;
     }
     // (2) Find my strongest planet.
     Planet source = null;
     double sourceScore = Double.MinValue;
     foreach (Planet p in pw.MyPlanets()) {
     double score = (double)p.NumShips();
     if (score > sourceScore) {
     sourceScore = score;
     source = p;
     }
     }
     // (3) Find the weakest enemy or neutral planet.
     Planet dest = null;
     double destScore = Double.MinValue;
     foreach (Planet p in pw.NotMyPlanets()) {
     double score = 1.0 / (1 + p.NumShips());
     if (score > destScore) {
     destScore = score;
     dest = p;
     }
     }
     // (4) Send half the ships from my strongest planet to the weakest
     // planet that I do not own.
     if (source != null && dest != null) {
     int numShips = source.NumShips() / 2;
     pw.IssueOrder(source, dest, numShips);
     }
 }
Ejemplo n.º 7
0
Archivo: MyBot.cs Proyecto: minskowl/MY
    private static Planet GetRichest(PlanetWars pw)
    {
        Planet source      = null;
        double sourceScore = Double.MinValue;

        foreach (Planet p in pw.MyPlanets())
        {
            double score = (double)p.TotalSheeps;
            if (score > sourceScore)
            {
                sourceScore = score;
                source      = p;
            }
        }
        return(source);
    }
Ejemplo n.º 8
0
    // Liste aller eigener Planeten erstellen, die Flotten senden koennen.
    // Fuer jeden Planeten eine Bewertung (Entfernung zum Zielplaneten) mitliefern.
    public static List<Planet> EvalSendPlanets(PlanetWars pw, Planet DestinationPlanet)
    {
        List<Planet> SendPlanets = new List<Planet>();

        foreach (Planet p in pw.MyPlanets())
        {
            if (p.NumShips() > 0)
            {
                double dist = distance(p, DestinationPlanet); // Entfernung zum Zielplaneten ermitteln

                Planet ThisPlanet = p;
                ThisPlanet.Score(dist);
                SendPlanets.Add(ThisPlanet);
            }
        }

        return SendPlanets;
    }
Ejemplo n.º 9
0
    // The DoTurn function is where your code goes. The PlanetWars object
    // contains the state of the game, including information about all planets
    // and fleets that currently exist. Inside this function, you issue orders
    // using the pw.IssueOrder() function. For example, to send 10 ships from
    // planet 3 to planet 8, you would say pw.IssueOrder(3, 8, 10).
    //
    // There is already a basic strategy in place here. You can use it as a
    // starting point, or you can throw it out entirely and replace it with
    // your own. Check out the tutorials and articles on the contest website at
    // http://www.ai-contest.com/resources.
    public static void DoTurn(PlanetWars pw)
    {
        // (1) If we currently have a fleet in flight, just do nothing.
        if (pw.MyFleets().Count >= 1)
        {
            return;
        }
        // (2) Find my strongest planet.
        Planet source      = null;
        double sourceScore = Double.MinValue;

        foreach (Planet p in pw.MyPlanets())
        {
            double score = (double)p.NumShips();
            if (score > sourceScore)
            {
                sourceScore = score;
                source      = p;
            }
        }
        // (3) Find the weakest enemy or neutral planet.
        Planet dest      = null;
        double destScore = Double.MinValue;

        foreach (Planet p in pw.NotMyPlanets())
        {
            double score = 1.0 / (1 + p.NumShips());
            if (score > destScore)
            {
                destScore = score;
                dest      = p;
            }
        }
        // (4) Send half the ships from my strongest planet to the weakest
        // planet that I do not own.
        if (source != null && dest != null)
        {
            int numShips = source.NumShips() / 2;
            pw.IssueOrder(source, dest, numShips);
        }
    }
Ejemplo n.º 10
0
    public static void DoTurn(PlanetWars pw)
    {
        if (CurrentTurn == 0 && pw.Distance(pw.MyPlanets().First().PlanetID, pw.EnemyPlanets().First().PlanetID) <= 8)
            IsKamikazi = true;

        if (IsKamikazi)
        {
            foreach (var planet in pw.MyPlanets())
            {
                var enemy = pw.EnemyPlanets().FirstOrDefault();
                int shipsHeaded = pw.Fleets().Where(f => f.DestinationPlanet == planet.PlanetID).Sum(f => f.NumShips);
                if (enemy != null)
                {
                    if (planet.NumShips - shipsHeaded - 1 > 0)
                        pw.IssueOrder(planet, enemy, planet.NumShips - shipsHeaded - 1);
                }
                else
                {
                    foreach (int dest in pw.EnemyFleets().Select(f => f.DestinationPlanet).Distinct())
                    {
                        if (dest == planet.PlanetID)
                            break;

                        int headedTo = pw.EnemyFleets().Where(f => f.DestinationPlanet == dest).Sum(f => f.NumShips);
                        int numToSend = ( (planet.NumShips - shipsHeaded) > headedTo) ? headedTo + 1 : (planet.NumShips - shipsHeaded);

                        if (numToSend > 0)
                            pw.IssueOrder(planet, pw.GetPlanet(dest), numToSend);
                    }
                }
            }
        }
        else
        {
            foreach (var planet in pw.MyPlanets())
            {
                int available = AvailableFleets(planet, pw);
                var enemy = pw.NotMyPlanets().Where(p => CanSend(planet, p, pw));
                enemy = enemy.OrderBy(p => GetScore(planet, p, pw));
                int skip = 0;

                while (available > 0)
                {
                    var bestEnemy = enemy.Skip(skip).FirstOrDefault();
                    skip++;

                    if (bestEnemy != null)
                    {
                        int numToSend = GetNumFleetsToSend(planet, bestEnemy, pw);
                        if (available > numToSend)
                        {

                            pw.IssueOrder(planet, bestEnemy, numToSend);
                            available = available - numToSend;
                        }
                    }
                    else
                    {
                        available = 0;
                    }
                }
            }
        }
    }
Ejemplo n.º 11
0
    public static void DoTurn(PlanetWars pw)
    {
        int     numFleets  = 1;
        Boolean attackMode = false;

        if (pw.NumShips(1) > pw.NumShips(2))
        {
            if (pw.Production(1) > pw.Production(2))
            {
                numFleets  = 1;
                attackMode = true;
            }
            else
            {
                numFleets = 3;
            }
        }
        else
        {
            if (pw.Production(1) > pw.Production(2))
            {
                numFleets = 1;
            }
            else
            {
                numFleets = 5;
            }
        }
        // (1) If we current have more tha numFleets fleets in flight, just do
        // nothing until at least one of the fleets arrives.
        if (pw.MyFleets().Count >= numFleets)
        {
            return;
        }
        // (2) Find my strongest planet.
        Planet source      = null;
        double sourceScore = Double.MinValue;

        foreach (Planet p in pw.MyPlanets())
        {
            double score = (double)p.NumShips() / (1 + p.GrowthRate());
            if (score > sourceScore)
            {
                sourceScore = score;
                source      = p;
            }
        }
        // (3) Find the weakest enemy or neutral planet.
        Planet        dest       = null;
        double        destScore  = Double.MinValue;
        List <Planet> candidates = pw.NotMyPlanets();

        if (attackMode)
        {
            candidates = pw.EnemyPlanets();
        }
        foreach (Planet p in candidates)
        {
            double score = (double)(1 + p.GrowthRate()) / p.NumShips();
            if (score > destScore)
            {
                destScore = score;
                dest      = p;
            }
        }
        // (4) Send half the ships from my strongest planet to the weakest
        // planet that I do not own.
        if (source != null && dest != null)
        {
            int numShips = source.NumShips() / 2;
            pw.IssueOrder(source, dest, numShips);
        }
    }
Ejemplo n.º 12
0
    public static List<Planet> MyPlanetsAll = null; // pw.MyPlanet() + Expansions

    public static void DoTurn(PlanetWars pw)
    {
        DateTime StartTime = DateTime.Now; // Startzeit festhalten, um herauszufinden, wie lange der Zug des Bots andauert

        //List<Fleet> ShadowFleets = pw.MyFleets(); // "ShadowFleets" sind alle unsere Flotten + die in dieser Runde von uns losgeschicken Flotten. (Letztere sind nicht teil von pw.MyFleets()!)

        turn++;
        //log("turn: " + turn.ToString());
        if (pw.Winner() != -1) return; // spiel ist vorbei, abbruch.

        // Start-Expanison ------------------------------------------------------------------------------------------------------------------
        // Wir benutzen knapsack01. Achtung: Diese Vorgehensweise beduetet nicht notwendiger Weise eine optimale Expansion!
        if (turn == 1)
        {
            Planet my_start = pw.MyPlanets()[0];
            Planet enemy_start = pw.EnemyPlanets()[0];

            // Schritt 1: Wie viele Schiffe kann ich schicken, ohne dass mein Hauptplanet eingenommen werden kann?
            int ships_available = Math.Min(my_start.NumShips(), my_start.GrowthRate() * ((int)distance(my_start, enemy_start)+1));

            // Schritt 2: Planet heraus suchen, die fuer eine Expansion grundsaetzlich geeignet sind
            List<Planet> candidates = new List<Planet>();
            foreach (Planet p in pw.NeutralPlanets())
            {
                if (Math.Ceiling(distance(p, my_start)) <= Math.Ceiling(distance(p, enemy_start)))
                    candidates.Add(p);
            }

            // Schritt 3: Suche die besten Planeten zur Expansion heraus
            Expansions = knapsack01(candidates, ships_available, my_start);

            // Schritt 4: Expansion starten
            foreach (Planet p in Expansions)
            {
                SendShips(pw, my_start, p, p.NumShips() + 1);
            }

            return;
        }

        int MyGain = 0; // Gesamtproduktionsrate aller (meiner) Planeten
        int OpGain = 0;
        int MyShipCount = pw.NumShips(1); // Gesamtzahl aller meiner Schfife (auf Planeten und unterwegs)
        int OpShipCount = pw.NumShips(2);
        int MyScore = 0; // Meine Bewertung
        bool AttackIsEnabled = true; // duerfen wir in dieser Runde angreifen?

        // Statistiken fuer beide Spieler erheben ------------------------------------------------------------------------------------------------------------------
        MyPlanetCount = 0; OpPlanetCount = 0;
        foreach (Planet p in pw.Planets())
        {
            if (p.Owner() == 1)
            {
                MyGain += p.GrowthRate();
                MyPlanetCount++;
            }
            if (p.Owner() == 2)
            {
                OpGain += p.GrowthRate();
                OpPlanetCount++;
            }
        }

        MyScore = (MyShipCount + MyGain) - (OpShipCount + OpGain);

        MyPlanetsAll = pw.MyPlanets(); // MyPlanetsAll := pw.MyPlanet() + Expansions
        foreach (Planet p in MyPlanetsAll) { // Planeten, auf die wi expandieren wollten, und die nun uns gehoeren, aus der Liste der Expansionsplaneten entfernen
            foreach (Planet ep in Expansions) {
                if (p.PlanetID() == ep.PlanetID())
                {
                    Expansions.Remove(ep);
                    break;
                }
            }
        }
        MyPlanetsAll.AddRange(Expansions);

        // Front-Planeten finden ------------------------------------------------------------------------------------------------------------------
        if (OpPlanetCount > 0 && MyPlanetCount > 0)
        {
            // Haupt-Planeten finden
            foreach (Planet p in MyPlanetsAll)
            {
                double minDist = Double.MaxValue;
                double dist = 0;
                double opDist = 0;
                Planet e = null;
                Planet q = null;

                // naehesten Planeten des Gegners finden: e
                foreach (Planet opp in pw.EnemyPlanets())
                {
                    dist = distance(p, opp);
                    if (dist < minDist)
                    {
                        minDist = dist;
                        e = opp;
                    }
                }
                opDist = minDist;

                // den eigenen Planeten finden, der e am naehsten ist: q
                if (MyPlanetsAll.Count > 1)
                {
                    minDist = Double.MaxValue;
                    foreach (Planet myp in MyPlanetsAll)
                    {
                        dist = distance(e, myp);
                        if ((dist < minDist) && (distance(p, myp) <= opDist))
                        {
                            minDist = dist;
                            q = myp;
                        }
                    }
                }
                else q = p;

                if (p == q)
                {
                    p.IsHead(true);
                    p.TargetPlanetID(e.PlanetID());
                }
                else
                {
                    p.IsHead(false);
                    p.TargetPlanetID(q.PlanetID());
                }
            }
        }

        // Verteidigung ------------------------------------------------------------------------------------------------------------------
        int maxturns = 0;
        foreach (Fleet f in pw.Fleets())
        {
            if (f.TurnsRemaining() > maxturns) maxturns = f.TurnsRemaining();
        }

        foreach (Planet p in MyPlanetsAll)
        {
            p.SimOwner(p.Owner()); p.SimShips(p.NumShips()); p.AvailShips(p.NumShips()); p.TimeOfFall(-1);
        }

        // Berechne, wie viele Schiffe jeder Planet schicken kann, ohne vom Gegner uebernommen zu werden.
        // Dabei wird auch erkannt, welche Planeten vom Gegner erobert werden, sofern sie keine Verstaerkung erhalten.
        for (int i = 1; i <= maxturns; i++)
        {
            foreach (Planet p in MyPlanetsAll)
            {
                if (p.SimOwner() != 0) p.SimShips(p.SimShips() + p.GrowthRate()); // Schiffproduktion berechnen

                foreach (Fleet f in pw.Fleets())
                {
                    if (f.DestinationPlanet() == p.PlanetID() && f.TurnsRemaining() == i)
                    {
                        // achtung: reihenfolge der folgenden if-abfragen ist relevant!
                        if (p.SimOwner() == f.Owner())
                        {
                            p.SimShips(p.SimShips() + f.NumShips()); // eigener Planet (aus Sicht der Flotte)
                            //if (p.SimOwner() == 2) p.SimOpShips(p.SimOpShips() + f.NumShips());
                        }
                        if (p.SimOwner() != f.Owner()) // neutraler/gegnerischer Planet (aus Sicht der Flotte)
                        {
                            p.SimShips(p.SimShips() - f.NumShips());
                            if (p.SimShips() < 0) p.SimOwner(f.Owner());
                            p.SimShips(Math.Abs(p.SimShips()));
                            if (p.SimOwner() == 2)
                            {
                                p.TimeOfFall(i); // speichern, wann der Planet vom Gegner erobert wurde (eigene Rueckeroberungen interessieren hier nicht)
                                p.SimOpShips(p.SimShips());
                                p.AvailShips(0); // Der Planet wurde zwischenzeitlich erobert. Moeglicherweise wird er spaeter zurueck erobert, aber trotzdem soll er in dieser Runde erst einmal keine Schfife schicken. Tendenziell kann dadurch die Zeit, bis der Planet zurueckerobert wird, sinken, was mehr Produktion fuer uns bedeutet.
                            }
                            else p.TimeOfFall(-1);
                        }
                    }
                }

                if (p.Owner() == 1) p.AvailShips(Math.Min(p.AvailShips(), p.SimShips()));
            }
        }

        // Listen erstellen der Planeten, die erobert werden bzw. Verstaerkung schicken koennen
        List<Planet> defplanets = new List<Planet>();
        List<Planet> fallenplanets = new List<Planet>();
        foreach (Planet p in MyPlanetsAll)
        {
            if (p.TimeOfFall() != -1) // Planeten, die ohne zusaetzliche Verstaerkung dauerhaft erobert wuerden
            {
                fallenplanets.Add(p);
                fallenplanets[fallenplanets.Count - 1].Score(p.GrowthRate());
                p.AvailShips(0); // der Planet hat keine Schiffe, die er als Verstaerkung schicken kann, ohne erobert zu werden, da er (voraussichtlich) so oder so erobert wird.
            }
            if (p.TimeOfFall() == -1 && p.AvailShips() > 0 && p.Owner() == 1) defplanets.Add(p); // Planeten, die ohne zusaetliche Verstaerkung nicht erobert werden (oder aber wieder zurueck erobert werden) und evtl. Schiffe schicken koennen
        }
        fallenplanets.Sort(comparePlanetListDesc); // nach Prioritaet sortieren

        // Zu den bedrohten Planeten Verstaerkung schicken
        foreach (Planet fallenplanet in fallenplanets)
        {
            foreach (Planet p in defplanets) // Fuer alle Planeten, die Verstaerkung schicken koennen/sollen...
            {
                p.Score((int)Math.Ceiling(distance(fallenplanet, p))); // ...Entfernung zum Zielplaneten ermitteln
            }
            defplanets.Sort(comparePlanetListAsc); // Wir wollen zuerst von nahe gelegenen Planeten Unterstuetzung senden.

            int sended = 0; // Gibt an, wie viele Schiffe andere Planeten, die naeher am Zielplaneten sind, schon gesendet haben
            int iMustSend = 0; // Anzahl Schiffe, die der Planet senden muss (ob er so viele Schiffe hat, wird hier nicht beruecksichtigt)

            foreach (Planet p in defplanets)
            {
                if (p.AvailShips() == 0) continue; // Planeten, die keine Schiffe schicken koennen, ignorieren
                if (p.Score() <= fallenplanet.TimeOfFall()) // p.score()=Entfernung=Zeit, bis Flotten den bedrohten Planet erreichen koennen
                {
                    iMustSend = fallenplanet.SimOpShips() + 1 - sended; // Ich befinde mich nah genug beim Zielplaneten, um eingreifen zu koennen, bevor er erobert wird. SimOpShips() gibt an, wie viele Schiffe der Planet direkt nach der Eroberung hat. Wenn der Planet so viele Schiffe mehr schickt, wird die Eroberung verhindert. [Es kann sein, dass der Planet zu viele Schiffe schickt, wenn z.B. der Planet vor der endgueltigen Eroberung schon mal  kurz erobert wurde und wir das verhinderen, denn dann werden ja mehr Schfife fuer uns produziert.] 
                }
                else
                {
                    iMustSend = fallenplanet.SimOpShips() + 1 + (int)(p.Score() - fallenplanet.TimeOfFall()) * fallenplanet.GrowthRate() - sended; // wie oben, aber jetzt beruecksichtigt der Planet zusaetlich, dass seine Flotte er erst nach der Eroberung eintrifft und der Gegner dann schon zusaetzliche Schiffe produziert hat. Es wird aber nicht beruecksichtigt, dass der Gegner ggf. Verstaerkung zu dem Planeten schickt.
                }

                if (p.AvailShips() >= iMustSend)
                {
                    p.AvailShips(p.AvailShips() - iMustSend);
                    SendShips(pw, p, fallenplanet, iMustSend);
                    break; // Es wurden (voraussichtlich) genug Schiffe gesendet, um den Planeten zurueck zu erobern. Bearbeitung dies Planeten abbrechen.
                }
                else
                {
                    sended += p.AvailShips();
                    SendShips(pw, p, fallenplanet, p.AvailShips());
                    p.AvailShips(0);
                }
            }
        }

        

        //// Expansion ------------------------------------------------------------------------------------------------------------------
        if (MyPlanetCount > 0 && OpPlanetCount > 0 && (MyScore < 150 && (MyGain - 5 < OpGain)))
        //if (MyPlanetCount > 0 && OpPlanetCount > 0 && (MyScore < 250 && (MyGain - 20 < OpGain)))
        {
            // Suche einen geeigneten Planeten zur Expansion:
            Planet ExpansionPlanet = null;
            Planet MyNearestPlanet = null;
            double maxScore = Double.MaxValue;
            foreach (Planet p in pw.NeutralPlanets())
            {
                if (p.GrowthRate() == 0) continue; // planeten ohne produktion interessieren uns nicht

                // pruefen, ob wir noch nicht zu diesem Planeten expandieren
                bool gofornext = false;
                foreach (Planet ExP in Expansions)
                {
                    if (p.PlanetID() == ExP.PlanetID())
                    {
                        p.Score(-1);
                        gofornext = true;
                        break;
                    }
                }
                if (gofornext == true) continue;

                p.Score(p.NumShips() / p.GrowthRate()); // p.GrowthRate() == 0 kann hier nicht auftreten

                // Der Planet sollte/muss in unserem Gebiet liegen oder zumindest fuer uns guenstiger als fuer den Gegner
                int MyEmpireDistance = int.MaxValue;
                int OpEmpireDistance = int.MaxValue;
                Planet SaveMyNearestPlanet = null;
                foreach (Planet MyP in pw.MyPlanets())
                {
                    int mindDist = (int)Math.Ceiling(distance(p, MyP));
                    if (mindDist < MyEmpireDistance)
                    {
                        MyEmpireDistance = mindDist;
                        SaveMyNearestPlanet = MyP;
                    }
                }
                foreach (Planet OpP in pw.EnemyPlanets())
                {
                    int mindDist = (int)Math.Ceiling(distance(p, OpP));
                    if (mindDist < OpEmpireDistance) OpEmpireDistance = mindDist;
                }

                // Entfernungen mit in die Bewertung einbeziehen
                //if (OpEmpireDistance < MyEmpireDistance) p.Score(p.Score() + 100 + (MyEmpireDistance - OpEmpireDistance)); // Wir wollen Planeten, die naeher zum Gegner sind also zu uns, nur im Notfall. Daher erhalten sie eine dratsich schlechtere Wertung.
                if (OpEmpireDistance < MyEmpireDistance) continue; // Wir wollen Planeten, die naeher zum Gegner sind also zu uns, nicht einnehmen.
                p.Score(p.Score() + MyEmpireDistance);

                if (p.Score() < maxScore)
                {
                    maxScore = p.Score();
                    ExpansionPlanet = p;
                    MyNearestPlanet = SaveMyNearestPlanet;
                }
            }

            log(" "); log("turn: " + turn);
            log("MyGain: " + MyGain + ", OpGain: " + OpGain + ", Score: " + MyScore);
            //if (ExpansionPlanet == null) log("Kein Expansionplanet gefunden."); else log("Expansionplanet gefunden!!!  ID: " + ExpansionPlanet.PlanetID() + " - Score: " + ExpansionPlanet.Score());

            if (ExpansionPlanet != null) // kein fuer Expansion geeigneter Planet gefunden: Abbruch
            {
                // Berechne via AvailShips, ob wir genuegend Schfife haben, um die Eroberung des Planeten in dieser Runde einzuleiten.
                int haveShips = 0;
                foreach (Planet p in pw.MyPlanets())
                {
                    haveShips += p.AvailShips();
                    if (haveShips >= ExpansionPlanet.NumShips() + 1) break;
                }

                bool Expand = true;
                if (haveShips>0) { // Wenn wir genug Schiffe fuer die Expansion haben:
                    int amortizeTime = ExpansionPlanet.NumShips() / ExpansionPlanet.GrowthRate() + (int)Math.Ceiling(distance(MyNearestPlanet, ExpansionPlanet));
                    int needed = ExpansionPlanet.NumShips() + 1;
                    log("amortizeTime: " + amortizeTime + ", MyNearestPlanet: " + MyNearestPlanet.PlanetID() + ", haveShips: " + haveShips + ", neededShips: " + needed);

                    foreach (Planet HeadPlanet in MyPlanetsAll) // Angriff auf jeden HeadPlaneten simulieren; auch Expansionsplaneten beruecksichtigen
                    {
                        if (HeadPlanet.IsHead() == true)
                        {
                            int SimShips = 0;
                            int IsTarget = 0;
                            List<Fleet> ESimFleets = new List<Fleet>(); // Simulierte Flotten hier speichern
                            foreach (Planet p in pw.Planets()) // Alle nicht-neutralen Planeten greifen an (bzw. verstaerken)
                            {
                                if (p.Owner() != 0)
                                {
                                    for (int i = 0; i <= amortizeTime; i++)
                                    {
                                        SimShips = p.GrowthRate(); // Die Schiff-Produktion beruecksichtigen
                                        if (i == 0 && p.PlanetID() != HeadPlanet.PlanetID()) SimShips = p.NumShips(); // Alle Schiffe losschicken
                                        if (p.PlanetID() == HeadPlanet.PlanetID()) IsTarget = 1; else IsTarget=0; // Flotte markieren: Diese Flotte wurde vom Zielplaneten losgeschickt (sie fliegt also eigentlich gar nicht. Sie wird nur losgeschickt, damit die Produktion des Ziel-Planeten beruecksichtigt wird)
                                        if (SimShips > 0) // wir wollen keine 0-Schiff-Flotten losschicken
                                        {
                                            Fleet ThisFleet = new Fleet(p.Owner(), SimShips, IsTarget, 0, -1, (int)Math.Ceiling(distance(p, HeadPlanet)));
                                            ESimFleets.Add(ThisFleet); // Flotte der Liste hinzufuegen
                                        }
                                    }
                                }
                            }

                            ESimFleets.Sort(compareFleetListAsc); // Flotten nach Ankunftszeit sortieren

                            SimShips = HeadPlanet.NumShips() - needed; // Der Zielplanet verfuegt ueber die auf ihm stationierten Schiffe. Die Schiffe fuer die Expansion werden abgezogen.
                            int SimOwner = 1; // Besitzer des Zielplaneten
                            foreach (Fleet ESimFleet in ESimFleets) // Eintreffen der Flotten simulieren. Da diese nach Entfernung sortiert sind, muss die exakte Akunftszeit hier nicht mehr beruecksichtigt werden.
                            {
                                if (ESimFleet.Owner() == SimOwner || ESimFleet.SourcePlanet() == 1) // Wenn der Zielplnaet zum Besitzer der Flotte gehoert (oder die Flotte als zum Zielplanet gehoerend markiert wurde):
                                {
                                    SimShips += ESimFleet.NumShips(); // Schiffe addieren
                                }
                                else
                                {
                                    SimShips -= ESimFleet.NumShips(); // Schiffe abziehen
                                    if (SimShips < 0) // Wenn wir < 0 Schiffe haben...
                                    {
                                        SimOwner = ESimFleet.Owner(); // wechselt der Besitzer des Planeten.
                                        SimShips = Math.Abs(SimShips); 
                                    }
                                }
                            }

                            log("Ergebnis der Simulation: " + SimShips + " (" + SimOwner + ")");
                            if (SimOwner != 1) // Wenn wir nicht der Besitzer des Planeten sind...
                            {
                                Expand = false; // Expansion abbrechen, da keine sichere Expansion moeglich ist. 
                                break; // Schleife ueber die Head-Planeten verlassen
                            }
                        }
                    }

                    if ((haveShips >= needed) && (Expand == true))
                    {
                        List<Planet> SourcePlanets = EvalSendPlanets(pw, ExpansionPlanet); // Liste aller infrage kommender eigener Planeten, die Flotten schicken koennen, erstellen. Fuer jeden Planeten eine Bewertung mitliefern.
                        SourcePlanets.Sort(comparePlanetListDesc); // Liste sortieren (nach Bewertung)

                        foreach (Planet SourcePlanet in SourcePlanets) // Alle moeglichen eigenen Planeten durchlaufen, die zum aktuellen Zielplaneten Flotten schicken koennen
                        {
                            int ships = SourcePlanet.AvailShips();
                            if (ships == 0) continue; // wir wollen ja keine 0-Schiff-Flotten losschicken
                            if (ships >= needed) // Wenn der Planet mehr Schiffe hat als fuer die Expansion benoetigt werden:
                            {
                                SourcePlanet.AvailShips(SourcePlanet.AvailShips() - needed);
                                SendShips(pw, SourcePlanet, ExpansionPlanet, needed);
                                break; // Abbruch, es wurden genug Schiffe losgeschickt
                            }
                            else
                            {
                                SourcePlanet.AvailShips(0);
                                SendShips(pw, SourcePlanet, ExpansionPlanet, ships);
                                needed -= ships;
                            }
                        }

                        Expansions.Add(ExpansionPlanet); // Planet zu der Liste der Expansionsplaneten hinzufuegen
                    }
                    else
                    {
                        if (haveShips < needed && Expand == true) AttackIsEnabled = false; // keine Angriffe durchfuehren, sondern warten, dass genug Schiffe produziert worden
                    }
                }
            }
        }
        
        // Nachschublinien ------------------------------------------------------------------------------------------------------------------
        if (OpPlanetCount > 0 && MyPlanetsAll.Count > 1) // Nachschub schicken, wenn der Gegner Planeten besitzt und wir mehr als 1 Planeten besitzen:
        {
            foreach (Planet p in pw.MyPlanets())
            {
                //if (p.AvailShips() > 0 && p.IsHead() == false && p.Owner() == 1)
                if (p.AvailShips() > 0 && p.IsHead() == false) // Nachschub schicken, wenn dafuer Schiffe verfuegbar sind und wir kein HEad-Planet sind.
                {
                    SendShips(pw, p, pw.GetPlanet(p.TargetPlanetID()), p.AvailShips());
                }
            }
        }

        // Angriff ------------------------------------------------------------------------------------------------------------------
        //log("Attack? : " + AttackIsEnabled + ", AvaiLShips(2): " + pw.GetPlanet(2).AvailShips() + ", OpPCount: " + OpPlanetCount + ", MyPCount: " + MyPlanetCount);
        if (OpPlanetCount > 0 && MyPlanetCount > 0 && AttackIsEnabled == true)
        {
            foreach (Planet p in pw.MyPlanets())
            {
                if (p.AvailShips() > 0 && p.IsHead() == true) // Angreifen, wenn wir Schiffe dazu haben und wir ein Head-Planet sind:
                {
                    int ships_available = p.AvailShips() + p.GrowthRate() * ((int)distance(p, pw.GetPlanet(p.TargetPlanetID())));
                    if (pw.GetPlanet(p.TargetPlanetID()).NumShips() <= ships_available || MyScore > 200)
                    {
                        if (MyScore > 250) // Wenn wir ueber x Schiffe mehr haben als der Gegner, greifen wir aggressiv an. 
                        {
                            ships_available = p.AvailShips();
                        }
                        else
                        {
                            ships_available = Math.Min(ships_available - pw.GetPlanet(p.TargetPlanetID()).NumShips(), p.AvailShips());
                        }
                        if (ships_available > 0) SendShips(pw, p, pw.GetPlanet(p.TargetPlanetID()), ships_available);
                    }
                }
            }
        }

        log("ExecutionTime: " + (DateTime.Now - StartTime).TotalMilliseconds + " Milliseconds (" + (DateTime.Now - StartTime).TotalSeconds + " Seconds)"); // Ausfuehrungszeit loggen.
    }
Ejemplo n.º 13
0
    public static void DoTurn(PlanetWars pw)
    {
        /*
         * basically I need to find out if I need to do something to maintain my advantage, by either attacking, reinforcing, or waiting
         */
        //double x = 0, y = 0;
        List<Planet> blue = pw.MyPlanets();
        List<Planet> opfor = pw.EnemyPlanets();
        List<Planet> targets = pw.NotMyPlanets();

        int opfor_army = 0;
        int opfor_production = 0;
        int blue_army = 0;
        int blue_production = 0;
        foreach (Planet p in opfor)
        {
            opfor_army += p.NumShips();
            opfor_production += p.GrowthRate();
        }
        foreach (Fleet f in pw.EnemyFleets())
        {
            opfor_army += f.NumShips();
        }
        foreach (Planet p in blue)
        {
            blue_army += p.NumShips();
            blue_production += p.GrowthRate();
        }
        foreach (Fleet f in pw.MyFleets())
        {
            blue_army += f.NumShips();
        }
        if (blue_army > opfor_army && blue_production > opfor_production)
        {
            // I win, attack
            foreach (Planet planet in blue)
            {
                targetSort = planet;
                opfor.Sort(SortTarget);
                foreach (Planet target in opfor)
                {
                    int shipsToSend = (int)Math.Floor(planet.NumShips()*0.5);
                    pw.IssueOrder(planet, target, shipsToSend);
                    planet.NumShips(planet.NumShips() - shipsToSend);
                }

            }
        }
        targets.Sort(ComparePlanetValue);
        foreach (Planet planet in blue)
        {
            foreach (Planet target in targets)
            {
                int turns = pw.Distance(planet.PlanetID(), target.PlanetID());
                int shipsToSend = target.NumShips() + (turns * target.GrowthRate()) + 1;
                int shipsSent = 0;
                foreach (Fleet fleet in pw.MyFleets())
                {
                    if (fleet.SourcePlanet() == planet.PlanetID())
                    {
                        shipsSent += fleet.NumShips();
                    }
                }
                if (planet.NumShips() > shipsToSend && shipsSent <= shipsToSend)
                {
                    int order = shipsToSend - shipsSent;
                    pw.IssueOrder(planet, target, order);
                    planet.NumShips(planet.NumShips() - order);
                }
            }

        }
        for (int i = 0; i < 3; i++)
        {
            Planet target = targets[i];
            targetSort = target;
            if (blue.Count > 1)
            {
            //    blue.Sort(SortTarget);
            }

            //pw.IssueOrder(pw.GetPlanet(blue[0].PlanetID()), target, pw.GetPlanet(blue[0].PlanetID()).NumShips() - 5);
            /*for (int j = 0; j < blue.Count; j++)
            {
                pw.IssueOrder(blue[j], target, 1);
                //blue[j].NumShips(0);
            }*/

        }
        /*foreach (Planet planet in blue)
        {
            if (planet.Owner() == 1)
            {
                foreach (Planet target in targets)
                {
                    int shipsExtra = 0;
                    int shipsSent = 0;
                    int shipsNeeded = 0;
                    shipsNeeded = target.NumShips() + 1;
                    int takeover = shipsExtra + shipsNeeded;
                    if (target.Owner() == 2)
                    {
                        int turns = pw.Distance(planet.PlanetID(), target.PlanetID());
                        takeover += turns * target.GrowthRate();
                    }
                    if (shipsSent < takeover)
                    {
                        if (planet.NumShips() <= shipsNeeded && planet.NumShips() > planet.GrowthRate()*5)
                        {
                          //  int shipsToSend = planet.NumShips();
                          //  shipsSent += shipsToSend;
                         //   pw.IssueOrder(planet, target, shipsToSend);
                         //   planet.NumShips(planet.NumShips() - shipsToSend);
                        }
                        else if (planet.NumShips() > takeover)
                        {
                            int shipsToSend = takeover;
                            shipsSent += shipsToSend;
                            pw.IssueOrder(planet, target, shipsToSend);
                            planet.NumShips(planet.NumShips() - shipsToSend);
                        }
                    }
                }
            }

        }*/

        /*

        else
        {
            if (closest != null)
            {
                int shipCount = 0;
                foreach (Planet p in blue)
                {
                    shipCount += p.NumShips();
                }
                foreach (Planet p in blue)
                {
                    if (shipCount > closest.NumShips())
                        pw.IssueOrder(p, closest, (int)Math.Floor(p.NumShips() * 0.5));
                }
            }
            if (next_closest != null)
            {
                foreach (Planet p in pw.MyPlanets())
                {
                    if (p.NumShips() > next_closest.NumShips())
                        pw.IssueOrder(p, next_closest, (int)Math.Floor(p.NumShips() * 0.5));
                }
            }
        }*/
    }