Beispiel #1
0
 public Vector GetPossibleStartPlace(IsGroundedChecker groundedChecker, Func <Vector, bool> isForbidden, Vector botCoordinate)
 {
     return(figure
            .Where(groundedChecker.CanRemove)
            .FirstOrDefault(f => f.GetAdjacents()
                            .Any(adj => !figure.Contains(adj) && matrix.Contains(adj) && !isForbidden(botCoordinate))));
 }
 public Vector GetPossibleStartPlace(IsGroundedChecker groundedChecker, Func <Vector, bool> isForbidden, Vector botCoordinate)
 {
     return(figure.OrderByDescending(f => (f - botCoordinate).Mlen)
            .Where(f => f != botCoordinate)
            .Where(f => groundedChecker.CanPlace(f))
            .FirstOrDefault(f => f.GetAdjacents()
                            .Any(adj => !figure.Contains(adj) && matrix.Contains(adj) && !isForbidden(botCoordinate))));
 }
Beispiel #3
0
 public PathWork(Vector botPosition, Vector endPosition, Matrix matrix, IsGroundedChecker isGroundedChecker, int botsCount, int botId, Matrix model)
 {
     BotPosition            = botPosition;
     EndPosition            = endPosition;
     this.matrix            = matrix;
     this.isGroundedChecker = isGroundedChecker;
     BotsCount  = botsCount;
     BotId      = botId;
     this.model = model;
 }
Beispiel #4
0
 public BotMoveSearcher(Matrix matrix, Matrix model, Vector botPosition, Func <Vector, bool> isForbiddenArea, int botsCount, Vector end, IsGroundedChecker groundedChecker)
 {
     Matrix          = matrix;
     BotPosition     = botPosition;
     IsForbiddenArea = isForbiddenArea;
     BotsCount       = botsCount;
     End             = end;
     GroundedChecker = groundedChecker;
     Model           = model;
 }
Beispiel #5
0
        public Dictionary <int, Vector> DoWork(IsGroundedChecker groundedChecker, Func <Vector, bool> isForbidden, out List <ICommand> commands, out List <Vector> vectors)
        {
            var searcher = new BotMoveSearcher(matrix, model, BotPosition, isForbidden, BotsCount, EndPosition, isGroundedChecker)
            {
                mongoOplogWriter = mongoOplogWriter
            };

            searcher.FindPath(out vectors, out commands, out _);
            return(new Dictionary <int, Vector>
            {
                { BotId, EndPosition }
            });
        }
Beispiel #6
0
        public Vector SetWorkerAndGetInput(IsGroundedChecker groundedChecker, Func <Vector, bool> isForbidden, Vector botCoordinate, int botId)
        {
            if (start != null)
            {
                throw new Exception("too many workers");
            }

            BotId = botId;
            return(start = figure
                           .Where(groundedChecker.CanRemove)
                           .FirstOrDefault(f => f.GetAdjacents()
                                           .Any(adj => !figure.Contains(adj) && matrix.Contains(adj) && !isForbidden(botCoordinate))));
        }
Beispiel #7
0
        public static void Test()
        {
            var modelFilePath = @"..\..\..\data\models\LA020_tgt.mdl";

            var matrix = MatrixDeserializer.Deserialize(File.ReadAllBytes(modelFilePath));

            var mongoOplogWriter = new JsonOpLogWriter(new MongoJsonWriter());

            mongoOplogWriter.WriteLogName("GreedyGravityAI_IsGrounded");
            var state = State.CreateInitial(matrix.R, mongoOplogWriter);

            mongoOplogWriter.WriteInitialState(state);

            var groundedChecker = new IsGroundedChecker(matrix);

            var vertexex = new List <Vector>();

            for (int y = 0; y < matrix.R; y++)
            {
                for (int x = 0; x < matrix.R; x++)
                {
                    for (int z = 0; z < matrix.R; z++)
                    {
                        var vector = new Vector(x, y, z);
                        if (matrix.IsVoid(vector))
                        {
                            continue;
                        }

                        vertexex.Add(vector);
                    }
                }
            }

            var rand = new Random();

            vertexex = vertexex.OrderBy(_ => rand.NextDouble()).ToList();

            foreach (var vector in vertexex)
            {
                if (groundedChecker.CanRemove(vector))
                {
                    groundedChecker.UpdateWithClear(vector);
                    continue;
                }

                mongoOplogWriter.WriteFill(vector);
            }

            mongoOplogWriter.Save();
        }
        public FigureDecomposer(Matrix targetMatrix, Matrix startMatrix = null)
        {
            R           = targetMatrix.R;
            costPerStep = 3 * R * R * R;

            curMatrix         = startMatrix?.Clone() ?? new Matrix(R);
            this.targetMatrix = targetMatrix.Clone();
            xorMatrix         = curMatrix ^ targetMatrix;

            curSums    = new PointCounter(curMatrix);
            targetSums = new PointCounter(targetMatrix);
            xorSums    = new PointCounter(xorMatrix);

            curGroundChecker = new IsGroundedChecker(curMatrix);

            rand = new Random(42);
        }
