Ejemplo n.º 1
0
        public bool ExecuteMotion(ref EntityLogic.Actions actions, Entity currentState, int generation, EntityRandom random, float myYield, ref int spawn)
        {
            bool rs = false;

            switch (generation % 3)
            {
            case 0:
                //receive unicast, send broadcast
                if (animal == null)
                {
                    foreach (var msg in currentState.EnumInboundEntityMessages(channel))
                    {
                        if (!msg.IsBroadcast)                                 //coming around
                        {
                            if (animal != null)
                            {
                                throw new ExecutionException(currentState.ID, "Trying to import multiple animals");
                            }
                            animal = new Animal(msg.Payload);
                            rs     = true;
                        }
                    }
                }

                if (animal != null)
                {
                    actions.Broadcast(channel, null);                               //can i go there?
                }
                break;

            case 1:
                //receive broadcast, send unicast
                if (animal == null)
                {
                    LazyList <Actor> competitors = new LazyList <Actor>();
                    foreach (var msg in currentState.EnumInboundEntityMessages(channel))
                    {
                        if (msg.IsBroadcast && msg.Payload == null)                                 //can i go here?
                        {
                            competitors.Add(msg.Sender);
                        }
                    }
                    if (competitors.IsNotEmpty)
                    {
                        actions.Send(competitors[random.Next(competitors.Count)], channel, BitConverter.GetBytes(myYield));                                 //you can go here
                    }
                }
                break;

            case 2:
                //receive unicast, send unicast
                if (animal != null)
                {
                    LazyList <Tuple <Actor, float> > options = new LazyList <Tuple <Actor, float> >();
                    foreach (var msg in currentState.EnumInboundEntityMessages(channel))
                    {
                        if (!msg.IsBroadcast && Helper.Length(msg.Payload) == 4)                                 //i can go there
                        {
                            options.Add(new Tuple <Actor, float>(msg.Sender, BitConverter.ToSingle(msg.Payload, 0)));
                        }
                    }
                    options.Sort((a, b) => { return(a.Item2.CompareTo(b.Item2)); });
                    if (options.IsNotEmpty)
                    {
                        if (spawn > 0)
                        {
                            foreach (var o in options)
                            {
                                actions.Send(o.Item1, channel, new Animal(0).Export());                                         //coming around
                                if (--spawn <= 0)
                                {
                                    break;
                                }
                            }
                            spawn = 0;
                        }
                        else
                        {
                            actions.Send(options.Last.Item1, channel, animal.Export()); //coming around
                        }
                        animal = null;                                                  //in transit
                    }
                }
                break;
            }

            return(rs);
        }
Ejemplo n.º 2
0
        public List <EntityError> Evolve(IReadOnlyList <Entity> entities,
                                         Dictionary <Guid, ClientMessage[]> clientMessages,
                                         InconsistencyCoverage ic,
                                         TimeSpan budget,
                                         EntityChange.ExecutionContext ctx)
        {
            if (ic.Size != InconsistencyCoverage.CommonResolution)
            {
                throw new IntegrityViolation("Trying to evolve with an IC of size " + ic.Size + ". Should be " + InconsistencyCoverage.CommonResolution);
            }
            int numErrors = 0;

            List <Task>             tasks  = new List <Task>();
            List <Entity.TimeTrace> tables = new List <Entity.TimeTrace>();

            ClientMessage[] clientBroadcasts = null;
            if (clientMessages != null)
            {
                clientMessages.TryGetValue(Guid.Empty, out clientBroadcasts);
            }
            Stopwatch watch0 = new Stopwatch();

            object lazyLock = new object();
            bool   exceeded = false;
            var    rs       = new LazyList <EntityError>();

            Parallel.For(0, entities.Count, i =>
            {
                Entity e = entities[i];
                ClientMessage[] messages = null;
                if (clientMessages != null)
                {
                    clientMessages.TryGetValue(e.ID.Guid, out messages);
                }
                var t = new Entity.TimeTrace(watch0);

                //tables.Add(t);


                EntityLogic st = null;

                try
                {
                    if (!exceeded)
                    {
                        st = e.Evolve(t, this, Helper.Concat(clientBroadcasts, messages), ctx, ic.IsInconsistentR(ctx.LocalSpace.Relativate(e.ID.Position)));
                        if (e.transientDeserializedLogic != null)
                        {
                            throw new IntegrityViolation("Transient deserialized logic was not wiped");
                        }
                    }
                    if (exceeded || watch0.Elapsed > budget)
                    {
                        exceeded = true;
                        throw new TimeBudgetException(budget, t);
                    }
                }
                catch (AssertFailedException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    if (st == null)
                    {
                        st = (EntityLogic)Helper.Deserialize(e.SerialLogicState);
                    }
                    var error = new EntityError(e, st, ex);
                    lock (lazyLock)
                        rs.Add(error);
                    ic.FlagInconsistentR(ctx.LocalSpace.Relativate(e.ID.Position));
                    Interlocked.Increment(ref numErrors);
                }
            });

/*
 *
 *                      watch0.Start();
 *                      foreach (var e in entities)
 *                      {
 *                              EntityMessage[] messages = null;
 *                              if (clientMessages != null)
 *                              {
 *                                      clientMessages.TryGetValue(e.ID.Guid, out messages);
 *                              }
 *                              var t = new Entity.TimeTrace(watch0);
 *                              tables.Add(t);
 *                              tasks.Add(e.EvolveAsync(t,this, roundNumber, maySendMessages,Helper.Concat(clientBroadcasts, messages)));
 *                      }
 *                      int at = 0;
 *
 *                      Stopwatch watch = new Stopwatch();
 *                      watch.Start();
 *
 *                      LazyList<EntityEvolutionException> rs = new LazyList<EntityEvolutionException>();
 *
 *                      foreach (var e in entities)
 *                      {
 *                              try
 *                              {
 *                                      var remaining = (budget - watch.Elapsed).NotNegative();
 *                                      if (!tasks[at].Wait( remaining))
 *                                              throw new ExecutionException(e.ID, "Failed to execute " + (EntityLogic)Helper.Deserialize(e.SerialLogicState)+" in "+remaining.TotalMilliseconds+" ms");
 *                              }
 *                              catch (Exception ex)
 *                              {
 *                                      rs.Add(new EntityEvolutionException(e, ex, tables[at]));
 *
 *                                      ic.FlagInconsistentR(Simulation.MySpace.Relativate(e.ID.Position));
 *
 *                                      Interlocked.Increment(ref numErrors);
 *                              }
 *                              at++;
 *                      }*/

            return(rs.InternalList);
        }