Example #1
0
			/// <summary>
			/// Evaluates all possible neighbor cells. The return values of <paramref name="f"/> are used as probability multipliers 
			/// to chose a random a option.
			/// Currently not thread-safe
			/// </summary>
			/// <param name="location">Location to evaluate the neighborhood of</param>
			/// <param name="f">Evaluation function. Must return 0/NotAChoice if not applicable, and >1 otherwise. Higher values indicate higher probability</param>
			/// <returns>Chocen relative cell, or Grid.RelativeCell.Invalid if none was found.</returns>
			public static Grid.RelativeCell EvaluateChoices(Grid.CellID location, Func<Grid.RelativeCell, Grid.CellID, int> f)
			{
				options.Clear();
				int total = 0;
				foreach (var n in location.GetRelativeNeighbors())
				{
					Grid.CellID cellLocation = location + n;
					int q = f(n, cellLocation);
					if (q > 0)
					{
						total += q;
						options.Add(new KeyValuePair<int, Grid.RelativeCell>(q, n));
					}
				}
				if (total == 0)
					return Grid.RelativeCell.Invalid;
				if (options.Count == 1)
					return options[0].Value;
				int c = random.Next(total);
				foreach (var o in options)
				{
					if (c <= o.Key)
						return o.Value;
					c -= o.Key;
				}
				Out.Log(Significance.ProgramFatal, "Logic error");
				return Grid.RelativeCell.Invalid;
			}
Example #2
0
			/// <summary>
			/// Determines a feasible, possibly ideal neighbor technite target, based on a given evaluation function
			/// </summary>
			/// <param name="location"></param>
			/// <param name="f">Evaluation function. Must return 0/NotAChoice if not applicable, and >1 otherwise. Higher values indicate higher probability</param>
			/// <returns>Chocen relative cell, or Grid.RelativeCell.Invalid if none was found.</returns>
			public static Grid.RelativeCell EvaluateNeighborTechnites(Grid.CellID location, Func<Grid.RelativeCell, Technite, int> f)
			{
				return EvaluateChoices(location, (relative, cell) =>
				{
					Grid.Content content = Grid.World.GetCell(cell).content;
					if (content != Grid.Content.Technite)
						return NotAChoice;
					Technite other = Technite.Find(cell);
					if (other == null)
					{
						Out.Log(Significance.Unusual, "Located neighboring technite in " + cell + ", but cannot find reference to class instance");
						return NotAChoice;
					}
					return f(relative,other);
				}
				);			
			}
Example #3
0
			/// <summary>
			/// Determines a feasible, possibly ideal technite neighbor cell that is at the very least on the same height level.
			/// Higher and/or lit neighbor technites are favored
			/// </summary>
			/// <param name="location"></param>
			/// <returns></returns>
			public static Grid.RelativeCell GetLitOrUpperTechnite(Grid.CellID location)
			{
				return EvaluateNeighborTechnites(location, (relative, technite) =>
				{
					int rs = 0;
					if (technite.Status.Lit)
						rs++;
					rs += relative.HeightDelta;
					return rs;
				});
			}
Example #4
0
			/// <summary>
			/// Determines a food source in the neighborhood of the specified location
			/// </summary>
			/// <param name="location"></param>
			/// <returns></returns>
			public static Grid.RelativeCell GetFoodChoice(Grid.CellID location)
			{
				return EvaluateChoices(location, (relative, cell) =>
				{
					Grid.Content content = Grid.World.GetCell(cell).content;
					int yield = Technite.MatterYield[(int)content];	//zero is zero, no exceptions
					if (Grid.World.GetCell(cell.BottomNeighbor).content != Grid.Content.Technite)
						return yield;
					return NotAChoice;
				}
				);
			}
Example #5
0
			/// <summary>
			/// Determines a feasible neighborhood cell that can work as a replication destination.
			/// </summary>
			/// <param name="location"></param>
			/// <returns></returns>
			public static Grid.RelativeCell GetSplitTarget(Grid.CellID location)
			{
				return EvaluateChoices(location, (relative, cell) =>
				{
					Grid.Content content = Grid.World.GetCell(cell).content;
					int rs = 100;
					if (content != Grid.Content.Clear && content != Grid.Content.Water)
						rs -= 90;
					if (Grid.World.GetCell(cell.TopNeighbor).content == Grid.Content.Technite)
						return NotAChoice;  //probably a bad idea to split beneath technite

					if (Technite.EnoughSupportHere(cell))
						return relative.HeightDelta + rs;

					return NotAChoice;
				}
				);
			}
Example #6
0
 public static Grid.RelativeCell EvaluateYieldChoices(Grid.CellID location, Func<Grid.RelativeCell, Grid.CellID, int> f)
 {
     options.Clear();
     foreach (var n in location.GetRelativeNeighbors())
     {
         Grid.CellID cellLocation = location + n;
         int q = f(n, cellLocation);
         if (q > 0)
         {
             options.Add(new KeyValuePair<int, Grid.RelativeCell>(q, n));
         }
     }
     if (options.Count == 0)
     {
         //Out.Log(Significance.ProgramFatal, "Logic error");
         return Grid.RelativeCell.Invalid;
     }
     if (options.Count == 1)
         return options[0].Value;
     int maxYield = 0;
     Grid.RelativeCell maxOption = Grid.RelativeCell.Invalid;
     foreach (var o in options)
     {
        if(maxYield <= o.Key)
        {
            maxYield = o.Key;
            maxOption = o.Value;
        }
     }
     return maxOption;
     //else
     //{
     //    Out.Log(Significance.ProgramFatal, "Logic error");
     //    return Grid.RelativeCell.Invalid;
     //}
 }
