Beispiel #1
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);
        }
Beispiel #2
0
            public void Update(TCoord coord, TBot bot)
            {
                if (Coords == null)
                {
                    return;
                }

                if (Coords.Contains(coord))
                {
                    throw new InvalidStateException($"bot {bot.Bid} interferes with other bots at {coord}");
                }

                Coords.Add(coord);
            }
Beispiel #3
0
            private static void TraceMove(TCoord botCoord, StraightMove m, Action <TCoord> action)
            {
                var cur = botCoord;
                var dst = cur;

                dst.Apply(m.Diff);
                var step = new CoordDiff(Math.Sign(m.Diff.Dx), Math.Sign(m.Diff.Dy), Math.Sign(m.Diff.Dz));

                do
                {
                    cur.Apply(step);
                    action(cur);
                }while (!cur.Equals(dst));
            }
Beispiel #4
0
        private bool IsGrounded(TCoord coord, HashSet <TCoord> visited)
        {
            if (visited.Contains(coord) || !coord.IsValid(Model.R) || !this[coord])
            {
                return(false);
            }

            visited.Add(coord);
            if (coord.Y == 0)
            {
                return(true);
            }

            return(coord.ManhattenNeighbours().Any(x => IsGrounded(x, visited)));
        }
Beispiel #5
0
        List <Tuple <TCoord, CoordDiff> > GenerateCuts(int lineIndex, List <int> segmentsMap, int layerIndex)
        {
            List <Tuple <TCoord, CoordDiff> > res = new List <Tuple <TCoord, CoordDiff> >();

            for (int j = 1; j < segmentsMap.Count; j += 2)
            {
                var start     = segmentsMap[j - 1];
                var end       = segmentsMap[j];
                var pos       = new TCoord(lineIndex, start, layerIndex);
                var direction = new CoordDiff(0, end, 0);
                res.Add(Tuple.Create <TCoord, CoordDiff>(pos, direction));
            }

            return(res);
        }
Beispiel #6
0
        public static TCoord RectangleTraverse(List <ICommand> commands, int minX, int minZ, int maxX, int maxZ, int y, TModel model)
        {
            TCoord current;

            current.X = minX;
            current.Y = y;
            current.Z = minZ;

            while (current.X < maxX || current.Z < maxZ)
            {
                if (current.X < maxX)
                {
                    TCoord next = current;
                    next.X = maxX;
                    AddTransition(commands, current, next, model, true);
                    current = next;
                }
                if (current.Z < maxZ)
                {
                    TCoord next1 = current;
                    next1.Z += 1;

                    TCoord next2 = next1;
                    next2.X = minX;

                    AddTransition(commands, current, next1, model, true);
                    AddTransition(commands, next1, next2, model, true);

                    current = next2;
                }
                if (current.Z < maxZ)
                {
                    TCoord next = current;
                    next.Z += 1;

                    AddTransition(commands, current, next, model, true);

                    current = next;
                }
            }

            return(current);
        }
Beispiel #7
0
            public List <ICommand> RecreatePath(TCoord src)
            {
                var path = new List <ICommand>();
                var cur  = Coord;

                while (!cur.Equals(src))
                {
                    var from = cells[cur.X, cur.Y, cur.Z].From;
                    path.Add(
                        new StraightMove
                    {
                        Diff = cur.Diff(from)
                    });
                    cur = from;
                }

                path.Reverse();
                return(path);
            }
Beispiel #8
0
        List <ICommand> FillLine(TBot bot, CoordDiff direction, CoordDiff botOffset)
        {
            TCoord          x          = bot.Coord;
            List <ICommand> res        = new List <ICommand>();
            CoordDiff       fillOffset = new CoordDiff(-botOffset.Dx, -botOffset.Dy, -botOffset.Dz);

            if (direction.Dx != 0)
            {
                int dif = direction.Dx < 0 ? -1 : 1;

                while (true)
                {
                    Fill fc = new Fill();
                    fc.Diff = fillOffset;
                    res.Add(fc);
                    if (bot.Coord.X == x.X + direction.Dx + botOffset.Dx)
                    {
                        break;
                    }
                    StraightMove move = new StraightMove();
                    move.Diff = new CoordDiff(dif, 0, 0);
                    res.Add(move);
                }
            }
            if (direction.Dy != 0)
            {
                int dif = direction.Dy < 0 ? -1 : 1;

                while (true)
                {
                    Fill fc = new Fill();
                    fc.Diff = fillOffset;
                    res.Add(fc);
                    if (bot.Coord.Y == x.Y + direction.Dy + botOffset.Dy)
                    {
                        break;
                    }
                    StraightMove move = new StraightMove();
                    move.Diff = new CoordDiff(0, dif, 0);
                    res.Add(move);
                }
            }
            if (direction.Dz != 0)
            {
                int dif = direction.Dz < 0 ? -1 : 1;

                while (true)
                {
                    Fill fc = new Fill();
                    fc.Diff = fillOffset;
                    res.Add(fc);
                    if (bot.Coord.Z == x.Z + direction.Dz + botOffset.Dz)
                    {
                        break;
                    }
                    StraightMove move = new StraightMove();
                    move.Diff = new CoordDiff(0, 0, dif);
                    res.Add(move);
                }
            }

            return(res);
        }
