Пример #1
0
        public TState(TModel model, bool enableValidation = false)
        {
            Model            = model;
            EnableValidation = enableValidation;
            Matrix           = new int[Model.R, Model.R, Model.R];

            var bot = new TBot
            {
                Bid   = 1,
                Coord =
                {
                    X = 0,
                    Y = 0,
                    Z = 0
                }
            };

            for (var i = 2; i <= 40; ++i)
            {
                bot.Seeds.Add(i);
            }

            Bots.Add(bot);

            Energy    = 0;
            Harmonics = EHarmonics.Low;
        }
Пример #2
0
        public List <ICommand> MakeTrace(TModel src, TModel model)
        {
            if (src.NumFilled != 0)
            {
                return(null);
            }

            EHarmonics curHarmonics = EHarmonics.Low;

            List <ICommand> result = new List <ICommand>();

            TCoord current = new TCoord();
            TBetterCubeTraverse betterCureTraverse = new TBetterCubeTraverse(model);

            int iteration = 0;

            while (iteration == 0 || !current.IsAtStart())
            {
                TCoord       next = betterCureTraverse.Next(model);
                StraightMove move = new StraightMove();
                move.Diff = betterCureTraverse.GetDirection();
                result.Add(move);

                if (next.Y > 0 && model[next.X, next.Y - 1, next.Z] > 0)
                {
                    if (curHarmonics == EHarmonics.Low)
                    {
                        result.Add(new Flip());
                        curHarmonics = EHarmonics.High;
                    }

                    Fill fill = new Fill();
                    fill.Diff.Dy = -1;
                    result.Add(fill);
                }
                else if (curHarmonics == EHarmonics.High)
                {
                    result.Add(new Flip());
                    curHarmonics = EHarmonics.Low;
                }

                current = next;
                ++iteration;
            }

            if (curHarmonics == EHarmonics.High)
            {
                result.Add(new Flip());
            }

            result.Add(new Halt());

            return(result);
        }
Пример #3
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);
        }