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(); }
private List <ICommand> FillFigure(HashSet <Vector> figure, HashSet <Vector> prohibited, Vector start) { if (figure.Intersect(prohibited).Count() > 0) { throw new ArgumentException("`figure` should not intersect `prohibited`"); } if (!figure.Contains(start)) { throw new ArgumentException("`figure` should contain `start` and `end`"); } var gravity = CalcGravity(figure, start); var mongoOplogWriter = new JsonOpLogWriter(new MongoJsonWriter()); mongoOplogWriter.WriteLogName("GreedyGravityAI_Expected"); var state = State.CreateInitial(targetMatrix.R, mongoOplogWriter); mongoOplogWriter.WriteInitialState(state); Console.WriteLine("figure.Count = {0}", figure.Count); Console.WriteLine("gravity.Count = {0}", gravity.Count); figure = gravity.Keys.ToHashSet(); // FIXME: It's a hack for non-connected figures int i = 0; var removeFills = new Queue <Vector>(); var filled = new HashSet <Vector>(); var curPoint = start; var volatiles = new List <Vector>(); var commands = new List <ICommand>(); while (filled.Count < figure.Count) { var nextPoint = curPoint.GetAdjacents() .Where(p => figure.Contains(p) && !filled.Contains(p)) .OrderByDescending(p => gravity[p]) .FirstOrDefault(); if (nextPoint == null) { nextPoint = figure.Where(p => p != curPoint && !filled.Contains(p)) .OrderBy(p => (curPoint - p).Mlen) .ThenByDescending(p => gravity[p]) .FirstOrDefault(); if (nextPoint != null) { mongoOplogWriter.WriteColor(curPoint, "0000FF", 0.5); mongoOplogWriter.WriteColor(nextPoint, "00FF00", 0.5); } } else { mongoOplogWriter.WriteColor(nextPoint, "FF0000", 0.5); } if (nextPoint == null) { nextPoint = new Vector(0, 0, 0); } try { List <Vector> curPath; List <ICommand> curCommands; if (!curPoint.IsAdjacentTo(nextPoint)) { Move(figure, prohibited, curPoint, nextPoint, CommandType.Fill, out curPath, out curCommands); } else { curPath = new List <Vector> { nextPoint }; curCommands = new List <ICommand> { new SMoveCommand(nextPoint - curPoint), new FillCommand(curPoint - nextPoint, curPoint), }; } foreach (var vector in curPath.Where(vector => filled.Contains(vector))) { removeFills.Enqueue(vector); mongoOplogWriter.WriteColor(vector, "FFFF00", 0.5); } filled.Add(curPoint); volatiles.AddRange(curPath); commands.AddRange(curCommands); } catch (ArgumentException) { Console.WriteLine("Exception, was able to draw only {0} points", filled.Count); break; } curPoint = nextPoint; } mongoOplogWriter.Save(); commands.Add(new HaltCommand()); Console.WriteLine("Commands have been generated"); commands = commands.Where(command => { var fillCommand = command as FillCommand; if (fillCommand == null) { return(true); } if (!fillCommand.RealFill.Equals(removeFills.Peek())) { return(true); } removeFills.Dequeue(); return(false); }).ToList(); return(commands); }
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 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 } }); }