Ejemplo n.º 1
0
        private Enlistment EnlistVolatileInternal(
            IEnlistmentNotification notification,
            EnlistmentOptions options)
        {
            EnsureIncompleteCurrentScope();
            /* FIXME: Handle options.EnlistDuringPrepareRequired */
            Volatiles.Add(notification);

            /* FIXME: Enlistment.. ? */
            return(new Enlistment());
        }
        protected T CreateNewInstance(IMap <string, INode> childNodes, IStateTreeNode meta)
        {
            var observables = Mutables.Select(mutable => new ObservableProperty {
                Type = mutable.Kind, Name = mutable.Name, Default = mutable.Default
            }).ToList();

            var volatiles = Volatiles.Select(xvolatile => new Observable.VolatileProperty {
                Type = xvolatile.Kind, Name = xvolatile.Name, Default = xvolatile.Default
            }).ToList();

            var computeds = Views.Select(view => new ComputedProperty {
                Type = view.Kind, Name = view.Name, Compute = view.View
            }).ToList();

            // var actions = Actions.Select(action => new ActionMethod { Name = action.Name, Action = action.Action });

            ObservableTypeDef typeDef = new ObservableTypeDef(observables, volatiles, computeds);

            var instance = ObservableObject <T, INode> .FromAs(typeDef, Proxify, Name, this, meta);

            return(instance);
        }
Ejemplo n.º 3
0
        private void MoveBot(TBot bot, CoordDiff diff, Volatiles volatiles)
        {
            if (EnableValidation)
            {
                var miniDiff = new CoordDiff(Math.Sign(diff.Dx), Math.Sign(diff.Dy), Math.Sign(diff.Dz));
                var current  = bot.Coord;
                var end      = bot.Coord;
                end.Apply(diff);
                while (!current.Equals(end))
                {
                    volatiles.Update(current, bot);
                    current.Apply(miniDiff);
                    if (this[current])
                    {
                        throw new InvalidStateException($"Coord {current} is occupied when moving bot {bot.Bid}");
                    }
                }

                volatiles.Update(end, bot);
            }

            bot.Coord.Apply(diff);
        }
Ejemplo n.º 4
0
        private void Fuse(Dictionary <int, CoordDiff> fusionPrimaries, Dictionary <int, CoordDiff> fusionSecondaries, Volatiles volatiles)
        {
            if (fusionPrimaries.Count != fusionSecondaries.Count)
            {
                throw new InvalidStateException(
                          $"Fusion count mismatch: {fusionPrimaries.Count} primaries, {fusionSecondaries.Count} secondaries");
            }

            foreach (var(primaryIdx, ndP) in fusionPrimaries)
            {
                var prim           = Bots[primaryIdx];
                var primaryCoord   = prim.Coord;
                var secondaryCoord = primaryCoord;
                secondaryCoord.Apply(ndP);

                bool foundSecondary = false;
                foreach (var(secondaryIdx, ndS) in fusionSecondaries)
                {
                    var sec = Bots[secondaryIdx];
                    if (sec != null && sec.Coord.Equals(secondaryCoord))
                    {
                        var sanityCheckCoord = sec.Coord;
                        sanityCheckCoord.Apply(ndS);
                        if (!sanityCheckCoord.Equals(primaryCoord))
                        {
                            throw new InvalidStateException($"Fusion coord mismatch: {sanityCheckCoord} vs. {primaryCoord}");
                        }

                        prim.Seeds.Add(sec.Bid);
                        prim.Seeds.AddRange(sec.Seeds);
                        prim.Seeds.Sort();

                        volatiles.Update(prim.Coord, prim);
                        volatiles.Update(sec.Coord, sec);

                        Bots[secondaryIdx] = null;

                        Energy -= 24;

                        foundSecondary = true;
                        break;
                    }
                }

                if (!foundSecondary)
                {
                    throw new InvalidStateException($"no secondary bot at {secondaryCoord} for bot {prim.Bid} at {primaryCoord}");
                }
            }

            Bots = Bots.Where(x => x != null).ToList();
        }
