Exemplo n.º 1
0
        public double AddQuantity(double amount, bool exactAmountOnly)
        {
            lock (_lock)
            {
                double actualAmount = amount;

                //   Figure out what should actually be stored
                double max = _quantityMax_Usable ?? _quantityMax;
                if (_quantityCurrent + actualAmount > max)
                {
                    actualAmount = max - _quantityCurrent;
                }

                //if (exactAmountOnly && actualAmount != amount)
                if (exactAmountOnly && !Math1D.IsNearValue(actualAmount, amount))
                {
                    actualAmount = 0d;
                }

                //   Add the value
                _quantityCurrent += actualAmount;

                //   Exit function
                return(amount - actualAmount);
            }
        }
Exemplo n.º 2
0
        private void Update_Position_Orbit(double elapsedTime)
        {
            //NOTE: This method doesn't try to limit motion inside the boundry rectangle, it just used the boundry to calculate orbit radius
            double orbitRadius = this.Boundry.Length * .8;

            Vector3D posVect = this.Position.ToVector();

            // Fix position
            if (Math3D.IsNearZero(posVect))
            {
                posVect = Math3D.GetRandomVector_Spherical_Shell(orbitRadius);
            }
            else if (!Math1D.IsNearValue(this.Position.ToVector().LengthSquared, orbitRadius * orbitRadius))
            {
                posVect = posVect.ToUnit() * orbitRadius;
            }

            // Figure out how many degrees to turn
            double circ  = Math.PI * orbitRadius * 2;
            double angle = this.Speed_Position / circ * 360 * elapsedTime;

            posVect = posVect.GetRotatedVector(_velocityUnit, angle);       // using the velocity vector as the axis of rotation

            this.Position = posVect.ToPoint();
        }
Exemplo n.º 3
0
        public double AddQuantity(IContainer pullFrom, double amount, bool exactAmountOnly)
        {
            lock (_lock)
            {
                double actualAmount = amount;

                // See if I can handle that much
                double max = _quantityMax_Usable ?? _quantityMax;
                if (_quantityCurrent + actualAmount > max)
                {
                    actualAmount = max - _quantityCurrent;
                }

                if (exactAmountOnly && !Math1D.IsNearValue(actualAmount, amount))
                {
                    actualAmount = 0d;
                }

                if (actualAmount != 0d)
                {
                    // Now try to pull that much out of the source container
                    actualAmount -= pullFrom.RemoveQuantity(actualAmount, exactAmountOnly);

                    // Add the value
                    _quantityCurrent += actualAmount;
                }

                // Exit function
                return(amount - actualAmount);
            }
        }
Exemplo n.º 4
0
        private static void DrawImage(Image image, double[] values)
        {
            double widthHeight    = Math.Sqrt(values.Length);  // they should be square
            int    widthHeightInt = widthHeight.ToInt_Round();

            if (!Math1D.IsNearValue(widthHeight, widthHeightInt))
            {
                throw new ApplicationException("Expected square images");
            }

            BitmapSource source;

            //if (isColor)
            //{
            //    source = UtilityWPF.GetBitmap_RGB(example, width, height);
            //}
            //else
            //{
            source = UtilityWPF.GetBitmap(values, widthHeightInt, widthHeightInt);
            //}

            image.Source = source;
            image.Width  = source.PixelWidth;     // if this isn't set, the image will take up all of the width, and be huge
            image.Height = source.PixelHeight;
        }
Exemplo n.º 5
0
        internal static double RemoveQuantity(double amount, List <Cargo> cargo)
        {
            //NOTE: cargo should be sorted from low density to high density, so the lowest quality material is removed first

            double current = 0d;

            while (cargo.Count > 0)
            {
                double mass = cargo[0].Density * cargo[0].Volume;

                if (current + mass < amount || Math1D.IsNearValue(current + mass, amount))
                {
                    // Eat this whole piece of cargo
                    current += mass;
                    cargo.RemoveAt(0);
                }
                else
                {
                    // Remove some of this cargo
                    double remainingMass   = amount - current;
                    double remainingVolume = remainingMass / cargo[0].Density;
                    cargo[0].Volume -= remainingVolume;
                    current          = amount;
                    break;
                }
            }

            // Return how much of the request COULDN'T be filled
            return(amount - current);
        }
