Example #1
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 #2
0
 public ControlMarker(Interface.Struct.ControlMarker other)
 {
     BirthRound = other.birthRound;
     Location   = new Technite.CompressedLocation(other.location).CellID;
     Radius     = other.radius;
     TypeIndex  = other.typeIndex;
 }
Example #3
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 #4
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 #5
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 #6
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 #7
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 #8
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 #9
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 #10
0
 protected /**/ Technite(Grid.CellID loc)
 {
     Location = loc;
 }
Example #11
0
		protected /**/				Technite(Grid.CellID loc)
		{
			Location = loc;
		}
Example #12
0
 public ObjectID(Interface.Struct.GameObjectID id) : this()
 {
     Location = new Technite.CompressedLocation(id.location).CellID;
     IsGhost  = id.isGhost;
     Type     = id.type;
 }
Example #13
0
				public ObjectID(Interface.Struct.GameObjectID id) : this()
				{
					Location = new Technite.CompressedLocation(id.location).CellID;
					IsGhost = id.isGhost;
					Type = id.type;
				}
Example #14
0
			public ControlMarker(Interface.Struct.ControlMarker other)
			{
				BirthRound = other.birthRound;
				Location = new Technite.CompressedLocation(other.location).CellID;
				Radius = other.radius;
				TypeIndex = other.typeIndex;
			}