Beispiel #9
0
        public static void SearchTest()
        {
            //var trackFilePath = @"..\..\..\data\track\LA001.nbt";
            var modelFilePath = @"..\..\..\data\models\LA180_tgt.mdl";

            var matrix = MatrixDeserializer.Deserialize(File.ReadAllBytes(modelFilePath));

            //var ai = new GreedyGravityAI(matrix);

            Console.WriteLine("matrix loaded");

            var mongoOplogWriter = new JsonOpLogWriter(new MongoJsonWriter());

            mongoOplogWriter.WriteLogName("GreedyGravityAI_IsGrounded");
            var state = State.CreateInitial(matrix.R, mongoOplogWriter);

            mongoOplogWriter.WriteInitialState(state);

            var groundedChecker = new IsGroundedChecker(matrix);
            var startPosition   = new Vector(0, 0, 0);

            for (int i = 0; i < matrix.R; i++)
            {
                for (int j = 0; j < matrix.R; j++)
                {
                    for (int k = 0; k < matrix.R; k++)
                    {
                        var vector = new Vector(i, j, k);
                        if (matrix.IsVoid(vector))
                        {
                            continue;
                        }
                        mongoOplogWriter.WriteColor(vector, "0000FF", 0.5);
                    }
                }
            }


            Console.WriteLine("matrix inited");

            var rand      = new Random(15);
            var forbidden = new HashSet <Vector>();

            Console.WriteLine("start");
            for (int i = 0; i < 1002; i++)
            {
                var endPosition = new Vector(rand.Next(matrix.R), rand.Next(matrix.R), rand.Next(matrix.R));
                while (forbidden.Contains(endPosition) || matrix.IsFull(endPosition))
                {
                    endPosition = new Vector(rand.Next(matrix.R), rand.Next(matrix.R), rand.Next(matrix.R));
                }

                mongoOplogWriter.WriteColor(endPosition, "00FF00", 1);
                DateTime d           = DateTime.UtcNow;
                var      pathBuilder = new BotMoveSearcher(matrix, state.Matrix, startPosition, vector => forbidden.Contains(vector), 39, endPosition, groundedChecker);
                pathBuilder.FindPath(out var movePath, out var commands, out var iterations);

                if (movePath == null)
                {
                    break;
                }

                Console.WriteLine($"{commands.Count}: {d - DateTime.UtcNow} - {iterations}");

                movePath.ForEach(c => forbidden.Add(c));


                foreach (var vector in movePath)
                {
                    mongoOplogWriter.WriteFill(vector);
                }
                mongoOplogWriter.WriteColor(endPosition, "0000FF", 1);

                startPosition = endPosition;
            }


            mongoOplogWriter.Save();
        }
        public Dictionary <int, Vector> DoWork(IsGroundedChecker groundedChecker, Func <Vector, bool> isForbidden, out List <ICommand> commands, out List <Vector> volatiles)
        {
            if (figure.Where(isForbidden).Any())
            {
                throw new ArgumentException("`figure` should not intersect `prohibited`");
            }
            if (!figure.Contains(start))
            {
                throw new ArgumentException("`figure` should contain `start`");
            }

            var gravity = CalcGravity(figure, start);

            Console.WriteLine("figure.Count = {0}", figure.Count);
            Console.WriteLine("gravity.Count = {0}", gravity.Count);

            var removeFills = new Dictionary <Vector, int>();
            var filled      = new HashSet <Vector>();
            var curPoint    = start;

            volatiles = new List <Vector>();
            commands  = new List <ICommand>();

            Dictionary <Vector, int> filltimes = new Dictionary <Vector, int>();
            int time = 0;

            while (filled.Count < figure.Count)
            {
                time++;
                var nextPoint = curPoint.GetAdjacents()
                                .Where(p => figure.Contains(p) && !filled.Contains(p))
                                .OrderByDescending(p => gravity[p])
                                .FirstOrDefault();

                if (nextPoint == null)
                {
                    break;
                }

                try
                {
                    List <Vector>   curPath     = null;
                    List <ICommand> curCommands = null;
                    if (!curPoint.IsAdjacentTo(nextPoint))
                    {
                        //Move(figure, isForbidden, curPoint, nextPoint, true, out curPath, out curCommands);
                    }
                    else
                    {
                        MoveStraight(curPoint, nextPoint, out curPath, out curCommands);
                    }
                    if (curPath == null)
                    {
                        break;
                    }

                    foreach (var vector in curPath.Where(vector => filled.Contains(vector)))
                    {
                        removeFills[vector] = removeFills.TryGetValue(vector, out var val) ? val + 1 : 1;
                        mongoOplogWriter?.WriteColor(vector, "FFFF00", 0.5);
                    }

                    filled.Add(curPoint);
                    volatiles.AddRange(curPath);
                    commands.AddRange(curCommands);

                    foreach (var fillCommand in curCommands.OfType <FillCommand>())
                    {
                        filltimes[fillCommand.RealFill] = time;
                    }
                }
                catch (ArgumentException)
                {
                    Console.WriteLine("Exception, was able to draw only {0} points", filled.Count);
                    break;
                }

                curPoint = nextPoint;
            }

            commands = commands.Where(command =>
            {
                if (removeFills.Count == 0)
                {
                    return(true);
                }
                var fillCommand = command as FillCommand;
                if (fillCommand == null)
                {
                    return(true);
                }

                if (!removeFills.TryGetValue(fillCommand.RealFill, out var val) || val == 0)
                {
                    return(true);
                }
                removeFills[fillCommand.RealFill]--;
                return(false);
            }).ToList();

            return(new Dictionary <int, Vector> {
                { BotId, curPoint }
            });
        }
