// 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); }
private void AddFlight(Game.Flight flight) { stars[flight.FromStarId].PendingOutgoingFlights++; stars[flight.FromStarId].Data.ShipCount -= flight.ShipCount; flights.Add(flight); }