Exemplo n.º 6
0
        /// <summary>
        /// This keeps the cargo hold sorted by density
        /// NOTE: If volumes change outside of this thread, then this could place cargo in an imperfect order.  No real damage, just be aware
        /// </summary>
        internal static void Add(List <Cargo> cargoHold, Cargo cargo)
        {
            if (cargoHold.Count == 0)
            {
                cargoHold.Add(cargo);
                return;
            }

            for (int cntr = 0; cntr < cargoHold.Count; cntr++)
            {
                if (cargo.Density < cargoHold[cntr].Density)
                {
                    // This is less dense, put it here
                    cargoHold.Insert(cntr, cargo);
                    return;
                }
                else if (Math1D.IsNearValue(cargo.Density, cargoHold[cntr].Density) && cargo.Volume < cargoHold[cntr].Volume)
                {
                    // This is the same density, but has less volume, so put it here
                    cargoHold.Insert(cntr, cargo);
                    return;
                }
            }

            // This is more desnse than everything else, put it at the end
            cargoHold.Add(cargo);
        }
Exemplo n.º 7
0
        private double AddQuantity_priv(double amount, bool exactAmountOnly)
        {
            double current = GetQuantityCurrent();
            double max     = GetQuantityMax().Item1;    // using the destroyed aware max

            double actualAmount = amount;

            //   Figure out what should actually be stored
            if (current + actualAmount > max)
            {
                actualAmount = max - current;
            }

            if (exactAmountOnly && !Math1D.IsNearValue(actualAmount, amount))
            {
                actualAmount = 0d;
            }

            if (actualAmount != 0d)
            {
                #region Add it

                // Ensure that the containers are equalized
                switch (_ownership)
                {
                case ContainerOwnershipType.GroupIsSoleOwner:
                    // Nothing to do
                    break;

                case ContainerOwnershipType.QuantitiesCanChange:
                    EqualizeContainers(false);
                    break;

                case ContainerOwnershipType.QuantitiesMaxesCanChange:
                    EqualizeContainers(true);
                    break;

                default:
                    throw new ApplicationException("Unknown ContainerOwnershipType: " + _ownership.ToString());
                }

                // Add the value evenly
                for (int cntr = 0; cntr < _containers.Count; cntr++)
                {
                    if (!_destroyed[cntr])
                    {
                        _containers[cntr].Item1.QuantityCurrent += actualAmount * _ratios[cntr].Item1;      // using the destroyed aware ratio
                    }
                }

                // Cache the new value (this is used if sole owner)
                _current = current + actualAmount;

                #endregion
            }

            //   Exit function
            return(amount - actualAmount);
        }