Beispiel #9
0
        public List <ICommand> MakeTrace(TModel src, TModel model)
        {
            if (src.NumFilled != 0)
            {
                return(null);
            }

            ICommand modifyCommand = new Fill();

            ((Fill)modifyCommand).Diff.Dy = -1;
            if (model.Name.Contains("FD"))
            {
                modifyCommand = new Void();
                ((Void)modifyCommand).Diff.Dy = -1;
            }

            //      TState state = new TState(model);

            var result = new List <ICommand>();

            result.Add(new Flip());

            var current          = new TCoord();
            var dumpCureTraverse = new TDumpCubeTraverse(model);

            var iteration = 0;

            while ((iteration == 0) || !current.IsAtStart())
            {
                if (iteration == 295)
                {
                    int a = 0;
                }

                var next = model.Name.Contains("FA") ? dumpCureTraverse.Next() : dumpCureTraverse.NextDestroy();
                var move = new StraightMove();
                move.Diff = dumpCureTraverse.GetDirection();
                result.Add(move);
                //               {
                //                   List<ICommand> ss = new List<ICommand>();
                //                 ss.Add(move);
                //                 TCommandsReader cr = new TCommandsReader(ss);
                //                 state.Step(cr);
                //             }

                if ((next.Y > 0) && (model[next.X, next.Y - 1, next.Z] > 0))
                {
                    result.Add(modifyCommand);
                    //              {
                    //                  List<ICommand> ss = new List<ICommand>();
                    //                 ss.Add(move);
                    //                 TCommandsReader cr = new TCommandsReader(ss);
                    //                 state.Step(cr);
                    //            }
                }

                current = next;
                ++iteration;
            }

            result.Add(new Flip());
            result.Add(new Halt());

            return(result);
        }
Beispiel #10
0
 int Depth(TCoord c) => depth_[c.X, c.Y, c.Z];
Beispiel #11
0
 private bool IsFree(TCoord coord) => (state.M(coord) == 0) && !interferedCells.Contains(coord);
Beispiel #12
0
        public List <ICommand> MakeTrace(TModel src, TModel model)
        {
            if (src.NumFilled != 0)
            {
                return(null);
            }

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

            int maxY = 0;

            for (var x = 0; x < model.R; ++x)
            {
                for (var y = 0; y < model.R; ++y)
                {
                    for (var z = 0; z < model.R; ++z)
                    {
                        if (model[x, y, z] > 0)
                        {
                            maxY = Math.Max(maxY, y);
                        }
                    }
                }
            }

            TCoord current;

            current.X = 0;
            current.Y = 0;
            current.Z = 0;

            for (int y = 0; y <= maxY; ++y)
            {
                int minX = model.R;
                int minZ = model.R;

                int maxX = 0;
                int maxZ = 0;

                for (var x = 0; x < model.R; ++x)
                {
                    for (var z = 0; z < model.R; ++z)
                    {
                        if (model[x, y, z] > 0)
                        {
                            minX = Math.Min(minX, x);
                            minZ = Math.Min(minZ, z);

                            maxX = Math.Max(maxX, x);
                            maxZ = Math.Max(maxZ, z);
                        }
                    }
                }

                TCoord startPoint;
                startPoint.X = minX;
                startPoint.Y = y;
                startPoint.Z = minZ;

                AddTransition(result, current, startPoint, model, false);

                current = RectangleTraverse(result, minX, minZ, maxX, maxZ, y, model);

                TCoord next = current;
                ++next.Y;
                AddTransition(result, current, next, model, false);
            }

            {
                TCoord next1 = current;
                next1.X = 0;
                next1.Z = 0;
                AddTransition(result, current, next1, model, false);

                TCoord next2 = next1;
                next2.Y = 0;

                AddTransition(result, next1, next2, model, false);
            }

            result.Add(new Halt());

            return(result);
        }
Beispiel #13
0
 List <ICommand> MoveToPosition(TBot bot, TCoord to)
 {
     return(MoveToPosition(bot, to.X, to.Y, to.Z));
 }
Beispiel #14
0
 public int M(TCoord c) => Matrix[c.X, c.Y, c.Z];