Example #7
0
            public static Grid.RelativeCell GetValleyTarget(Grid.CellID location)
            {
                return EvaluateValleyChoices(location, (relative, cell) =>
                {
                    //Grid.Content content = Grid.World.GetCell(cell).content;
                    //int rs = 100;
                    //if (content != Grid.Content.Clear && content != Grid.Content.Water)
                    //    rs -= 90;
                    //if (Grid.World.GetCell(cell.TopNeighbor).content == Grid.Content.Technite)
                    //    return NotAChoice;  //probably a bad idea to split beneath technite

                    //if (Technite.EnoughSupportHere(cell))
                    //    return relative.HeightDelta + rs;

                    if (Grid.World.GetCell(cell).content == Grid.Content.Clear)
                    {
                        if (Grid.World.GetCell(cell.BottomNeighbor).content != Grid.Content.Technite)
                        {
                            if (Technite.EnoughSupportHere(cell))
                                return 1;
                        }
                    }

                    return NotAChoice;
                }
                );
            }
Example #8
0
		internal static bool EnoughSupportHere(Grid.CellID cell)
		{
			if (Grid.IsSolid(cell.BottomNeighbor.BottomNeighbor))
				return true;
			foreach (var n0 in cell.GetHorizontalNeighbors())
				if (Grid.IsSolid(n0) && Grid.IsSolid(n0.BottomNeighbor))
					return true;
			return false;
		}
Example #9
0
 public static Grid.RelativeCell EvaluateValleyChoices(Grid.CellID location, Func<Grid.RelativeCell, Grid.CellID, int> f)
 {
     //suche höhergelegene leere Zelle über Matter
     options.Clear();
     int total = 0;
     foreach (var n in location.GetRelativeEqualOrLowerNeighbors())  //GetRelativeUpperNeighbors effizienter
     {
         Grid.CellID cellLocation = location + n;
         if (cellLocation.Layer <= location.Layer)
         {
             int q = f(n, cellLocation);
             if (q > 0)
             {
                 total += q;
                 options.Add(new KeyValuePair<int, Grid.RelativeCell>(q, n));
             }
         }
     }
     if (total == 0)
         return Grid.RelativeCell.Invalid;
     if (options.Count == 1)
         return options[0].Value;
     int c = random.Next(total);
     return options[c].Value;
     //Out.Log(Significance.ProgramFatal, "Logic error");
     //return Grid.RelativeCell.Invalid;
 }
Example #10
0
		protected /**/				Technite(Grid.CellID loc)
		{
			Location = loc;
		}
Example #11
0
		/// <summary>
		/// Updates the next task to execute. Technites can memorize and execute only one task per round, thus the logic
		/// must redefine this task each round. If the last task result is TaskResult.MoreWorkNeeded, then  the last task 
		/// is not cleared automatically, but can be redefined if desired.
		/// Calling the method several times on the same technite before a new round is processed will overwrite the previously set task.
		/// Calling SetNextTask() at all is optional. The technite will sooner or later default to not doing anything in this case.
		/// </summary>
		/// <param name="t">Task to execute next</param>
		/// <param name="target">Location target of the task</param>
		/// <param name="parameter">Task parameter. What the parameter does depends on the task executed.</param>
		public void SetNextTask(Task t, Grid.RelativeCell target, byte parameter = 0)
		{
			//Out.Log(Significance.Low, this + "->" + t + " @" + target);
			Grid.CellID absoluteTarget = Location + target;
			if (!absoluteTarget.IsValid)
				throw new TaskException(this,"Trying to set invalid relative target "+target+". Task not set.");

			if (t == Task.SelfTransformToType)
			{
				if (parameter > MatterYield.Length)
					throw new TaskException(this,"Parameter for task "+t+" ("+parameter+") is not a valid matter type.");
				if (MatterYield[parameter] == 0)
					throw new TaskException(this,"Parameter for task " + t + " (" + parameter + "/"+((Grid.Content)parameter) + ") is not a suitable transformation output.");
			}
			else
			if ((t == Task.TransferEnergyTo || t == Task.TransferMatterTo) && parameter == 0)
				throw new TaskException(this, "Task "+t+" requires a non-zero parameter value");

			Grid.Content content = Grid.World.CellStacks[absoluteTarget.StackID].volumeCell[absoluteTarget.Layer].content;
			nextTask = t;
			taskParameter = parameter;
			taskTarget = target;
		}
Example #12
0
			public CompressedTarget(Grid.RelativeCell target)
			{
				Data = (byte)((byte)target.NeighborIndex | (byte)((target.HeightDelta + 1) << 4));
			}
Example #13
0
		/// <summary>
		/// Attempts to a find a technite based on its location.
		/// Hashtable lookup is used to quickly locate the technite.
		/// </summary>
		/// <param name="location">Location to look at</param>
		/// <returns>Technite reference, if a technite was found in the given location, null otherwise</returns>
		public static Technite Find(Grid.CellID location)
		{
			Technite rs;
			if (map.TryGetValue(location, out rs))
				return rs;
			return null;
		}
Example #14
0
 public CompressedLocation(Grid.CellID id)
 {
     Data = (uint)(((uint)id.Layer & 0xFF) | (id.StackID << 8));
 }