Exemplo n.º 8
0
        //NOTE: There is only an add method.  Any cargo added to this converter is burned off over time
        public bool Add(Cargo cargo)
        {
            lock (_lock)
            {
                //double sumVolume = this.UsedVolume + cargo.Volume;
                double sumVolume = _cargo.Sum(o => o.Volume) + cargo.Volume;        // inlined this.UsedVolume because of the lock

                if (sumVolume <= this.MaxVolume || Math1D.IsNearValue(sumVolume, this.MaxVolume))
                {
                    ConverterMatterToFuel.Add(_cargo, cargo);
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// This is a helper method to know what RemoveQuantity will take (between RemovalMultiple and exactAmountOnly, it
        /// gets a little complex)
        /// </summary>
        public static double GetRemoveAmount(IContainer container, double amount, bool exactAmountOnly)
        {
            //NOTE: I couldn't think of a way to make this totally threadsafe without adding more to the IContainer interface that returns all the needed
            //variables in one shot.  But in reality, OnlyRemoveMultiples and RemovalMultiple should change very infrequently if ever

            double retVal = amount;

            double quantityCurrent = container.QuantityCurrent;

            // See if the outgoing flow needs to be restricted
            if (retVal > quantityCurrent)
            {
                retVal = quantityCurrent;
            }

            // See if it wants even multiples
            if (container.OnlyRemoveMultiples)
            {
                double removalMultiple = container.RemovalMultiple;

                if (!Math1D.IsDivisible(retVal, removalMultiple))
                {
                    // Remove as many multiples of the requested amount as possible
                    retVal = Math.Floor(retVal / removalMultiple) * removalMultiple;
                }
            }

            // Exact amount
            if (exactAmountOnly && !Math1D.IsNearValue(retVal, amount))
            {
                retVal = 0d;
            }

            // Exit Function
            return(retVal);
        }
Exemplo n.º 10
0
        private Model3D GetModel()
        {
            const double SIZE = 4;

            Model3DGroup    retVal = new Model3DGroup();
            GeometryModel3D geometry;
            MaterialGroup   material;

            var rhomb = UtilityWPF.GetRhombicuboctahedron(SIZE, SIZE, SIZE);

            TriangleIndexed[] triangles;

            #region X,Y,Z spikes

            double thickness = .2;
            double length    = SIZE * 1.5;

            retVal.Children.Add(new BillboardLine3D()
            {
                Color             = UtilityWPF.ColorFromHex("80" + ChaseColors.X),
                IsReflectiveColor = false,
                Thickness         = thickness,
                FromPoint         = new Point3D(0, 0, 0),
                ToPoint           = new Point3D(length, 0, 0)
            }.Model);

            retVal.Children.Add(new BillboardLine3D()
            {
                Color             = UtilityWPF.ColorFromHex("80" + ChaseColors.Y),
                IsReflectiveColor = false,
                Thickness         = thickness,
                FromPoint         = new Point3D(0, 0, 0),
                ToPoint           = new Point3D(0, length, 0)
            }.Model);

            retVal.Children.Add(new BillboardLine3D()
            {
                Color             = UtilityWPF.ColorFromHex("80" + ChaseColors.Z),
                IsReflectiveColor = false,
                Thickness         = thickness,
                FromPoint         = new Point3D(0, 0, 0),
                ToPoint           = new Point3D(0, 0, length)
            }.Model);

            #endregion

            #region X plates

            geometry = new GeometryModel3D();

            material = new MaterialGroup();
            material.Children.Add(new DiffuseMaterial(new SolidColorBrush(UtilityWPF.ColorFromHex("80" + ChaseColors.X))));
            material.Children.Add(new SpecularMaterial(new SolidColorBrush(UtilityWPF.ColorFromHex("70DCE01D")), 5));

            geometry.Material     = material;
            geometry.BackMaterial = material;

            triangles = rhomb.Squares_Orth.
                        SelectMany(o => o).
                        Where(o => o.IndexArray.All(p => Math1D.IsNearValue(Math.Abs(o.AllPoints[p].X * 2), SIZE))).
                        ToArray();

            geometry.Geometry = UtilityWPF.GetMeshFromTriangles_IndependentFaces(triangles);

            retVal.Children.Add(geometry);

            #endregion
            #region Y plates

            geometry = new GeometryModel3D();

            material = new MaterialGroup();
            material.Children.Add(new DiffuseMaterial(new SolidColorBrush(UtilityWPF.ColorFromHex("80" + ChaseColors.Y))));
            material.Children.Add(new SpecularMaterial(new SolidColorBrush(UtilityWPF.ColorFromHex("702892BF")), 3));

            geometry.Material     = material;
            geometry.BackMaterial = material;

            triangles = rhomb.Squares_Orth.
                        SelectMany(o => o).
                        Where(o => o.IndexArray.All(p => Math1D.IsNearValue(Math.Abs(o.AllPoints[p].Y * 2), SIZE))).
                        ToArray();

            geometry.Geometry = UtilityWPF.GetMeshFromTriangles_IndependentFaces(triangles);

            retVal.Children.Add(geometry);

            #endregion
            #region Z plates

            geometry = new GeometryModel3D();

            material = new MaterialGroup();
            material.Children.Add(new DiffuseMaterial(new SolidColorBrush(UtilityWPF.ColorFromHex("80" + ChaseColors.Z))));
            material.Children.Add(new SpecularMaterial(new SolidColorBrush(UtilityWPF.ColorFromHex("B0CF1919")), 17));

            geometry.Material     = material;
            geometry.BackMaterial = material;

            triangles = rhomb.Squares_Orth.
                        SelectMany(o => o).
                        Where(o => o.IndexArray.All(p => Math1D.IsNearValue(Math.Abs(o.AllPoints[p].Z * 2), SIZE))).
                        ToArray();

            geometry.Geometry = UtilityWPF.GetMeshFromTriangles_IndependentFaces(triangles);

            retVal.Children.Add(geometry);

            #endregion
            #region Base

            geometry = new GeometryModel3D();

            material = new MaterialGroup();
            material.Children.Add(new DiffuseMaterial(new SolidColorBrush(UtilityWPF.ColorFromHex("305B687A"))));
            material.Children.Add(new SpecularMaterial(new SolidColorBrush(UtilityWPF.ColorFromHex("507E827A")), 12));

            geometry.Material     = material;
            geometry.BackMaterial = material;

            triangles = UtilityCore.Iterate(
                rhomb.Squares_Diag.SelectMany(o => o),
                rhomb.Triangles
                ).ToArray();

            geometry.Geometry = UtilityWPF.GetMeshFromTriangles_IndependentFaces(triangles);

            retVal.Children.Add(geometry);

            #endregion

            return(retVal);
        }
Exemplo n.º 11
0
        public virtual void Update_AnyThread(double elapsedTime)
        {
            //NOTE: This method doesn't have a lock, so there could be a bit of reentry.  But the individual pieces should be ok with that

            double age   = this.Age;
            long   count = Interlocked.Increment(ref _partUpdateCount_AnyThread);

            #region Fill the converters

            if (_parts.Containers.ConvertMatterGroup != null && age >= (double)_nextMatterTransferTime)
            {
                if (_parts.Containers.ConvertMatterGroup.Transfer())
                {
                    this.ShouldRecalcMass_Large = true;
                }

                //NOTE: Throwing a min in there, because if I have breakpoints set elsewhere, and resume after awhile, elapsed time will be
                //huge, and the calculated next transer time will be obscene.  In those cases, the odds are good that the bot will be fairly young
                //so a simple 110% of age should be enough of a safeguard
                //_nextMatterTransferTime = Math.Min(age * 1.1, age + (elapsedTime * StaticRandom.Next(80, 120)));      // no need to spin the processor unnecessarily each tick
                _nextMatterTransferTime = Math.Min(age * 1.1, age + (elapsedTime * StaticRandom.Next(20, 60)));      // no need to spin the processor unnecessarily each tick
            }

            #endregion

            #region Update Parts

            foreach (int index in UtilityCore.RandomRange(0, _updatableParts_AnyThread.Length))
            {
                int skips = _updatableParts_AnyThread[index].IntervalSkips_AnyThread.Value;        // no need to check for null, nulls weren't added to the list
                if (skips > 0 && count % (skips + 1) != 0)
                {
                    continue;
                }

                _updatableParts_AnyThread[index].Update_AnyThread(elapsedTime + (elapsedTime * skips));       // if skips is greater than zero, then approximate how much time elapsed based on this tick's elapsed time
            }

            if (_lifeEvents != null)
            {
                _lifeEvents.Update_AnyThread(elapsedTime);
            }

            // Detect small change
            if (_hasMassChangingUpdatables_Small)
            {
                // There's a good chance that at least one of the parts changed the ship's mass a little bit
                this.ShouldRecalcMass_Small = true;
            }

            // Detect medium change
            if (_hasMassChangingUpdatables_Medium && !this.ShouldRecalcMass_Medium)
            {
                double?ammoVolumeAtRecalc = (double?)_ammoVolumeAtRecalc;
                double ammoMassCur        = _parts.Containers.AmmoGroup.QuantityCurrent;

                if (ammoVolumeAtRecalc != null && !Math1D.IsNearValue(ammoVolumeAtRecalc.Value, ammoMassCur))
                {
                    this.ShouldRecalcMass_Medium = true;
                }
            }

            #endregion

            #region Recalc mass

            if (this.ShouldRecalcMass_Large)
            {
                RecalculateMass();
            }
            else if (this.ShouldRecalcMass_Medium && age > (double)_lastMassRecalculateTime + (elapsedTime * 200d))
            {
                RecalculateMass();
            }
            else if (this.ShouldRecalcMass_Small && age > (double)_lastMassRecalculateTime + (elapsedTime * 1000d))     //NOTE: This age check isn't atomic, so multiple threads could theoretically interfere, but I don't think it's worth worrying about (the RecalculateMass method itself is threadsafe)
            {
                RecalculateMass();
            }

            #endregion
        }
Exemplo n.º 12
0
        private void btnMovePoints_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (!double.TryParse(txtRadius.Text, out double radius))
                {
                    MessageBox.Show("Couldn't parse radius as a double", this.Title, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }

                if (!double.TryParse(txtMovePercent.Text, out double percent))
                {
                    MessageBox.Show("Couldn't parse percent as a double", this.Title, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }
                percent /= 100d;

                double calcDist;
                if (chkCalcDist.IsChecked.Value)
                {
                    if (!double.TryParse(txtCalcDist.Text, out calcDist))
                    {
                        MessageBox.Show("Couldn't parse calculation distance as a double", this.Title, MessageBoxButton.OK, MessageBoxImage.Warning);
                        return;
                    }
                }
                else
                {
                    calcDist = GetCalcDistance(GetApproximateCount(_dots, radius), radius);
                }

                ClearDebugVisuals();


                if (!chkInteriorPoints.IsChecked.Value)
                {
                    // Snap them to the surface of the sphere
                    SnapToSphere(_dots, radius);
                }



                Vector3D[] forces = new Vector3D[_dots.Count];
                if (chkInteriorPoints.IsChecked.Value && chkInwardForce.IsChecked.Value)
                {
                    // Inward Force
                    GetInwardForces(forces, _dots);
                }

                if (chkRepulsiveForce.IsChecked.Value)
                {
                    // Repulsion Force
                    GetRepulsionForces(forces, _dots, calcDist);
                }

                // Move the points
                for (int cntr = 0; cntr < _dots.Count; cntr++)
                {
                    if (!_dots[cntr].IsStatic)
                    {
                        _dots[cntr].Position += forces[cntr] * percent;
                    }
                }



                if (!chkInteriorPoints.IsChecked.Value)
                {
                    // Now that they've moved, snap them back to the surface of the sphere
                    SnapToSphere(_dots, radius);
                }



                if (chkShowForcesAfterMove.IsChecked.Value)
                {
                    btnCalculateForces_Click(this, new RoutedEventArgs());
                }

                if (chkShowRadius.IsChecked.Value)
                {
                    #region Show Radius

                    double   maxRadius = _dots.Where(o => !o.IsStatic).Max(o => o.Position.ToVector().Length);
                    Visual3D visual    = null;

                    if (Math1D.IsNearValue(radius, maxRadius))
                    {
                        // Draw one green one
                        visual = GetSphereVisual(radius, UtilityWPF.ColorFromHex("1000FF00"));
                        _debugVisuals.Add(visual);
                        _viewport.Children.Add(visual);
                    }
                    else if (maxRadius < radius)
                    {
                        // Small than desired radius
                        visual = GetSphereVisual(maxRadius, UtilityWPF.ColorFromHex("10FF0000"));
                        _debugVisuals.Add(visual);
                        _viewport.Children.Add(visual);

                        visual = GetSphereVisual(radius, UtilityWPF.ColorFromHex("10000000"));
                        _debugVisuals.Add(visual);
                        _viewport.Children.Add(visual);
                    }
                    else
                    {
                        // Larger than desired radius
                        visual = GetSphereVisual(radius, UtilityWPF.ColorFromHex("10000000"));
                        _debugVisuals.Add(visual);
                        _viewport.Children.Add(visual);

                        visual = GetSphereVisual(maxRadius, UtilityWPF.ColorFromHex("10FF0000"));
                        _debugVisuals.Add(visual);
                        _viewport.Children.Add(visual);
                    }

                    #endregion
                }

                UpdateReport();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
Exemplo n.º 13
0
        public double RemoveQuantity(double amount, bool exactAmountOnly)
        {
            lock (_lock)
            {
                double current = GetQuantityCurrent();
                double max     = GetQuantityMax().Item1;    // using the destroyed aware max

                double actualAmount = amount;

                // See if I need to restrict the outgoing flow
                if (actualAmount > current)
                {
                    actualAmount = current;
                }

                //NOTE: Only looking at the whole, not each individual container
                if (_onlyRemoveMultiples && !Math1D.IsDivisible(actualAmount, _removalMultiple))
                {
                    // Remove as many multiples of the requested amount as possible
                    actualAmount = Math.Floor(actualAmount / _removalMultiple) * _removalMultiple;
                }

                if (exactAmountOnly && !Math1D.IsNearValue(actualAmount, amount))
                {
                    actualAmount = 0d;
                }

                if (actualAmount != 0d)
                {
                    #region Remove it

                    // Ensure that the containers are equalized
                    switch (_ownership)
                    {
                    case ContainerOwnershipType.GroupIsSoleOwner:
                        // Nothing to do
                        break;

                    case ContainerOwnershipType.QuantitiesCanChange:
                        EqualizeContainers(false);
                        break;

                    case ContainerOwnershipType.QuantitiesMaxesCanChange:
                        EqualizeContainers(true);
                        break;

                    default:
                        throw new ApplicationException("Unknown ContainerOwnershipType: " + _ownership.ToString());
                    }

                    // Remove the value evenly
                    for (int cntr = 0; cntr < _containers.Count; cntr++)
                    {
                        _containers[cntr].Item1.QuantityCurrent -= actualAmount * _ratios[cntr].Item1;      // using the destroyed aware ratio
                    }

                    // Cache the new value (this is used if sole owner)
                    _current = current - actualAmount;

                    #endregion
                }

                // Exit function
                return(amount - actualAmount);
            }
        }
Exemplo n.º 14
0
        private double AddQuantity_priv(IContainer pullFrom, double amount, bool exactAmountOnly)
        {
            if (pullFrom is ITakesDamage && ((ITakesDamage)pullFrom).IsDestroyed)
            {
                return(0d);
            }

            double current = GetQuantityCurrent();
            double max     = GetQuantityMax().Item1;    // using the destroyed aware max

            double actualAmount = amount;

            // See if I can handle that much
            if (current + actualAmount > max)
            {
                actualAmount = max - current;
            }

            if (exactAmountOnly && !Math1D.IsNearValue(actualAmount, amount))
            {
                actualAmount = 0d;
            }

            if (actualAmount != 0d)
            {
                // Now try to pull that much out of the source container
                actualAmount -= pullFrom.RemoveQuantity(actualAmount, exactAmountOnly);

                if (actualAmount != 0d)
                {
                    #region Add it

                    // Ensure that the containers are equalized
                    switch (_ownership)
                    {
                    case ContainerOwnershipType.GroupIsSoleOwner:
                        // Nothing to do
                        break;

                    case ContainerOwnershipType.QuantitiesCanChange:
                        EqualizeContainers(false);
                        break;

                    case ContainerOwnershipType.QuantitiesMaxesCanChange:
                        EqualizeContainers(true);
                        break;

                    default:
                        throw new ApplicationException("Unknown ContainerOwnershipType: " + _ownership.ToString());
                    }

                    // Add the value evenly
                    for (int cntr = 0; cntr < _containers.Count; cntr++)
                    {
                        if (!_destroyed[cntr])
                        {
                            _containers[cntr].Item1.QuantityCurrent += actualAmount * _ratios[cntr].Item1;        // using the destroyed aware ratio
                        }
                    }

                    // Cache the new value (this is used if sole owner)
                    _current = current + actualAmount;

                    #endregion
                }
            }

            // Exit function
            return(amount - actualAmount);
        }
Exemplo n.º 15
0
        private void ResetTraining()
        {
            _patternStorage = null;
            panelTrainingImages.Children.Clear();

            if (_images.Count == 0)
            {
                return;
            }

            #region choose images

            int numImages;
            if (!int.TryParse(txtTrainCount.Text, out numImages))
            {
                MessageBox.Show("Couldn't parse count as an integer", this.Title, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            numImages = Math.Min(_images.Count, numImages);

            var trainImages = UtilityCore.RandomRange(0, _images.Count, numImages).
                              Select(o => new
            {
                File = _images[o],
                Conv = GetTrainingImage(_images[o], _trainKernel),
            }).
                              ToArray();

            #endregion

            //_patternStorage = new RandomPatternStorage();
            _patternStorage = new Hopfield(IMAGESIZE * IMAGESIZE, 0, 1, .9);

            #region show thumbnails

            // Display thumbnails
            //< !--Run them through a KMeans, then sort in 1D-- >
            //< !--Show full resolution over the canvas on mouseover-- >
            //< !--Show full resolution under the canvas on click-- >

            foreach (var trainImage in trainImages)
            {
                double widthHeight    = Math.Sqrt(trainImage.Conv.Length);  // they should be square
                int    widthHeightInt = widthHeight.ToInt_Round();
                if (!Math1D.IsNearValue(widthHeight, widthHeightInt))
                {
                    throw new ApplicationException("Expected square images");
                }

                double[] imageConv = trainImage.Conv;
                imageConv = _patternStorage.Convert_Local_External(imageConv);

                BitmapSource source;
                //if (isColor)
                //{
                //    source = UtilityWPF.GetBitmap_RGB(example, width, height);
                //}
                //else
                //{
                source = UtilityWPF.GetBitmap(imageConv, widthHeightInt, widthHeightInt);
                //}

                Image image = new Image()
                {
                    Source = source,
                    Width  = source.PixelWidth,     // if this isn't set, the image will take up all of the width, and be huge
                    Height = source.PixelHeight,
                    Margin = new Thickness(8),
                };

                panelTrainingImages.Children.Add(image);
            }

            #endregion

            _patternStorage.AddItems(trainImages.Select(o => o.Conv).ToArray());
        }
Exemplo n.º 16
0
        private void AddPoison(Mineral mineral)
        {
            // Try to pop this out of the map
            if (!_map.RemoveItem(mineral, true))
            {
                // It's already gone
                return;
            }

            double mass = mineral.VolumeInCubicMeters * mineral.Density;

            // Try to remove the equivalent mass from the cargo bay
            var vomit = base.CargoBays.RemoveMineral_Mass(mass);

            if (vomit.Item1 > 0d)
            {
                this.ShouldRecalcMass_Large = true;
            }

            if (Math1D.IsNearValue(vomit.Item1, mass))
            {
                // There was enough in the cargo bay to balance out the poison
                return;
            }

            mass -= vomit.Item1;

            // The remaining mass needs to come out of plasma/energy/fuel

            // The conversion ratios are meant to be lossy when going from mass to energy/fuel/plasma.  But when run the other direction, they
            // become overly ideal, so bump the target mass a bit to account for that
            mass *= 1.1d;

            // Plasma is least important, take from that first
            if (AddPoisonSprtContainer(ref mass, this.Plasma, _itemOptions.MatterToPlasma_ConversionRate))
            {
                // There was enough to cover it
                return;
            }

            // Draw from fuel next
            if (this.Fuel != null && this.Fuel.QuantityCurrent > 0d)
            {
                this.ShouldRecalcMass_Large = true;     // fuel is about to be removed, so set this now
            }

            if (AddPoisonSprtContainer(ref mass, this.Fuel, _itemOptions.MatterToFuel_ConversionRate))
            {
                // There was enough to cover it
                return;
            }

            // Go after energy as a last resort
            if (AddPoisonSprtContainer(ref mass, this.Energy, _itemOptions.MatterToEnergy_ConversionRate))
            {
                // There was enough to cover it
                return;
            }

            // If there's nothing left, then just exist.  The next time this bot is examined, it will be considered dead
        }