예제 #1
0
        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);
        }
예제 #2
0
파일: Solver.cs 프로젝트: tstivers/icfp2018
        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 ");
            }
        }