Beispiel #11
0
 public Vector SetWorkerAndGetInput(IsGroundedChecker groundedChecker, Func <Vector, bool> isForbidden, Vector botCoordinate, int botId)
 {
     throw new NotImplementedException();
 }
Beispiel #12
0
 public Vector GetPossibleStartPlace(IsGroundedChecker groundedChecker, Func <Vector, bool> isForbidden, Vector botCoordinate)
 {
     throw new NotImplementedException();
 }
        public List <BuildingTask> Decompose()
        {
            Console.WriteLine("FigureDecomposer.Decompose() started");

            double initialTemp = EvaluateDifferenceFrom(curMatrix) / 10.0;
            var    tasks       = new List <BuildingTask>();

            ConvergenceStopper.Run(regionNo =>
            {
                var stopwatch = Stopwatch.StartNew();

                if (xorSums.TotalFulls <= 3)
                {
                    return(null);
                }
                Console.WriteLine($"Points to change: {xorSums.TotalFulls}\n");

                var state = FindNextRectangle(regionNo, initialTemp);
                if ((state.Region.Max - state.Region.Min).Clen <= 3)
                {
                    Console.WriteLine("Too small region, it will be skipped");
                    return(xorSums.TotalFulls);
                }

                Region leg = null;
                if (state.Fill && BreakesGrounding(state) && state.Region.Min.Y > 0)
                {
                    var direction = state.Region.Max - state.Region.Min;
                    if (true /*direction.X < 3 || direction.Z < 3*/)
                    {
                        Console.WriteLine("We don't build regions like vertical lines if they are not grounded");
                        return(xorSums.TotalFulls);
                    }

                    var legX = state.Region.Min.X + 1;
                    var legZ = state.Region.Min.Z + 1;
                    leg      = new Region(
                        new Vector(legX, 0, legZ),
                        new Vector(legX, state.Region.Min.Y - 1, legZ));
                    Console.WriteLine($"Building leg {leg} for region {state.Region}");

                    curMatrix.Fill(leg);
                    UpdateXorMatrix(leg);
                    if (leg.Volume >= 4)
                    {
                        tasks.Add(new BuildingTask(BuildingTaskType.GFill, leg));
                    }
                    else
                    {
                        tasks.AddRange(leg.AllPoints()
                                       .Select(p => new BuildingTask(BuildingTaskType.Fill, new Region(p))));
                    }
                }
                if (!state.Fill && BreakesGrounding(state))
                {
                    Console.WriteLine("Can't fix ungrounded GVoids");
                    return(xorSums.TotalFulls);
                }

                if (state.Fill)
                {
                    curMatrix.Fill(state.Region);
                }
                else
                {
                    curMatrix.Clear(state.Region);
                }
                UpdateXorMatrix(state.Region);
                var type = state.Fill ? BuildingTaskType.GFill : BuildingTaskType.GVoid;
                tasks.Add(new BuildingTask(type, state.Region));

                var minChanged = leg == null ? state.Region.Min : new Vector(0, 0, 0);
                curSums.Update(curMatrix, minChanged);
                xorSums.Update(xorMatrix, minChanged);
                curGroundChecker = new IsGroundedChecker(curMatrix);

                Console.WriteLine($"Elapsed {stopwatch.ElapsedMilliseconds} ms");
                return(xorSums.TotalFulls);
            }, 0.001, 50);

            Console.WriteLine($"Points to change: {xorSums.TotalFulls}");
            tasks.AddRange(CreatePointwiseTasks());

            Console.WriteLine("FigureDecomposer.Decompose() complete");
            return(tasks);
        }
