Example #1
0
        // public Profile LoadProfile(string fileName)
        // {
        //     var profile = new Profile
        //     {
        //         FileName = fileName,
        //         Current = null,
        //         Statistics = new Statistics()
        //     };
        //     var pairs = TrivialNameValueFileFormat.Load(fileName);
        //     var binder = new TrivialNameValueFileFormat.WithBinder<Profile>();
        //     foreach (var pair in pairs)
        //     {
        //         binder.SetWhen(pair, profile, x => x.Name);
        //         binder.SetWhen(pair, profile, x => x.Created);
        //         binder.SetWhen(pair, profile, x => x.TimeInGame);
        //         binder.With(profile, x => x.Current)
        //             .SetWhen(pair, x => x.Library)
        //             .SetWhen(pair, x => x.Puzzle);
        //         binder.With(profile, x => x.Statistics)
        //             .SetWhen(pair, x => x.Pushes)
        //             .SetWhen(pair, x => x.Steps)
        //             .SetWhen(pair, x => x.Started)
        //             .SetWhen(pair, x => x.Undos)
        //             .SetWhen(pair, x => x.Restarts)
        //             ;
        //     }
        //
        //     return profile;
        // }


        // public TrivialNameValueFileFormat SaveProfile(Profile lib, string fileName)
        // {
        //     var txt = TrivialNameValueFileFormat.Serialise(lib);
        //     txt.Save(fileName);
        //     return txt;
        // }

        public Library LoadLegacySokoSolve_SSX(string fileName)
        {
            var ser = new XmlSerializer(typeof(SokobanLibrary));

            SokobanLibrary?xmlLib = null;

            using (var reader = File.OpenText(fileName))
            {
                xmlLib = (SokobanLibrary)ser.Deserialize(reader);
            }

            var lib = Convert(xmlLib);

            foreach (var puzzle in lib)
            {
                puzzle.Rating = StaticAnalysis.CalculateRating(puzzle.Puzzle);
            }

            return(lib);
        }
