Example #1
0
        public static Dictionary <Design, long> FillCarriers(StaticsDB statics, PlayerProcessor playerProc, Dictionary <Design, long> shipGroups)
        {
            var designStats = playerProc.DesignStats;
            var uncarried   = new PriorityQueue <KeyValuePair <Design, long> >();
            var carriedTows = new Stack <KeyValuePair <Design, long> >();
            var carryOrder  = shipGroups.Keys.
                              OrderBy(x => statics.ShipFormulas.GalaxySpeed.Evaluate(
                                          new Var(SpeedKey, designStats[x].GalaxySpeed).
                                          And(SizeKey, designStats[x].Size).
                                          And(TowKey, designStats[x].TowCapacity).
                                          And(LaneKey, false).Get
                                          )).
                              ThenByDescending(x => designStats[x].Size);

            foreach (var design in carryOrder)
            {
                var carryCapacity = designStats[design].CarryCapacity * shipGroups[design];
                var tooBig        = new List <KeyValuePair <Design, long> >();

                while (carryCapacity > 0 && uncarried.Count > 0)
                {
                    var priority  = uncarried.PeekPriority();
                    var sameSpeed = new PriorityQueue <KeyValuePair <Design, long> >();
                    while (uncarried.Count > 0 && uncarried.PeekPriority() == priority)
                    {
                        var group = uncarried.Dequeue();
                        sameSpeed.Enqueue(group, designStats[group.Key].Size);
                    }

                    while (carryCapacity > 0 && sameSpeed.Count > 0)
                    {
                        var group            = sameSpeed.Dequeue();
                        var maxTransportable = (long)Math.Floor(carryCapacity / designStats[group.Key].Size);
                        if (designStats[group.Key].Size > designStats[design].CarryCapacity)
                        {
                            maxTransportable = 0;
                        }

                        var transported   = Math.Min(maxTransportable, group.Value);
                        var untransported = group.Value - transported;

                        carryCapacity -= transported * designStats[group.Key].Size;

                        if (untransported > 0)
                        {
                            tooBig.Add(new KeyValuePair <Design, long>(group.Key, untransported));
                        }
                        if (designStats[group.Key].TowCapacity > 0 && transported > 0)
                        {
                            carriedTows.Push(new KeyValuePair <Design, long>(group.Key, transported));
                        }
                    }

                    tooBig.AddRange(sameSpeed);
                }

                uncarried.Enqueue(new KeyValuePair <Design, long>(design, shipGroups[design]), designStats[design].GalaxySpeed);
                foreach (var untransported in tooBig)
                {
                    uncarried.Enqueue(untransported, designStats[untransported.Key].GalaxySpeed);
                }
            }

            var result    = uncarried.ToDictionary(x => x.Key, x => x.Value);
            var nonIsSize = uncarried.Where(x => x.Key.IsDrive == null).Sum(x => designStats[x.Key].Size * x.Value);

            nonIsSize -= uncarried.Where(x => x.Key.IsDrive != null).Sum(x => designStats[x.Key].TowCapacity * x.Value);

            while (nonIsSize > 0 && carriedTows.Count > 0)
            {
                var towGroup = carriedTows.Pop();
                var usedTows = (long)Math.Min(Math.Floor(nonIsSize / designStats[towGroup.Key].TowCapacity), towGroup.Value);

                if (usedTows <= 0)
                {
                    continue;
                }
                if (!result.ContainsKey(towGroup.Key))
                {
                    result.Add(towGroup.Key, 0);
                }

                result[towGroup.Key] += usedTows;
                nonIsSize            -= usedTows * designStats[towGroup.Key].TowCapacity;
            }

            return(result);
        }
        private void makeDesign(StaticsDB statics, StatesDB states, string id, PredefinedDesign predefDesign, PlayerProcessor playerProc)
        {
            var design = states.Designs.FirstOrDefault(x => x.IdCode == id);

            if (design == null)
            {
                var techLevels = new Var().
                                 Init(statics.DevelopmentTopics.Select(x => x.IdCode), false).
                                 Init(statics.ResearchTopics.Select(x => x.IdCode), false).Get;

                var hull     = statics.Hulls[predefDesign.HullCode].MakeHull(techLevels);
                var specials = predefDesign.SpecialEquipment.OrderBy(x => x.Key).Select(
                    x => statics.SpecialEquipment[x.Key].MakeBest(techLevels, x.Value)
                    ).ToList();

                var armor     = AComponentType.MakeBest(statics.Armors.Values, techLevels);                                          //TODO(0.5) get id from template
                var reactor   = ReactorType.MakeBest(techLevels, hull, specials, statics);                                           //TODO(0.5) get id from template
                var isDrive   = predefDesign.HasIsDrive ? IsDriveType.MakeBest(techLevels, hull, reactor, specials, statics) : null; //TODO(0.5) get id from template
                var sensor    = AComponentType.MakeBest(statics.Sensors.Values, techLevels);                                         //TODO(0.5) get id from template
                var shield    = predefDesign.ShieldCode != null ? statics.Shields[predefDesign.ShieldCode].MakeBest(techLevels) : null;
                var equipment = predefDesign.MissionEquipment.Select(
                    x => statics.MissionEquipment[x.Key].MakeBest(techLevels, x.Value)
                    ).ToList();

                var thruster = AComponentType.MakeBest(statics.Thrusters.Values, techLevels);                 //TODO(0.5) get id from template

                design = new Design(
                    id, playerProc.Player, false, true, predefDesign.Name, predefDesign.HullImageIndex,
                    armor, hull, isDrive, reactor, sensor, shield, equipment, specials, thruster
                    );

                design.CalcHash(statics);
                states.Designs.Add(design);
            }

            playerProc.Analyze(design, statics);
        }
        private void makeDesign(StaticsDB statics, StatesDB states, string id, PredefinedDesign designData, PlayerProcessor playerProc)
        {
            var design = states.Designs.FirstOrDefault(x => x.IdCode == id);

            if (design == null)
            {
                var armor    = new Component <ArmorType>(statics.Armors[designData.Armor.IdCode], designData.Armor.Level);
                var hull     = new Component <HullType>(statics.Hulls[designData.Hull.IdCode], designData.Hull.Level);
                var reactor  = new Component <ReactorType>(statics.Reactors[designData.Reactor.IdCode], designData.Reactor.Level);
                var sensor   = new Component <SensorType>(statics.Sensors[designData.Sensors.IdCode], designData.Sensors.Level);
                var thruster = new Component <ThrusterType>(statics.Thrusters[designData.Thrusters.IdCode], designData.Thrusters.Level);

                var isDrive   = designData.IsDrive != null ? new Component <IsDriveType>(statics.IsDrives[designData.IsDrive.IdCode], designData.IsDrive.Level) : null;
                var shield    = designData.Shield != null ? new Component <ShieldType>(statics.Shields[designData.Shield.IdCode], designData.Shield.Level) : null;
                var equipment = designData.MissionEquipment.Select(
                    x => new Component <MissionEquipmentType>(statics.MissionEquipment[x.IdCode], x.Level, x.Amount)
                    ).ToList();
                var specials = designData.SpecialEquipment.Select(
                    x => new Component <SpecialEquipmentType>(statics.SpecialEquipment[x.IdCode], x.Level, x.Amount)
                    ).ToList();

                design = new Design(
                    id, playerProc.Player, false, designData.Name, designData.HullImageIndex, designData.UsesFuel,
                    armor, hull, isDrive, reactor, sensor, thruster, shield, equipment, specials
                    );

                design.CalcHash(statics);
                states.Designs.Add(design);
            }

            playerProc.Analyze(design, statics);
        }