public double ComputeErrorAgainstSeed(Utilities.LoggingCallback logger = null)
        {
            var error = 0.0;
            {
                var err = BlockSetInfo.TotalRawResources;
                logger?.Invoke("Raw resources {0:e}.  Err {1:e}", BlockSetInfo.TotalRawResources, err);
                error += err;
            }
            // Block counts
            {
                var countCopy = new Dictionary <SupportedBlockTypes, int>(SupportedBlockTypesEquality.Instance);
                foreach (var kv in Seed.BlockCountRequirements)
                {
                    countCopy[kv.Key] = 0;
                }
                foreach (var kv in BlockSetInfo.BlockCountByType)
                {
                    var def = MyDefinitionManager.Static.GetCubeBlockDefinition(kv.Key);
                    foreach (var kt in Seed.BlockCountRequirements)
                    {
                        if (kt.Key.IsOfType(def))
                        {
                            countCopy.AddValue(kt.Key, kv.Value);
                        }
                    }
                }
                foreach (var kv in countCopy)
                {
                    var target = Seed.BlockCountRequirement(kv.Key);
                    var err    = ErrorFunction(target.Count, kv.Value, 1e5, 0.1) * target.Multiplier;
                    logger?.Invoke("Block {0} count current {1:e} vs {2:e}. Err {3:e}", kv.Key, kv.Value, target.Count, err);
                    error += err;
                }
            }

            var powerReq = new ProceduralConstructionSeed.TradeRequirements(0, 0);

            foreach (var kv in Seed.ProductionStorage)
            {
                var id  = kv.Key;
                var req = kv.Value;
                if (id == MyResourceDistributorComponent.ElectricityId)
                {
                    powerReq = req;
                    continue;
                }
                if (id.TypeId == typeof(MyObjectBuilder_GasProperties))
                {
                    var storageCurrent = BlockSetInfo.TotalGasStorage(id);
                    var ce             = ErrorFunction(req.Storage, storageCurrent, 10, 1e-5) * req.StorageErrorMultiplier;
                    logger?.Invoke("Gas {0} storage current {1:e} vs {2:e}. Err {3:e}", id.SubtypeName, storageCurrent, req.Storage, ce);
                    error += ce;
                }
                var throughputCurrent = BlockSetInfo.TotalProduction(id);
                var te = ErrorFunction(req.Throughput, throughputCurrent, 1, 1e-6) * req.ThroughputErrorMultiplier;
                logger?.Invoke("{0} throughput current {1:e} vs {2:e}.  Store {3:e}. Err {4:e}", id, throughputCurrent, req.Throughput, req.Storage, te);
                error += te;
            }
            error /= Seed.LocalStorage.Count();

            // inventory:
            var errInventory = ErrorFunction(Seed.StorageVolume, BlockSetInfo.TotalInventoryCapacity, 1e3, 1e-3);

            logger?.Invoke("Inventory capacity current {0:e} vs {1:e}.  Err {2:e}", BlockSetInfo.TotalInventoryCapacity, Seed.StorageVolume, errInventory);
            error += errInventory;

            // power:
            // throughput is extra power available.  Total power consumption is (consumption - production).
            var errPowerThroughput = ErrorFunction(powerReq.Throughput, -BlockSetInfo.TotalPowerNetConsumption, 1e9, 0) * powerReq.ThroughputErrorMultiplier;
            var errPowerStorage    = ErrorFunction(powerReq.Storage, BlockSetInfo.TotalPowerStorage, 1e7, 0) * powerReq.StorageErrorMultiplier;

            logger?.Invoke("Power throughput current {0:e} vs {1:e}. Err {2:e}", -BlockSetInfo.TotalPowerNetConsumption, powerReq.Throughput, errPowerThroughput);
            logger?.Invoke("Power capacity current {0:e} vs {1:e}. Err {2:e}", BlockSetInfo.TotalPowerStorage, powerReq.Storage, errPowerStorage);
            error += errPowerThroughput;
            error += errPowerStorage;
            return(error);
        }
Exemplo n.º 2
0
        public static ReservedSpace ParseReservedSpace(float gridSize, MyObjectBuilder_CubeBlock src, string[] args, Utilities.LoggingCallback log = null)
        {
            var optional = false;
            var shared   = false;
            var nSet     = false;
            var pSet     = false;
            var nExt     = Vector3.Zero;
            var pExt     = Vector3.Zero;

            foreach (var arg in args)
            {
                if (arg.StartsWithICase("NE:"))
                {
                    Vector3 tmp;
                    if (PartDummyUtils.TryParseVector(arg.Substring(3), out tmp))
                    {
                        nSet = true;
                        nExt = tmp;
                    }
                    else
                    {
                        log?.Invoke("Failed to decode negative extent argument \"{0}\"", arg);
                    }
                }
                else if (arg.StartsWithICase("PE:"))
                {
                    Vector3 tmp;
                    if (PartDummyUtils.TryParseVector(arg.Substring(3), out tmp))
                    {
                        pSet = true;
                        pExt = tmp;
                    }
                    else
                    {
                        log?.Invoke("Failed to decode positive extent argument \"{0}\"", arg);
                    }
                }
                else if (arg.Equals("share", StringComparison.CurrentCultureIgnoreCase) || arg.Equals("shared", StringComparison.CurrentCultureIgnoreCase))
                {
                    shared = true;
                }
                else if (arg.Equals("opt", StringComparison.CurrentCultureIgnoreCase) || arg.Equals("optional", StringComparison.CurrentCultureIgnoreCase) || arg.Equals("hint", StringComparison.CurrentCultureIgnoreCase))
                {
                    optional = true;
                }
                else
                {
                    log?.Invoke("Failed to decode argument \"{0}\"", arg);
                }
            }
            if (!nSet || !pSet)
            {
                var sense = src as MyObjectBuilder_SensorBlock;
                if (sense != null)
                {
                    if (!nSet)
                    {
                        nExt = (Vector3)sense.FieldMin / gridSize;
                    }
                    if (!pSet)
                    {
                        pExt = (Vector3)sense.FieldMax / gridSize;
                    }
                }
                else
                {
                    log?.Invoke("Isn't a sensor block and isn't fully specified");
                }
            }
            var srcTra = new MatrixI(src.BlockOrientation).GetFloatMatrix();

            nExt = Vector3.TransformNormal(nExt, srcTra);
            pExt = Vector3.TransformNormal(pExt, srcTra);
            return(new ReservedSpace()
            {
                Box = new BoundingBox(nExt, pExt), IsOptional = optional, IsShared = shared
            });
        }