Beispiel #14
0
        public Dictionary <int, Vector> DoWork(IsGroundedChecker groundedChecker, Func <Vector, bool> isForbidden, out List <ICommand> commands, out List <Vector> volatiles)
        {
            if (figure.Where(isForbidden).Any())
            {
                throw new ArgumentException("`figure` should not intersect `prohibited`");
            }
            if (!figure.Contains(start))
            {
                throw new ArgumentException("`figure` should contain `start`");
            }

            var gravity = CalcGravity(figure, start);

            Console.WriteLine("figure.Count = {0}", figure.Count);
            Console.WriteLine("gravity.Count = {0}", gravity.Count);


            var voided = new HashSet <Vector> {
                start
            };

            if (matrix.IsFull(start))
            {
                groundedChecker.UpdateWithClear(start);
            }
            var curPoint = start;

            volatiles = new List <Vector>();
            commands  = new List <ICommand>();


            while (voided.Count < figure.Count)
            {
                var nextPoint = curPoint.GetAdjacents()
                                .Where(p => figure.Contains(p) && !voided.Contains(p))
                                .Where(groundedChecker.CanRemove)
                                .OrderByDescending(f => f.GetAdjacents().Count(f1 => matrix.Contains(f1) && matrix.IsFull(f1) && !voided.Contains(f1)) == 1)
                                .ThenByDescending(p => gravity[p])
                                .FirstOrDefault();

                List <Vector>   curPath;
                List <ICommand> curCommands;

                if (nextPoint == null)
                {
                    break;
                }

                MoveStraight(curPoint, nextPoint, out curPath, out curCommands);

                foreach (var vector in curPath.Where(vector => voided.Contains(vector)))
                {
                    mongoOplogWriter?.WriteColor(vector, "FFFF00", 0.5);
                }

                voided.Add(nextPoint);
                groundedChecker.UpdateWithClear(nextPoint);
                commands.AddRange(curCommands);
                volatiles.AddRange(curPath);

                curPoint = nextPoint;
            }

            foreach (var vector in commands.OfType <VoidCommand>().Select(c => c.RealVoid).Reverse())
            {
                groundedChecker.UpdateWithFill(vector);
            }

            return(new Dictionary <int, Vector> {
                { BotId, curPoint }
            });
        }