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)))); }
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; }
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; }
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 } }); }
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)))); }
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); }
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 } }); }
public Vector SetWorkerAndGetInput(IsGroundedChecker groundedChecker, Func <Vector, bool> isForbidden, Vector botCoordinate, int botId) { throw new NotImplementedException(); }
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); }
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 } }); }