Example #2
0
        public List <SolverResultSummary> Run(
            SolverRun run,
            SolverCommand baseCommand,
            ISolver solver,
            bool showSummary,
            BatchSolveComponent.BatchArgs?batchArgs = null)
        {
            if (run == null)
            {
                throw new ArgumentNullException(nameof(run));
            }
            if (baseCommand == null)
            {
                throw new ArgumentNullException(nameof(baseCommand));
            }
            if (solver == null)
            {
                throw new ArgumentNullException(nameof(solver), "See: " + nameof(SingleThreadedForwardSolver));
            }

            Report.WriteLine("Puzzle Exit Conditions: {0}", run.PuzzleExit);
            Report.WriteLine("Batch Exit Conditions : {0}", run.BatchExit);
            Report.WriteLine("Environment           : {0}", DevHelper.RuntimeEnvReport());
            Report.WriteLine("Solver Environment    : v{0} -- {1}", SolverHelper.VersionUniversal, SolverHelper.VersionUniversalText);
            Report.WriteLine("Started               : {0}", DateTime.Now.ToString("u"));
            Report.WriteLine();

            var res   = new List <SolverResultSummary>();
            var start = new SolverStatistics
            {
                Started = DateTime.Now
            };
            SolverState?state            = null;
            var         pp               = 0;
            var         consecutiveFails = 0;

            foreach (var puzzle in run)
            {
                if (baseCommand.CheckAbort(baseCommand))
                {
                    Progress.WriteLine("EXITING...");
                    break;
                }

                try
                {
                    pp++;
                    Progress.WriteLine($"(Puzzle   {pp}/{run.Count}) Attempting: {puzzle.Ident} \"{puzzle.Name}\", R={StaticAnalysis.CalculateRating(puzzle.Puzzle)}. Stopping on [{baseCommand.ExitConditions}] ...");

                    Report.WriteLine("           Name: {0}", puzzle);
                    Report.WriteLine("          Ident: {0}", puzzle.Ident);
                    Report.WriteLine("         Rating: {0}", StaticAnalysis.CalculateRating(puzzle.Puzzle));
                    Report.WriteLine(puzzle.Puzzle.ToString());    // Adds 2x line feeds

                    IReadOnlyCollection <SolutionDTO> existingSolutions = null;
                    if (SkipPuzzlesWithSolutions && Repository != null)
                    {
                        existingSolutions = Repository.GetPuzzleSolutions(puzzle.Ident);
                        if (existingSolutions != null && existingSolutions.Any(
                                x => x.MachineName == Environment.MachineName && x.SolverType == solver.GetType().Name))
                        {
                            Progress.WriteLine("Skipping... (SkipPuzzlesWithSolutions)");
                            continue;
                        }
                    }



                    // #### Main Block Start --------------------------------------
                    var memStart     = GC.GetTotalMemory(false);
                    var attemptTimer = new Stopwatch();
                    attemptTimer.Start();
                    state = solver.Init(new SolverCommand(baseCommand)
                    {
                        Report = Report,
                        Puzzle = puzzle.Puzzle
                    });
                    var propsReport = GetPropReport(solver, state);
                    Tracking?.Begin(state);

                    try
                    {
                        solver.Solve(state);
                    }
                    catch (Exception e)
                    {
                        state.Exception = e;
                        state.Exit      = ExitConditions.Conditions.Error;
                        state.EarlyExit = true;
                    }
                    var memEnd = GC.GetTotalMemory(false);
                    state.Statistics.MemUsed = memEnd;
                    var memDelta     = memEnd - memStart;
                    var bytesPerNode = memDelta / state.Statistics.TotalNodes;
                    var maxNodes     = (ulong)0;
                    if (DevHelper.TryGetTotalMemory(out var totalMem))
                    {
                        maxNodes = totalMem / (ulong)bytesPerNode;
                    }
                    Report.WriteLine($"Memory Used: {Humanise.SizeSuffix(memEnd)}, delta: {Humanise.SizeSuffix(memDelta)} ~ {bytesPerNode:#,##0} bytes/node => max nodes:{maxNodes:#,##0}");
                    attemptTimer.Stop();
                    // #### Main Block End ------------------------------------------

                    state.Summary = new SolverResultSummary(
                        puzzle,
                        state.Solutions,
                        state.Exit,
                        SolverHelper.GenerateSummary(state),
                        attemptTimer.Elapsed,
                        state.Statistics
                        );

                    res.Add(state.Summary);

                    start.TotalNodes += state.Statistics.TotalNodes;
                    start.TotalDead  += state.Statistics.TotalDead;

                    Report.WriteLine("[DONE] {0}", state.Summary.Text);
                    Progress.WriteLine($" -> {state.Summary.Text}");

                    if (batchArgs != null && batchArgs.Save != null)
                    {
                        Console.WriteLine(" -> Saving...");
                        var binSer = new BinaryNodeSerializer();

                        var rootForward = state.GetRootForward();
                        if (rootForward != null)
                        {
                            var outState = System.IO.Path.Combine(batchArgs.Save, $"{puzzle.Ident}-forward.ssbn");
                            using (var f = File.Create(outState))
                            {
                                using (var bw = new BinaryWriter(f))
                                {
                                    binSer.WriteTree(bw, rootForward);
                                }
                            }
                            Report.WriteLine($"\tSaving State: {outState}");
                            Progress.WriteLine($"\tSaving State: {outState}");
                        }

                        var rootReverse = state.GetRootReverse();
                        if (rootReverse != null)
                        {
                            var outState = System.IO.Path.Combine(batchArgs.Save, $"{puzzle.Ident}-reverse.ssbn");
                            using (var f = File.Create(outState))
                            {
                                using (var bw = new BinaryWriter(f))
                                {
                                    binSer.WriteTree(bw, rootReverse);
                                }
                            }
                            Report.WriteLine($"\tSaving State: {outState}");
                            Progress.WriteLine($"\tSaving State: {outState}");
                        }
                    }

                    // Add Depth Reporting
                    Console.WriteLine(" -> Generating Reports...");
                    GenerateReports(state, solver);

                    if (Repository != null)
                    {
                        var id = StoreAttempt(solver, puzzle, state, propsReport.ToString());

                        if (id >= 0)
                        {
                            var solTxt = $"Checking against known solutions. SolutionId={id}";
                            Report.WriteLine(solTxt);
                            Console.WriteLine(solTxt);
                        }
                    }
                    else
                    {
                        Report.WriteLine($"Solution Repository not available: Skipping.");
                    }


                    if (state?.Summary?.Solutions != null && state.Summary.Solutions.Any()) // May have been removed above
                    {
                        consecutiveFails = 0;
                    }
                    else
                    {
                        consecutiveFails++;
                        if (StopOnConsecutiveFails != 0 && consecutiveFails > StopOnConsecutiveFails)
                        {
                            Progress.WriteLine("ABORTING... StopOnConsecutiveFails");
                            break;
                        }
                    }

                    Tracking?.End(state);

                    if (state.Exception != null)
                    {
                        Report.WriteLine("[EXCEPTION]");
                        WriteException(Report, state.Exception);
                    }
                    if (state.Exit == ExitConditions.Conditions.Aborted)
                    {
                        Progress.WriteLine("ABORTING...");
                        if (showSummary)
                        {
                            WriteSummary(res, start);
                        }
                        return(res);
                    }
                    if (start.DurationInSec > run.BatchExit.Duration.TotalSeconds)
                    {
                        Progress.WriteLine("BATCH TIMEOUT...");
                        if (showSummary)
                        {
                            WriteSummary(res, start);
                        }
                        return(res);
                    }

                    Progress.WriteLine();
                }
                catch (Exception ex)
                {
                    if (state != null)
                    {
                        state.Exception = ex;
                    }
                    Progress.WriteLine("ERROR: " + ex.Message);
                    WriteException(Report, ex);
                }
                finally
                {
                    state = null;

                    if (puzzle != run.Last())
                    {
                        GC.Collect();
                    }
                }
            }
            if (showSummary)
            {
                WriteSummary(res, start);
            }

            Report.WriteLine("Completed               : {0}", DateTime.Now.ToString("u"));
            return(res);
        }