Beispiel #15
0
 private bool this[TCoord c] => c.IsValid(Model.R) && Matrix[c.X, c.Y, c.Z] > 0;
Beispiel #16
0
        public IEnumerable <CoordWithPath> EnumerateReachablePaths(TCoord src, int maxDepth, int maxSteps)
        {
            ++curGeneration;

            // THIS IS VERY DUMB ALGO. BECAUSE I'M TOO STUPID TO DO BETTER

            // TODO: support LMoves
            queue.Clear();
            queue.Enqueue(src);
            cells[src.X, src.Y, src.Z] = new CellData()
            {
                Cost       = 0,
                Generation = curGeneration
            };

            yield return(new CoordWithPath(src, cells));

            int steps = 0;

            while (queue.Count != 0)
            {
                var cur = queue.Dequeue();

                // TODO: smarter precompute?
                var(minDx, maxDx) = FindRange(1, 0, 0);
                var(minDy, maxDy) = FindRange(0, 1, 0);
                var(minDz, maxDz) = FindRange(0, 0, 1);

                var c = default(CoordWithPath);
                // we visit (and yield) closes nodes first
                for (var dx = minDx; dx <= maxDx; ++dx)
                {
                    if (TryVisit(Math.Abs(dx), dx, 0, 0))
                    {
                        yield return(c);

                        if (++steps >= maxSteps)
                        {
                            yield break;
                        }
                        queue.Enqueue(c.Coord);
                    }
                }

                for (var dy = minDy; dy <= maxDy; ++dy)
                {
                    if (TryVisit(Math.Abs(dy), 0, dy, 0))
                    {
                        yield return(c);

                        if (++steps >= maxSteps)
                        {
                            yield break;
                        }
                        queue.Enqueue(c.Coord);
                    }
                }

                for (var dz = minDz; dz <= maxDz; ++dz)
                {
                    if (TryVisit(Math.Abs(dz), 0, 0, dz))
                    {
                        yield return(c);

                        if (++steps >= maxSteps)
                        {
                            yield break;
                        }
                        queue.Enqueue(c.Coord);
                    }
                }

                (int, int) FindRange(int dx, int dy, int dz)
                {
                    var min      = 0;
                    var minCoord = cur;

                    do
                    {
                        minCoord.Apply(new CoordDiff(-1 * dx, -1 * dy, -1 * dz));
                        --min;
                    }while ((min >= -Constants.StraightMoveCorrection) && minCoord.IsValid(model.R) && IsFree(minCoord, maxDepth));

                    var max      = 0;
                    var maxCoord = cur;

                    do
                    {
                        maxCoord.Apply(new CoordDiff(dx, dy, dz));
                        ++max;
                    }while ((max <= Constants.StraightMoveCorrection) && maxCoord.IsValid(model.R) && IsFree(maxCoord, maxDepth));

                    return(min + 1, max - 1);
                }

                bool TryVisit(int dist, int dx, int dy, int dz)
                {
                    var next    = new TCoord(cur.X + dx, cur.Y + dy, cur.Z + dz);
                    var curCost = cells[cur.X, cur.Y, cur.Z].Cost;

                    if (next.IsValid(model.R) && !cells[next.X, next.Y, next.Z].Visited(curGeneration))
                    {
                        // TODO: add energy maintainance into cost
                        cells[next.X, next.Y, next.Z] = new CellData()
                        {
                            From       = cur,
                            Cost       = curCost + (2 * dist),
                            Generation = curGeneration,
                        };
                        c = new CoordWithPath(next, cells);
                        return(true);

                        // if (!IsFree(next)) throw new Exception("WTF");
                    }

                    return(false);
                }
            }
        }
