public PanelSimulation(FlyingBeanOptions options) { InitializeComponent(); _options = options; PropertyInfo[] propsOptions = typeof(FlyingBeanOptions).GetProperties(); //trkNumBeans.Value = _options.NumBeansAtATime; //trkProbWinner.Value = _options.NewBeanProbOfWinner * 100d; //trkGravity.Value = _options.Gravity; // Simulation _propLinks.Add(new SliderShowValues.PropSync(trkNumBeans, propsOptions.Where(o => o.Name == "NumBeansAtATime").First(), _options, 1, 30)); _propLinks.Add(new SliderShowValues.PropSync(trkProbWinner, propsOptions.Where(o => o.Name == "NewBeanProbOfWinner").First(), _options, 0, 1)); //TODO: Multiply by 100 _propLinks.Add(new SliderShowValues.PropSync(trkGravity, propsOptions.Where(o => o.Name == "Gravity").First(), _options, 0, 2)); chkRandomOrientation.IsChecked = _options.NewBeanRandomOrientation; chkRandomSpin.IsChecked = _options.NewBeanRandomSpin; // Death _propLinks.Add(new SliderShowValues.PropSync(trkLifespan, propsOptions.Where(o => o.Name == "MaxAgeSeconds").First(), _options, 5, 90)); _propLinks.Add(new SliderShowValues.PropSync(trkAngularVelocity, propsOptions.Where(o => o.Name == "AngularVelocityDeath").First(), _options, 0, 40)); _propLinks.Add(new SliderShowValues.PropSync(trkGroundCollisions, propsOptions.Where(o => o.Name == "MaxGroundCollisions").First(), _options, 0, 5)); // Misc chkShowExplosions.IsChecked = _options.ShowExplosions; _isInitialized = true; }
//TODO: Rework this class to use SessionSaveLoad.cs public static void Save(string baseFolder, string saveFolder, FlyingBeanSession session, FlyingBeanOptions options, ItemOptions itemOptions) { // Session //NOTE: This is in the base folder UtilityCore.SerializeToFile(Path.Combine(baseFolder, FILENAME_SESSION), session); // ItemOptions UtilityCore.SerializeToFile(Path.Combine(saveFolder, FILENAME_ITEMOPTIONS), itemOptions); // Options FlyingBeanOptions optionCloned = UtilityCore.Clone(options); optionCloned.DefaultBeanList = null; // this is programatically generated, no need to save it //optionCloned.NewBeanList //NOTE: These will be serialized with the options file SortedList <string, ShipDNA> winningFilenames; SortedList <string, double> maxScores; ExtractHistory(out winningFilenames, out maxScores, options.WinnersFinal); // can't use cloned.winners, that property is skipped when serializing optionCloned.WinningScores = maxScores; // Main class UtilityCore.SerializeToFile(Path.Combine(saveFolder, FILENAME_OPTIONS), optionCloned); // Winning beans if (winningFilenames != null) { foreach (string beanFile in winningFilenames.Keys) { UtilityCore.SerializeToFile(Path.Combine(saveFolder, beanFile), winningFilenames[beanFile]); } } }
public PanelBeanTypes(FlyingBeanOptions options, World world) { InitializeComponent(); _world = world; this.Options = options; }
public Bean(BotConstruction_Result construction, FlyingBeanOptions beanOptions) : base(construction) { _beanOptions = beanOptions; _dyingCounters = new SortedList <CauseOfDeath, int>(); foreach (CauseOfDeath cause in Enum.GetValues(typeof(CauseOfDeath))) { _dyingCounters.Add(cause, 0); } }
public static MutateUtility.ShipMutateArgs BuildMutateArgs(FlyingBeanOptions options) { #region Neural MutateUtility.NeuronMutateArgs neuralArgs = null; if (options.MutateChangeNeural) { MutateUtility.MuateArgs neuronMovement = new MutateUtility.MuateArgs(false, options.NeuronPercentToMutate, null, null, new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Distance, options.NeuronMovementAmount)); // neurons are all point3D (positions need to drift around freely. percent doesn't make much sense) MutateUtility.MuateArgs linkMovement = new MutateUtility.MuateArgs(false, options.LinkPercentToMutate, new Tuple <string, MutateUtility.MuateFactorArgs>[] { Tuple.Create("FromContainerPosition", new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Distance, options.LinkContainerMovementAmount)), Tuple.Create("FromContainerOrientation", new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Percent, options.LinkContainerRotateAmount)) }, new Tuple <PropsByPercent.DataType, MutateUtility.MuateFactorArgs>[] { Tuple.Create(PropsByPercent.DataType.Double, new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Distance, options.LinkWeightAmount)), // all the doubles are weights, which need to be able to cross over zero (percents can't go + to -) Tuple.Create(PropsByPercent.DataType.Point3D, new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Distance, options.LinkMovementAmount)), // using a larger value for the links }, null); neuralArgs = new MutateUtility.NeuronMutateArgs(neuronMovement, null, linkMovement, null); } #endregion #region Body MutateUtility.MuateArgs bodyArgs = null; if (options.MutateChangeBody) { var mutate_Vector3D = Tuple.Create(PropsByPercent.DataType.Vector3D, new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Percent, options.BodySizeChangePercent)); var mutate_Point3D = Tuple.Create(PropsByPercent.DataType.Point3D, new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Distance, options.BodyMovementAmount)); // positions need to drift around freely. percent doesn't make much sense var mutate_Quaternion = Tuple.Create(PropsByPercent.DataType.Quaternion, new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Percent, options.BodyOrientationChangePercent)); //NOTE: The mutate class has special logic for Scale and ThrusterDirections bodyArgs = new MutateUtility.MuateArgs(true, options.BodyNumToMutate, null, new Tuple <PropsByPercent.DataType, MutateUtility.MuateFactorArgs>[] { mutate_Vector3D, mutate_Point3D, mutate_Quaternion, }, new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Percent, .01d)); // this is just other (currently there aren't any others - just being safe) } #endregion return(new MutateUtility.ShipMutateArgs(null, bodyArgs, neuralArgs)); }
public Bean(BotConstruction_Result construction, FlyingBeanOptions beanOptions) : base(construction) { _beanOptions = beanOptions; _dyingCounters = new SortedList<CauseOfDeath, int>(); foreach (CauseOfDeath cause in Enum.GetValues(typeof(CauseOfDeath))) { _dyingCounters.Add(cause, 0); } }
public PanelMutation(FlyingBeanOptions options) { InitializeComponent(); _options = options; PropertyInfo[] propsOptions = typeof(FlyingBeanOptions).GetProperties(); _propLinks.Add(new SliderShowValues.PropSync(trkNumBody, propsOptions.Where(o => o.Name == "BodyNumToMutate").First(), _options, 1, 10)); _propLinks.Add(new SliderShowValues.PropSync(trkBodyVect, propsOptions.Where(o => o.Name == "BodySizeChangePercent").First(), _options, 0, 2d)); _propLinks.Add(new SliderShowValues.PropSync(trkBodyPos, propsOptions.Where(o => o.Name == "BodyMovementAmount").First(), _options, 0, 1d)); _propLinks.Add(new SliderShowValues.PropSync(trkBodyOrient, propsOptions.Where(o => o.Name == "BodyOrientationChangePercent").First(), _options, 0, .2)); _propLinks.Add(new SliderShowValues.PropSync(trkPercentNeurons, propsOptions.Where(o => o.Name == "NeuronPercentToMutate").First(), _options, 0, .08)); //TODO: Multiply by 100 _propLinks.Add(new SliderShowValues.PropSync(trkNeuronDistance, propsOptions.Where(o => o.Name == "NeuronMovementAmount").First(), _options, 0, .2)); _propLinks.Add(new SliderShowValues.PropSync(trkPercentLinks, propsOptions.Where(o => o.Name == "LinkPercentToMutate").First(), _options, 0, .08)); //TODO: Multiply by 100 _propLinks.Add(new SliderShowValues.PropSync(trkLinkWeight, propsOptions.Where(o => o.Name == "LinkWeightAmount").First(), _options, 0, .5)); _propLinks.Add(new SliderShowValues.PropSync(trkLinkDistance, propsOptions.Where(o => o.Name == "LinkMovementAmount").First(), _options, 0, .5)); _propLinks.Add(new SliderShowValues.PropSync(trkLinkFromContainerDist, propsOptions.Where(o => o.Name == "LinkContainerMovementAmount").First(), _options, 0, 1)); _propLinks.Add(new SliderShowValues.PropSync(trkLinkFromContainerRotate, propsOptions.Where(o => o.Name == "LinkContainerRotateAmount").First(), _options, 0, .3)); //TODO: Figure out how to do this in xaml trkNumBody.ValueChanged += new EventHandler(Slider_ValueChanged); trkBodyVect.ValueChanged += new EventHandler(Slider_ValueChanged); trkBodyPos.ValueChanged += new EventHandler(Slider_ValueChanged); trkBodyOrient.ValueChanged += new EventHandler(Slider_ValueChanged); trkPercentNeurons.ValueChanged += new EventHandler(Slider_ValueChanged); trkNeuronDistance.ValueChanged += new EventHandler(Slider_ValueChanged); trkPercentLinks.ValueChanged += new EventHandler(Slider_ValueChanged); trkLinkWeight.ValueChanged += new EventHandler(Slider_ValueChanged); trkLinkDistance.ValueChanged += new EventHandler(Slider_ValueChanged); trkLinkFromContainerDist.ValueChanged += new EventHandler(Slider_ValueChanged); trkLinkFromContainerRotate.ValueChanged += new EventHandler(Slider_ValueChanged); chkBody.IsChecked = options.MutateChangeBody; chkNeural.IsChecked = options.MutateChangeNeural; //trkPercentNeurons.Value = _options.NeuronPercentToMutate * 100d; //trkNeuronDistance.Value = _options.NeuronMovementAmount; //trkPercentLinks.Value = _options.LinkPercentToMutate * 100d; //trkLinkWeight.Value = _options.LinkWeightAmount; //trkLinkDistance.Value = _options.LinkMovementAmount; //trkLinkFromContainerDist.Value = _options.LinkContainerMovementAmount; //trkLinkFromContainerRotate.Value = _options.LinkContainerRotateAmount; _isInitialized = true; }
public PanelFile(string sessionFolder, FlyingBeanSession session, FlyingBeanOptions options, ItemOptions itemOptions, SortedList <string, ShipDNA> defaultBeanList) { InitializeComponent(); _defaultBeanList = defaultBeanList; this.SessionFolder = sessionFolder; this.Session = session; this.Options = options; this.ItemOptions = itemOptions; _isInitialized = true; }
public PanelFile(string sessionFolder, FlyingBeanSession session, FlyingBeanOptions options, ItemOptions itemOptions, SortedList<string, ShipDNA> defaultBeanList) { InitializeComponent(); _defaultBeanList = defaultBeanList; this.SessionFolder = sessionFolder; this.Session = session; this.Options = options; this.ItemOptions = itemOptions; _isInitialized = true; }
public PanelTracking(FlyingBeanOptions options) { InitializeComponent(); _options = options; PropertyInfo[] propsOptions = typeof(FlyingBeanOptions).GetProperties(); _propLinks.Add(new SliderShowValues.PropSync(trkLineagesFinal, propsOptions.Where(o => o.Name == "TrackingMaxLineagesFinal").First(), _options, 1, 10)); _propLinks.Add(new SliderShowValues.PropSync(trkNumPerLineageFinal, propsOptions.Where(o => o.Name == "TrackingMaxPerLineageFinal").First(), _options, 1, 10)); _propLinks.Add(new SliderShowValues.PropSync(trkLineagesLive, propsOptions.Where(o => o.Name == "TrackingMaxLineagesLive").First(), _options, 1, 10)); _propLinks.Add(new SliderShowValues.PropSync(trkNumPerLineageLive, propsOptions.Where(o => o.Name == "TrackingMaxPerLineageLive").First(), _options, 1, 10)); _propLinks.Add(new SliderShowValues.PropSync(trkNumCandidates, propsOptions.Where(o => o.Name == "FinalistCount").First(), _options, 0, 8)); _propLinks.Add(new SliderShowValues.PropSync(trkScanFrequency, propsOptions.Where(o => o.Name == "TrackingScanFrequencySeconds").First(), _options, .1, 5)); _isInitialized = true; }
public void New(bool startEmpty, bool randomSettings) { FlyingBeanOptions beanOptions = new FlyingBeanOptions(); ItemOptions itemOptions = new ItemOptions(); if (randomSettings) { double newBeanProb = beanOptions.NewBeanProbOfWinner; double scanFrequency = beanOptions.TrackingScanFrequencySeconds; beanOptions = MutateUtility.MutateSettingsObject(beanOptions, new MutateUtility.MuateArgs(.5d)); beanOptions.NewBeanProbOfWinner = newBeanProb; // leave these one alone beanOptions.TrackingScanFrequencySeconds = scanFrequency; itemOptions = MutateUtility.MutateSettingsObject(itemOptions, new MutateUtility.MuateArgs(.5d)); } FinishLoad(new FlyingBeanSession(), beanOptions, itemOptions, null, null, startEmpty); }
public void Save(bool async, bool pruneAutosavesAfter, string name) { const int MAXAUTOSAVES = 8; string baseFolder = UtilityCore.GetOptionsFolder(); string saveFolder = GetNewSaveFolder(name); FlyingBeanSession session = this.Session ?? new FlyingBeanSession(); FlyingBeanOptions options = this.Options; ItemOptions itemOptions = this.ItemOptions; string sessionFolder = this.SessionFolder; // It doesn't matter what folder was stored there before, make sure it holds where the last save is session.SessionFolder = sessionFolder; if (async) { Task.Factory.StartNew(() => { FlyingBeanSession.Save(baseFolder, saveFolder, session, options, itemOptions); if (pruneAutosavesAfter) { PruneAutosaves(sessionFolder, MAXAUTOSAVES); } }); } else { FlyingBeanSession.Save(baseFolder, saveFolder, session, options, itemOptions); if (pruneAutosavesAfter) { PruneAutosaves(sessionFolder, MAXAUTOSAVES); } } }
public static MutateUtility.ShipMutateArgs BuildMutateArgs(FlyingBeanOptions options) { #region Neural MutateUtility.NeuronMutateArgs neuralArgs = null; if (options.MutateChangeNeural) { MutateUtility.MuateArgs neuronMovement = new MutateUtility.MuateArgs(false, options.NeuronPercentToMutate, null, null, new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Distance, options.NeuronMovementAmount)); // neurons are all point3D (positions need to drift around freely. percent doesn't make much sense) MutateUtility.MuateArgs linkMovement = new MutateUtility.MuateArgs(false, options.LinkPercentToMutate, new Tuple<string, MutateUtility.MuateFactorArgs>[] { Tuple.Create("FromContainerPosition", new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Distance, options.LinkContainerMovementAmount)), Tuple.Create("FromContainerOrientation", new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Percent, options.LinkContainerRotateAmount)) }, new Tuple<PropsByPercent.DataType, MutateUtility.MuateFactorArgs>[] { Tuple.Create(PropsByPercent.DataType.Double, new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Distance, options.LinkWeightAmount)), // all the doubles are weights, which need to be able to cross over zero (percents can't go + to -) Tuple.Create(PropsByPercent.DataType.Point3D, new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Distance, options.LinkMovementAmount)), // using a larger value for the links }, null); neuralArgs = new MutateUtility.NeuronMutateArgs(neuronMovement, null, linkMovement, null); } #endregion #region Body MutateUtility.MuateArgs bodyArgs = null; if (options.MutateChangeBody) { var mutate_Vector3D = Tuple.Create(PropsByPercent.DataType.Vector3D, new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Percent, options.BodySizeChangePercent)); var mutate_Point3D = Tuple.Create(PropsByPercent.DataType.Point3D, new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Distance, options.BodyMovementAmount)); // positions need to drift around freely. percent doesn't make much sense var mutate_Quaternion = Tuple.Create(PropsByPercent.DataType.Quaternion, new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Percent, options.BodyOrientationChangePercent)); //NOTE: The mutate class has special logic for Scale and ThrusterDirections bodyArgs = new MutateUtility.MuateArgs(true, options.BodyNumToMutate, null, new Tuple<PropsByPercent.DataType, MutateUtility.MuateFactorArgs>[] { mutate_Vector3D, mutate_Point3D, mutate_Quaternion, }, new MutateUtility.MuateFactorArgs(MutateUtility.FactorType.Percent, .01d)); // this is just other (currently there aren't any others - just being safe) } #endregion return new MutateUtility.ShipMutateArgs(null, bodyArgs, neuralArgs); }
private void FinishLoad(FlyingBeanSession session, FlyingBeanOptions options, ItemOptions itemOptions, ShipDNA[] winningBeans, string saveFolder, bool startEmpty) { // Manually instantiate some of the properties that didn't get serialized options.DefaultBeanList = _defaultBeanList; if (options.NewBeanList == null) // if this was called by new, it will still be null { options.NewBeanList = new SortedList<string, ShipDNA>(); if (!startEmpty) { string[] beanKeys = options.DefaultBeanList.Keys.ToArray(); foreach (int keyIndex in UtilityCore.RandomRange(0, beanKeys.Length, Math.Min(3, beanKeys.Length))) // only do 3 of the defaults { string key = beanKeys[keyIndex]; options.NewBeanList.Add(key, options.DefaultBeanList[key]); } } } options.MutateArgs = PanelMutation.BuildMutateArgs(options); options.GravityField = new GravityFieldUniform(); options.Gravity = options.Gravity; // the property set modifies the gravity field options.WinnersLive = new WinnerList(true, options.TrackingMaxLineagesLive, options.TrackingMaxPerLineageLive); if (options.WinnersFinal == null) // if a previous save had winning ships, this will already be loaded with them { options.WinnersFinal = new WinnerList(false, options.TrackingMaxLineagesFinal, options.TrackingMaxPerLineageFinal); } options.WinnerCandidates = new CandidateWinners(); // These are already in the final list, there's no point in putting them in the candidate list as well //if (winningBeans != null) //{ // foreach (ShipDNA dna in winningBeans) // { // options.WinnerCandidates.Add(dna); // } //} // Make sure the session folder is up to date if (saveFolder == null) { this.SessionFolder = null; } else { string dirChar = Regex.Escape(System.IO.Path.DirectorySeparatorChar.ToString()); string pattern = dirChar + Regex.Escape(FlyingBeansWindow.SESSIONFOLDERPREFIX) + "[^" + dirChar + "]+(?<upto>" + dirChar + ")" + Regex.Escape(FlyingBeansWindow.SAVEFOLDERPREFIX); Match match = Regex.Match(saveFolder, pattern, RegexOptions.IgnoreCase); if (match.Success) { this.SessionFolder = saveFolder.Substring(0, match.Groups["upto"].Index); // the session folder is everything before the save subfolder } else { // They may have chosen a folder that they unziped onto their desktop, or wherever. Leaving this null so that if they hit save, it will be saved // in the appropriate location this.SessionFolder = null; } } // Swap out the settings this.Session = session; this.Options = options; this.ItemOptions = itemOptions; // Inform the world if (this.SessionChanged != null) { this.SessionChanged(this, new EventArgs()); } }
public static void Load(out FlyingBeanSession session, out FlyingBeanOptions options, out ItemOptions itemOptions, out ShipDNA[] winningBeans, string baseFolder, string saveFolder) { #region Session string filename = Path.Combine(baseFolder, FILENAME_SESSION); if (File.Exists(filename)) { session = UtilityCore.DeserializeFromFile <FlyingBeanSession>(filename); } else { session = new FlyingBeanSession(); } #endregion #region FlyingBeanOptions filename = Path.Combine(saveFolder, FILENAME_OPTIONS); if (File.Exists(filename)) { options = UtilityCore.DeserializeFromFile <FlyingBeanOptions>(filename); } else { //options = new FlyingBeanOptions(); throw new ArgumentException("Didn't find " + FILENAME_OPTIONS + "\r\n\r\nThe folder might not be a valid save folder"); } #endregion // This currently isn't stored to file session = new FlyingBeanSession(); #region ItemOptions filename = Path.Combine(saveFolder, FILENAME_ITEMOPTIONS); if (File.Exists(filename)) { itemOptions = UtilityCore.DeserializeFromFile <ItemOptions>(filename); } else { itemOptions = new ItemOptions(); } #endregion #region Winning Beans List <Tuple <string, ShipDNA> > winners = new List <Tuple <string, ShipDNA> >(); foreach (string filename2 in Directory.GetFiles(saveFolder)) { Match match = Regex.Match(Path.GetFileName(filename2), @"^(.+?( - )){2}(?<rank>\d+)\.xml$", RegexOptions.IgnoreCase); if (!match.Success) { continue; } // All other xml files should be winning beans ShipDNA dna = null; try { dna = UtilityCore.DeserializeFromFile <ShipDNA>(filename2); } catch (Exception) { // Must not be a ship continue; } winners.Add(Tuple.Create(Path.GetFileName(filename2), dna)); } winningBeans = winners.Select(o => o.Item2).ToArray(); #endregion // WinnersFinal options.WinnersFinal = MergeHistory(options.WinningScores, winners, options.TrackingMaxLineagesFinal, options.TrackingMaxPerLineageFinal); }
public PanelBeanProps(FlyingBeanOptions options, ItemOptions itemOptions) { InitializeComponent(); _options = options; _itemOptions = itemOptions; //PropertyInfo[] propsOptions = typeof(FlyingBeanOptions).GetProperties(); PropertyInfo[] propsItems = typeof(ItemOptions).GetProperties(); // Consumption _propLinks.Add(new SliderShowValues.PropSync(trkThrustForce, propsItems.Where(o => o.Name == "ThrusterStrengthRatio").First(), _itemOptions, 5, 100)); _propLinks.Add(new SliderShowValues.PropSync(trkFuelDraw, propsItems.Where(o => o.Name == "FuelToThrustRatio").First(), _itemOptions, .001d, 5)); _propLinks.Add(new SliderShowValues.PropSync(trkGravitySensorEnergyDraw, propsItems.Where(o => o.Name == "GravitySensorAmountToDraw").First(), _itemOptions, .1, 10)); _propLinks.Add(new SliderShowValues.PropSync(trkSpinSensorEnergyDraw, propsItems.Where(o => o.Name == "SpinSensorAmountToDraw").First(), _itemOptions, .1, 10)); _propLinks.Add(new SliderShowValues.PropSync(trkBrainEnergyDraw, propsItems.Where(o => o.Name == "BrainAmountToDraw").First(), _itemOptions, .1, 10)); // Neural _propLinks.Add(new SliderShowValues.PropSync(trkGravSensorNeuronDensity, propsItems.Where(o => o.Name == "GravitySensorNeuronDensity").First(), _itemOptions, 4, 60)); _propLinks.Add(new SliderShowValues.PropSync(trkBrainNeuronDensity, propsItems.Where(o => o.Name == "BrainNeuronDensity").First(), _itemOptions, 4, 60)); _propLinks.Add(new SliderShowValues.PropSync(trkBrainChemicalDensity, propsItems.Where(o => o.Name == "BrainChemicalDensity").First(), _itemOptions, 0, 10)); _propLinks.Add(new SliderShowValues.PropSync(trkBrainInternalLinks, propsItems.Where(o => o.Name == "BrainLinksPerNeuron_Internal").First(), _itemOptions, .5, 8)); _propLinks.Add(new SliderShowValues.PropSync(trkBrainExternalLinkSensor, propsItems.Where(o => o.Name == "BrainLinksPerNeuron_External_FromSensor").First(), _itemOptions, .1, 5)); _propLinks.Add(new SliderShowValues.PropSync(trkBrainExternalLinkBrain, propsItems.Where(o => o.Name == "BrainLinksPerNeuron_External_FromBrain").First(), _itemOptions, .1, 5)); _propLinks.Add(new SliderShowValues.PropSync(trkThrusterExternalLinkSensor, propsItems.Where(o => o.Name == "ThrusterLinksPerNeuron_Sensor").First(), _itemOptions, .1, 5)); _propLinks.Add(new SliderShowValues.PropSync(trkThrusterExternalLinkBrain, propsItems.Where(o => o.Name == "ThrusterLinksPerNeuron_Brain").First(), _itemOptions, .1, 5)); // Density _propLinks.Add(new SliderShowValues.PropSync(trkBrainDensity, propsItems.Where(o => o.Name == "BrainDensity").First(), _itemOptions, 1, 5000)); _propLinks.Add(new SliderShowValues.PropSync(trkGravSensorDensity, propsItems.Where(o => o.Name == "SensorDensity").First(), _itemOptions, 1, 5000)); _propLinks.Add(new SliderShowValues.PropSync(trkEnergyTankDensity, propsItems.Where(o => o.Name == "EnergyTankDensity").First(), _itemOptions, 1, 5000)); _propLinks.Add(new SliderShowValues.PropSync(trkFuelTankDensity, propsItems.Where(o => o.Name == "FuelTankWallDensity").First(), _itemOptions, 1, 5000)); _propLinks.Add(new SliderShowValues.PropSync(trkFuelDensity, propsItems.Where(o => o.Name == "FuelDensity").First(), _itemOptions, 1, 5000)); _propLinks.Add(new SliderShowValues.PropSync(trkThrusterDensity, propsItems.Where(o => o.Name == "ThrusterDensity").First(), _itemOptions, 1, 5000)); // TODO: this one should have a log scale //trkMomentOfInertia.Normalize_SliderToValue += //convert a linear to nonlinear //trkMomentOfInertia.Normalize_ValueToSlider += //convert a nonlinear to linear _propLinks.Add(new SliderShowValues.PropSync(trkMomentOfInertia, propsItems.Where(o => o.Name == "MomentOfInertiaMultiplier").First(), _itemOptions, .01, 10)); //TODO: When I start saving the options to file, also need to set the min/max from options (in case the user changed the range) //TODO: This is a lot of hard coding. Store the linkage between slider and property in a list, and just have one event listener for all sliders //trkThrustForce.Value = _itemOptions.ThrusterStrengthRatio; //trkFuelDraw.Minimum = .000000001; //trkFuelDraw.Maximum = .000005; //trkFuelDraw.Value = _itemOptions.FuelToThrustRatio; //trkSensorEnergyDraw.Value = _itemOptions.GravitySensorAmountToDraw; //trkBrainEnergyDraw.Value = _itemOptions.BrainAmountToDraw; //trkLifespan.Value = _options.MaxAgeSeconds; //trkAngularVelocity.Value = _options.AngularVelocityDeath; //trkGroundCollisions.Value = _options.MaxGroundCollisions; //trkGravSensorNeuronDensity.Value = _itemOptions.GravitySensorNeuronDensity; //trkBrainNeuronDensity.Value = _itemOptions.BrainNeuronDensity; //trkBrainChemicalDensity.Value = _itemOptions.BrainChemicalDensity; //trkBrainInternalLinks.Value = _itemOptions.BrainLinksPerNeuron_Internal; //trkBrainExternalLinkSensor.Value = _itemOptions.BrainLinksPerNeuron_External_FromSensor; //trkBrainExternalLinkBrain.Value = _itemOptions.BrainLinksPerNeuron_External_FromBrain; //trkThrusterExternalLinkSensor.Value = _itemOptions.ThrusterLinksPerNeuron_Sensor; //trkThrusterExternalLinkBrain.Value = _itemOptions.ThrusterLinksPerNeuron_Brain; //trkBrainDensity.Value = _itemOptions.BrainDensity; //trkGravSensorDensity.Value = _itemOptions.SensorDensity; //trkEnergyTankDensity.Value = _itemOptions.EnergyTankDensity; //trkFuelTankDensity.Value = _itemOptions.FuelTankWallDensity; //trkFuelDensity.Value = _itemOptions.FuelDensity; //trkThrusterDensity.Value = _itemOptions.ThrusterDensity; //trkMomentOfInertia.Value = _itemOptions.MomentOfInertiaMultiplier; _isInitialized = true; }
private void Window_Loaded(object sender, RoutedEventArgs e) { try { double terrainHeight = TERRAINRADIUS / 20d; #region Load last save _session = new FlyingBeanSession(); _options = new FlyingBeanOptions(); _itemOptions = new ItemOptions(); _panelFile = new PanelFile(null, _session, _options, _itemOptions, GetDefaultBeans()); _panelFile.SessionChanged += new EventHandler(PanelFile_SessionChanged); if (!_panelFile.TryLoadLastSave(false)) { _panelFile.New(false, false); // by calling new, all of the options initialization is done by the file panel instead of doing it here } #endregion #region Winners _winnerManager = new WinnerManager(_options.WinnersLive, _options.WinnerCandidates, _options.WinnersFinal, _options.FinalistCount); #endregion #region Init World double boundryXY = TERRAINRADIUS * 1.25d; _boundryMin = new Point3D(-boundryXY, -boundryXY, terrainHeight * -2d); _boundryMax = new Point3D(boundryXY, boundryXY, TERRAINRADIUS * 25d); _world = new World(); _world.Updating += new EventHandler<WorldUpdatingArgs>(World_Updating); List<Point3D[]> innerLines, outerLines; _world.SetCollisionBoundry(out innerLines, out outerLines, _boundryMin, _boundryMax); // Draw the lines _boundryLines = new ScreenSpaceLines3D(true) { Thickness = 1d, Color = _colors.BoundryLines, }; _viewport.Children.Add(_boundryLines); foreach (Point3D[] line in innerLines) { _boundryLines.AddLine(line[0], line[1]); } #endregion #region Materials _materialManager = new MaterialManager(_world); // Terrain Game.Newt.v2.NewtonDynamics.Material material = new Game.Newt.v2.NewtonDynamics.Material(); material.Elasticity = .1d; _material_Terrain = _materialManager.AddMaterial(material); // Bean material = new Game.Newt.v2.NewtonDynamics.Material(); _material_Bean = _materialManager.AddMaterial(material); // Exploding Bean material = new Game.Newt.v2.NewtonDynamics.Material(); material.IsCollidable = false; _material_ExplodingBean = _materialManager.AddMaterial(material); // Projectile material = new Game.Newt.v2.NewtonDynamics.Material(); _material_Projectile = _materialManager.AddMaterial(material); _materialManager.RegisterCollisionEvent(0, _material_Bean, Collision_BeanTerrain); // zero should be the boundry (it should be the default material if no other is applied) _materialManager.RegisterCollisionEvent(_material_Terrain, _material_Bean, Collision_BeanTerrain); _materialManager.RegisterCollisionEvent(_material_Bean, _material_Bean, Collision_BeanBean); #endregion #region Trackball // Trackball _trackball = new TrackBallRoam(_camera); _trackball.KeyPanScale = 15d; _trackball.EventSource = grdViewPort; //NOTE: If this control doesn't have a background color set, the trackball won't see events (I think transparent is ok, just not null) _trackball.AllowZoomOnMouseWheel = true; _trackball.Mappings.AddRange(TrackBallMapping.GetPrebuilt(TrackBallMapping.PrebuiltMapping.MouseComplete_NoLeft)); _trackball.Mappings.AddRange(TrackBallMapping.GetPrebuilt(TrackBallMapping.PrebuiltMapping.Keyboard_ASDW_In)); _trackball.ShouldHitTestOnOrbit = true; _trackball.UserMovedCamera += new EventHandler<UserMovedCameraArgs>(Trackball_UserMovedCamera); _trackball.GetOrbitRadius += new EventHandler<GetOrbitRadiusArgs>(Trackball_GetOrbitRadius); #endregion #region Map _map = new Map(_viewport, null, _world) { SnapshotFequency_Milliseconds = 125, SnapshotMaxItemsPerNode = 10, ShouldBuildSnapshots = false, ShouldShowSnapshotLines = false, ShouldSnapshotCentersDrift = true, }; _updateManager = new UpdateManager( new Type[] { typeof(Bean) }, new Type[] { typeof(Bean) }, _map); #endregion #region Terrain //TODO: Texture map this so it's not so boring #region WPF Model (plus collision hull) // Material MaterialGroup materials = new MaterialGroup(); materials.Children.Add(new DiffuseMaterial(new SolidColorBrush(_colors.Terrain))); materials.Children.Add(_colors.TerrainSpecular); // Geometry Model GeometryModel3D geometry = new GeometryModel3D(); geometry.Material = materials; geometry.BackMaterial = materials; geometry.Geometry = UtilityWPF.GetCylinder_AlongX(100, TERRAINRADIUS, terrainHeight); CollisionHull hull = CollisionHull.CreateCylinder(_world, 0, TERRAINRADIUS, terrainHeight, null); // Transform Transform3DGroup transform = new Transform3DGroup(); // rotate needs to be added before translate transform.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), -90))); transform.Children.Add(new TranslateTransform3D(new Vector3D(0, 0, terrainHeight / -2d))); // I want the objects to be able to add to z=0 // Model Visual ModelVisual3D model = new ModelVisual3D(); model.Content = geometry; model.Transform = transform; // Add to the viewport _viewport.Children.Add(model); #endregion // Make a physics body that represents this shape _terrain = new Body(hull, transform.Value, 0, new Visual3D[] { model }); // using zero mass tells newton it's static scenery (stuff bounces off of it, but it will never move) hull.Dispose(); _terrain.MaterialGroupID = _material_Terrain; #endregion #region Fields // gravity was done by the file panel _radiation = new RadiationField() { AmbientRadiation = 0d, }; _boundryField = new BoundryField(.5d, 7500d, 2d, _boundryMin, _boundryMax); #endregion // Doing this so that if they hit the import button, it will call a method in beantypes (not the best design, but it works) _panelBeanTypes = new PanelBeanTypes(_options, _world); _panelFile.BeanTypesPanel = _panelBeanTypes; this.TotalBeansText = _options.TotalBeans.ToString("N0"); _world.UnPause(); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void PanelFile_SessionChanged(object sender, EventArgs e) { try { //NOTE: This method has many statements, and isn't very threadsafe, but even if there were several threads hitting these options there shouldn't //be any damage with the panels being momentarily out of sync // Kill all current if (_selectedBean != null && _selectedBean.Viewer != null) { _selectedBean.Viewer.Close(); } _selectedBean = null; foreach (Bean bean in _beans.ToArray()) // using toarray, because DisposeBean removes from the list { DisposeBean(bean); } foreach (ExplodingBean explosion in _explosions.ToArray()) { DisposeExplosion(explosion); } // Get the new session _session = _panelFile.Session; _options = _panelFile.Options; _itemOptions = _panelFile.ItemOptions; #region Refresh options panels if (_panelBeanTypes != null) { _panelBeanTypes.Options = _options; } if (_panelBeanProps != null) { _panelBeanProps.Options = _options; _panelBeanProps.ItemOptions = _itemOptions; } if (_panelMutation != null) { _panelMutation.Options = _options; } if (_panelTracking != null) { _panelTracking.Options = _options; } if (_panelSimulation != null) { _panelSimulation.Options = _options; } #endregion // Refresh winner manager if (_winnerManager != null) { _winnerManager.Live = _options.WinnersLive; _winnerManager.Candidates = _options.WinnerCandidates; _winnerManager.Final = _options.WinnersFinal; } RefreshStats(); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void FinishLoad(FlyingBeanSession session, FlyingBeanOptions options, ItemOptions itemOptions, ShipDNA[] winningBeans, string saveFolder, bool startEmpty) { // Manually instantiate some of the properties that didn't get serialized options.DefaultBeanList = _defaultBeanList; if (options.NewBeanList == null) // if this was called by new, it will still be null { options.NewBeanList = new SortedList <string, ShipDNA>(); if (!startEmpty) { string[] beanKeys = options.DefaultBeanList.Keys.ToArray(); foreach (int keyIndex in UtilityCore.RandomRange(0, beanKeys.Length, Math.Min(3, beanKeys.Length))) // only do 3 of the defaults { string key = beanKeys[keyIndex]; options.NewBeanList.Add(key, options.DefaultBeanList[key]); } } } options.MutateArgs = PanelMutation.BuildMutateArgs(options); options.GravityField = new GravityFieldUniform(); options.Gravity = options.Gravity; // the property set modifies the gravity field options.WinnersLive = new WinnerList(true, options.TrackingMaxLineagesLive, options.TrackingMaxPerLineageLive); if (options.WinnersFinal == null) // if a previous save had winning ships, this will already be loaded with them { options.WinnersFinal = new WinnerList(false, options.TrackingMaxLineagesFinal, options.TrackingMaxPerLineageFinal); } options.WinnerCandidates = new CandidateWinners(); // These are already in the final list, there's no point in putting them in the candidate list as well //if (winningBeans != null) //{ // foreach (ShipDNA dna in winningBeans) // { // options.WinnerCandidates.Add(dna); // } //} // Make sure the session folder is up to date if (saveFolder == null) { this.SessionFolder = null; } else { string dirChar = Regex.Escape(System.IO.Path.DirectorySeparatorChar.ToString()); string pattern = dirChar + Regex.Escape(FlyingBeansWindow.SESSIONFOLDERPREFIX) + "[^" + dirChar + "]+(?<upto>" + dirChar + ")" + Regex.Escape(FlyingBeansWindow.SAVEFOLDERPREFIX); Match match = Regex.Match(saveFolder, pattern, RegexOptions.IgnoreCase); if (match.Success) { this.SessionFolder = saveFolder.Substring(0, match.Groups["upto"].Index); // the session folder is everything before the save subfolder } else { // They may have chosen a folder that they unziped onto their desktop, or wherever. Leaving this null so that if they hit save, it will be saved // in the appropriate location this.SessionFolder = null; } } // Swap out the settings this.Session = session; this.Options = options; this.ItemOptions = itemOptions; // Inform the world if (this.SessionChanged != null) { this.SessionChanged(this, new EventArgs()); } }