Пример #1
0
        // Returns the number of stars owned by each player.
        public List <int> AdvanceTurn(List <Game.TurnOutput> instructions)
        {
            // First create flights as instructed by the AIs.
            var alreadyIssuedFlights = new HashSet <(int from, int to)> ();

            for (int i = 0; i < 2 * NUM_COMMANDERS_PER_PLAYER; i++)
            {
                var inst = instructions[i];
                foreach (var fly in inst.Fly)
                {
                    if (fly.FromStarId < 0 || fly.FromStarId >= NUM_STARS || fly.ToStarId < 0 || fly.ToStarId >= NUM_STARS)
                    {
                        Trace.TraceInformation($"[{i}] Invalid flight, stars out of bound: {fly}");
                        continue;
                    }
                    if (fly.FromStarId == fly.ToStarId)
                    {
                        Trace.TraceInformation($"[{i}] Invalid flight, flying to same star: {fly}");
                        continue;
                    }
                    if (stars[fly.FromStarId].Data.Owner != i)
                    {
                        Trace.TraceInformation($"[{i}] Invalid flight, source star not owned: {fly}");
                        continue;
                    }
                    if (fly.ShipCount <= 0 || stars[fly.FromStarId].Data.ShipCount < fly.ShipCount)
                    {
                        Trace.TraceInformation($"[{i}] Invalid flight, invalid ship count: {fly}");
                        continue;
                    }
                    if (CalculateDistanceCeiling(fly.FromStarId, fly.ToStarId) > FLIGHT_RANGE)
                    {
                        Trace.TraceInformation($"[{i}] Invalid flight, star too far: {fly}, {stars[fly.FromStarId].Position}, {stars[fly.ToStarId].Position}");
                        continue;
                    }
                    if (stars[fly.FromStarId].PendingOutgoingFlights >= MAX_OUTGOING_FLIGHTS_IN_FLIGHT)
                    {
                        Trace.TraceInformation($"[{i}] Invalid flight, too many outgoing flights: {fly}");
                        continue;
                    }
                    if (alreadyIssuedFlights.Contains((fly.FromStarId, fly.ToStarId)))
                    {
                        Trace.TraceInformation($"[{i}] Invalid flight, duplicate flight in same turn: {fly}");
                        continue;
                    }
                    alreadyIssuedFlights.Add((fly.FromStarId, fly.ToStarId));
                    var flight = new Game.Flight {
                        FromStarId     = fly.FromStarId,
                        ToStarId       = fly.ToStarId,
                        Owner          = i,
                        ShipCount      = fly.ShipCount,
                        TurnsToArrival = (CalculateDistanceCeiling(fly.FromStarId, fly.ToStarId) + TRAVEL_SPEED - 1) / TRAVEL_SPEED
                    };
                    AddFlight(flight);
                }
            }

            // Now advance 1 turn, granting production of new ships, and resolving arrivals.
            foreach (var star in stars)
            {
                if (star.Data.Owner != -1)
                {
                    star.Data.TurnsToNextProduction--;
                    if (star.Data.TurnsToNextProduction == 0)
                    {
                        star.Data.TurnsToNextProduction = TURNS_PER_PRODUCTION;
                        star.Data.ShipCount            += star.Data.Richness;
                    }
                }
            }

            var arrivingFlights = new List <List <Game.Flight> >();

            for (int i = 0; i < NUM_STARS; i++)
            {
                arrivingFlights.Add(new List <Game.Flight>());
            }

            // Erase-remove idiom.
            int j = 0;

            for (int i = 0; i < flights.Count; i++)
            {
                var flight = flights[i];
                flight.TurnsToArrival -= 1;
                if (flight.TurnsToArrival > 0)
                {
                    flights[j] = flights[i];
                    j++;
                }
                else
                {
                    arrivingFlights[flight.ToStarId].Add(flight);
                }
            }
            flights.RemoveRange(j, flights.Count - j);

            for (int i = 0; i < NUM_STARS; i++)
            {
                if (arrivingFlights[i].Count > 0)
                {
                    ResolveArrivingFlights(i, arrivingFlights[i]);
                }
            }

            record.Turns.Add(GetTurnInputForRecordKeeping());

            List <int> numStarsOwned = new List <int>()
            {
                0, 0
            };

            foreach (var star in stars)
            {
                if (star.Data.Owner != -1)
                {
                    numStarsOwned[commanders[star.Data.Owner].Affiliation]++;
                }
            }
            return(numStarsOwned);
        }
Пример #2
0
 private void AddFlight(Game.Flight flight)
 {
     stars[flight.FromStarId].PendingOutgoingFlights++;
     stars[flight.FromStarId].Data.ShipCount -= flight.ShipCount;
     flights.Add(flight);
 }