Ejemplo n.º 5
0
        public void Step(TCommandsReader commands)
        {
            if (Harmonics == EHarmonics.Low)
            {
                Energy += 3 * Model.R * Model.R * Model.R;
            }
            else if (Harmonics == EHarmonics.High)
            {
                Energy += 30 * Model.R * Model.R * Model.R;
            }

            Energy += 20 * Bots.Count;

            var botsCount         = Bots.Count;
            var fusionPrimaries   = new Dictionary <int, CoordDiff>();
            var fusionSecondaries = new Dictionary <int, CoordDiff>();
            var volatiles         = new Volatiles(EnableValidation);

            for (var botIdx = 0; botIdx < botsCount; ++botIdx)
            {
                var command = commands.GetCommand(botIdx);
                var bot     = Bots[botIdx];

                switch (command)
                {
                case Halt halt:
                {
                    volatiles.Update(bot.Coord, bot);
                    break;
                }

                case Wait wait:
                {
                    volatiles.Update(bot.Coord, bot);
                    break;
                }

                case Flip flip:
                {
                    volatiles.Update(bot.Coord, bot);
                    if (Harmonics == EHarmonics.High)
                    {
                        Harmonics = EHarmonics.Low;
                    }
                    else
                    {
                        Harmonics = EHarmonics.High;
                    }

                    break;
                }

                case StraightMove move:
                {
                    MoveBot(bot, move.Diff, volatiles);
                    Energy += 2 * move.Diff.MLen();
                    break;
                }

                case LMove lMove:
                {
                    MoveBot(bot, lMove.Diff1, volatiles);
                    MoveBot(bot, lMove.Diff2, volatiles);

                    Energy += 2 * (lMove.Diff1.MLen() + 2 + lMove.Diff2.MLen());

                    break;
                }

                case Fission fission:
                {
                    bot.Seeds.Sort();

                    var newBot = new TBot {
                        Bid = bot.Seeds[0]
                    };

                    for (var i = 1; i <= fission.M; ++i)
                    {
                        newBot.Seeds.Add(bot.Seeds[i]);
                    }

                    bot.Seeds.RemoveRange(0, fission.M + 1);

                    newBot.Coord = bot.Coord;
                    newBot.Coord.Apply(fission.Diff);

                    volatiles.Update(bot.Coord, bot);
                    volatiles.Update(newBot.Coord, newBot);

                    Bots.Add(newBot);
                    Energy += 24;

                    break;
                }

                case Fill fill:
                {
                    var newCoord = bot.Coord;
                    newCoord.Apply(fill.Diff);

                    volatiles.Update(bot.Coord, bot);
                    volatiles.Update(newCoord, bot);

                    if (Matrix[newCoord.X, newCoord.Y, newCoord.Z] > 0)
                    {
                        Energy += 6;
                    }
                    else
                    {
                        Matrix[newCoord.X, newCoord.Y, newCoord.Z] = 1;
                        if (EnableValidation)
                        {
                            if (Harmonics == EHarmonics.Low && !IsGrounded(newCoord, new HashSet <TCoord>()))
                            {
                                throw new InvalidStateException($"{newCoord} is not grounded");
                            }
                        }

                        Energy += 12;
                    }

                    break;
                }

                case Void @void:
                {
                    var newCoord = bot.Coord;
                    newCoord.Apply(@void.Diff);

                    volatiles.Update(bot.Coord, bot);
                    volatiles.Update(newCoord, bot);

                    if (Matrix[newCoord.X, newCoord.Y, newCoord.Z] > 0)
                    {
                        Matrix[newCoord.X, newCoord.Y, newCoord.Z] = 0;
                        Energy -= 12;
                    }
                    else
                    {
                        Energy += 3;
                    }

                    break;
                }

                case FusionP fusionP:
                {
                    fusionPrimaries.Add(botIdx, fusionP.Diff);
                    break;
                }

                case FusionS fusionS:
                {
                    fusionSecondaries.Add(botIdx, fusionS.Diff);
                    break;
                }

                default: throw new InvalidStateException($"unknown item type {command}");
                }
            }

            if (fusionPrimaries.Count > 0)
            {
                Fuse(fusionPrimaries, fusionSecondaries, volatiles);
            }

            SortBots();

            commands.Advance(botsCount);
        }