public override (Voxel target, Voxel moveTarget) ChooseNextTarget() { if (Octree == null) { Octree = new VoxelOctree(0, 0, 0, MatterSystem.Matrix.Resolution, MatterSystem.Matrix.Resolution, MatterSystem.Matrix.Resolution); foreach (var v in RemainingVoxels) { Octree.Add(v); } } var pos = MatterSystem.Bots[1].Position; HashSet <Voxel> unreachable = new HashSet <Voxel>(); for (var i = 4; i < MatterSystem.Matrix.Resolution; i++) { var target = Octree.GetNearby(pos, i) .Where(x => !unreachable.Contains(x)) .Where(x => x.Grounded) .OrderBy(x => x.Y) .ThenBy(x => x.dv(pos)); foreach (var v in target) { // see if we can navigate to this var moveTargets = v.Nearby .Where(x => !x.Filled) .OrderByDescending(x => x.Y) .ThenByDescending(x => x.Nearby.Count(y => y.Filled != y.Target && y.Grounded)) .ThenBy(x => x.dv(pos)); foreach (var mt in moveTargets) { if (AstarMatrixPather.GetRouteTo(pos, mt) == null) { continue; } return(v, mt); } unreachable.Add(v); } } return(null, null); }
public void Solve(string outputFile) { if (outputFile != null) { Name = Path.GetFileNameWithoutExtension(outputFile); } // get all the target voxels RemainingVoxels = new HashSet <Voxel>(MatterSystem.Matrix.Storage.Where(x => x.Filled != x.Target)); var lastCompletePercent = 0; var startCount = RemainingVoxels.Count; Log.Info($"{Name} Total targets: {RemainingVoxels.Count:N0}"); while (RemainingVoxels.Count > 0) { var(targetVoxel, moveTarget) = ChooseNextTarget(); // move bot to a nearby if we're not there if (MatterSystem.Bots[1].Position != moveTarget) { var route = AstarMatrixPather.GetRouteTo(MatterSystem.Bots[1].Position, moveTarget); MatterSystem.ExecuteCommands(CommandOptimizer.Compress(route)); } // fill/void it ToggleVoxel(targetVoxel); // remove it from targets RemainingVoxels.Remove(targetVoxel); var complete = (int)(100 - ((float)RemainingVoxels.Count / startCount * 100)); if (complete != lastCompletePercent) { lastCompletePercent = complete; Log.Info($"{Name} {complete:N0}% complete ({RemainingVoxels.Count:N0} remaining)"); } } // move to home var homeRoute = AstarMatrixPather.GetRouteTo(MatterSystem.Bots[1].Position, MatterSystem.Matrix.Get(0, 0, 0)); if (homeRoute == null) { TraceFile.WriteTraceFile(outputFile + ".failed", MatterSystem.Trace); Log.Error($"{Path.GetFileNameWithoutExtension(outputFile)} Failed with {RemainingVoxels.Count:N0} targets left"); return; } MatterSystem.ExecuteCommands(CommandOptimizer.Compress(homeRoute)); if (outputFile != null) { // halt MatterSystem.ExecuteCommand(1, new CommandHalt()); // save trace file TraceFile.WriteTraceFile(outputFile, MatterSystem.Trace); Log.Debug($"{Path.GetFileNameWithoutExtension(outputFile)} Finished solution "); } }