Beispiel #17
0
        public List <ICommand> MakeReassemblyTrace(TModel srcModel, TModel tgtModel)
        {
            Fill doFill = new Fill();

            doFill.Diff.Dy = -1;

            Void doVoid = new Void();

            doVoid.Diff.Dy = -1;

            var result = new List <ICommand>();

            result.Add(new Flip());

            var current          = new TCoord();
            var dumpCureTraverse = new TDumpCubeTraverse(srcModel, tgtModel);

            TState          state = new TState(srcModel);
            List <ICommand> ss    = new List <ICommand>();

            var iteration = 0;

            while ((iteration == 0) || !current.IsAtStart())
            {
                var next = dumpCureTraverse.Next();

                if (srcModel[next] > 0)
                {
                    Void curVoid = new Void();
                    curVoid.Diff = dumpCureTraverse.GetDirection();
                    result.Add(curVoid);

                    {
                        if (ss.Count == 0)
                        {
                            ss.Add(curVoid);
                        }
                        else
                        {
                            ss[0] = curVoid;
                        }
                        ss.Add(curVoid);
                        TCommandsReader cr = new TCommandsReader(ss);
                        state.Step(cr);
                    }
                }

                var move = new StraightMove();
                move.Diff = dumpCureTraverse.GetDirection();
                result.Add(move);

                {
                    if (ss.Count == 0)
                    {
                        ss.Add(move);
                    }
                    else
                    {
                        ss[0] = move;
                    }

                    TCommandsReader cr = new TCommandsReader(ss);
                    state.Step(cr);
                }

                if ((next.Y > 0) && (tgtModel[next.X, next.Y - 1, next.Z] > 0) && state.Matrix[next.X, next.Y - 1, next.Z] == 0)
                {
                    result.Add(doFill);
                    {
                        if (ss.Count == 0)
                        {
                            ss.Add(doFill);
                        }
                        else
                        {
                            ss[0] = doFill;
                        }
                        TCommandsReader cr = new TCommandsReader(ss);
                        state.Step(cr);
                    }
                }
                if ((next.Y > 0) && (tgtModel[next.X, next.Y - 1, next.Z] == 0) && state.Matrix[next.X, next.Y - 1, next.Z] > 0)
                {
                    result.Add(doVoid);
                    {
                        if (ss.Count == 0)
                        {
                            ss.Add(doVoid);
                        }
                        else
                        {
                            ss[0] = doVoid;
                        }

                        TCommandsReader cr = new TCommandsReader(ss);
                        state.Step(cr);
                    }
                }

                current = next;
                ++iteration;
            }

            result.Add(new Flip());
            result.Add(new Halt());

            return(result);
        }
Beispiel #18
0
 public CoordWithPath(TCoord coord, CellData[,,] cells)
 {
     Coord      = coord;
     this.cells = cells;
 }
Beispiel #19
0
 private bool IsFree(TCoord coord, int maxDepth) =>
 (state.M(coord) == 0) &&
 // depth[coord.X, coord.Y, coord.Z] < maxDepth &&
 !interferedCells.Contains(coord);
Beispiel #20
0
        public static void AddTransition(List <ICommand> commands, TCoord current, TCoord target, TModel model, bool doFill)
        {
            Fill fill = new Fill();

            fill.Diff.Dx = 0;
            fill.Diff.Dy = 0;
            fill.Diff.Dz = 0;

            if (model[current.X, current.Y, current.Z] > 0 && doFill)
            {
                commands.Add(fill);
            }

            int xDiff = target.X > current.X ? 1 : -1;
            int yDiff = target.Y > current.Y ? 1 : -1;
            int zDiff = target.Z > current.Z ? 1 : -1;

            while (Math.Abs(current.X - target.X) > 1 ||
                   Math.Abs(current.Y - target.Y) > 1 ||
                   Math.Abs(current.Z - target.Z) > 1)
            {
                LMove lMove = new LMove();

                lMove.Diff1.Dx = Math.Abs(current.X - target.X) > 1 ? xDiff : 0;
                lMove.Diff1.Dy = Math.Abs(current.Y - target.Y) > 1 ? yDiff : 0;
                lMove.Diff1.Dz = Math.Abs(current.Z - target.Z) > 1 ? zDiff : 0;

                lMove.Diff2.Dx = Math.Abs(current.X - target.X) > 0 ? xDiff : 0;
                lMove.Diff2.Dy = Math.Abs(current.Y - target.Y) > 0 ? yDiff : 0;
                lMove.Diff2.Dz = Math.Abs(current.Z - target.Z) > 0 ? zDiff : 0;

                commands.Add(lMove);

                current.X += lMove.Diff1.Dx + lMove.Diff2.Dx;
                current.Y += lMove.Diff1.Dy + lMove.Diff2.Dy;
                current.Z += lMove.Diff1.Dz + lMove.Diff2.Dz;

                if (model[current.X, current.Y, current.Z] > 0 && doFill)
                {
                    commands.Add(fill);
                }
            }

            while (Math.Abs(current.X - target.X) > 0 ||
                   Math.Abs(current.Y - target.Y) > 0 ||
                   Math.Abs(current.Z - target.Z) > 0)
            {
                StraightMove sMove = new StraightMove();

                sMove.Diff.Dx = Math.Abs(current.X - target.X) > 0 ? xDiff : 0;
                sMove.Diff.Dy = Math.Abs(current.Y - target.Y) > 0 ? yDiff : 0;
                sMove.Diff.Dz = Math.Abs(current.Z - target.Z) > 0 ? zDiff : 0;

                commands.Add(sMove);

                current.X += sMove.Diff.Dx;
                current.Y += sMove.Diff.Dy;
                current.Z += sMove.Diff.Dz;

                if (model[current.X, current.Y, current.Z] > 0 && doFill)
                {
                    commands.Add(fill);
                }
            }
        }