public List<Result> Run(SolverRun run, SolverCommand baseCommand, ISolver solver = null)
        {
            if (solver == null)
            {
                solver = new SingleThreadedForwardSolver();
            }

            Report.WriteLine("Puzzle Exit Conditions: {0}", run.PuzzleExit);
            Report.WriteLine("Batch Exit Conditions : {0}", run.BatchExit);
            Report.WriteLine("Solver                : {0}", SolverHelper.Describe(solver));
            Report.WriteLine("CPU                   : {0}", DebugHelper.GetCPUDescription());
            Report.WriteLine("Machine               : {0} {1}", Environment.MachineName, Environment.Is64BitProcess ? "x64" : "x32");

            Report.WriteLine();

            var res = new List<Result>();
            var start = new SolverStatistics()
            {
                Started = DateTime.Now
            };
            SolverCommandResult result = null;
            int pp = 0;
            int consecutiveFails = 0;
            foreach (var puzzle in run)
            {
                if (baseCommand.CheckAbort(baseCommand))
                {
                    Progress.WriteLine("EXITING...");
                    break;
                }
                try
                {
                    pp++;
                    Progress.WriteLine("Attempting: {0} ({2}/{3}); Rating: {1}", PuzzleHelper.GetName(puzzle), StaticAnalysis.CalculateRating(puzzle), pp, run.Count);

                    var libPuzzle = puzzle as LibraryPuzzle;
                    Report.WriteLine("           Name: {0}", PuzzleHelper.GetName(puzzle));
                    Report.WriteLine("          Ident: {0}", libPuzzle != null ? libPuzzle.Ident : null);
                    Report.WriteLine("         Rating: {0}", StaticAnalysis.CalculateRating(puzzle));
                    Report.WriteLine("Starting Memory: {0}", Environment.WorkingSet);
                    Report.WriteLine(puzzle.ToString());

                    PuzzleDTO dto = null;
                    if (Repository != null)
                    {
                        dto = Repository.Get(puzzle);
                        if (dto == null)
                        {
                            dto = Repository.ToDTO(puzzle);
                            Repository.Store(dto);
                        }
                        dto.Solutions = Repository.GetSolutions(dto.PuzzleId);
                    }

                    if (SkipPuzzlesWithSolutions)
                    {
                        if (dto != null &&
                            dto.Solutions.Exists(x=>x.HostMachine == Environment.MachineName && x.SolverType == solver.GetType().Name))
                        {
                            Progress.WriteLine("Skipping... (SkipPuzzlesWithSolutions)");
                            continue;
                        }
                    }

                    Report.WriteLine();

                    result = solver.Init(new SolverCommand(baseCommand)
                    {
                        Report = Report,
                        ExitConditions = run.PuzzleExit,
                        Puzzle = puzzle,

                    });
                    if (Tracking != null) Tracking.Begin(result);

                    solver.Solve(result);
                    var r = new Result()
                    {
                        Summary = SolverHelper.Summary(result),
                        Exited = result.Exit,
                        Solutions = result.GetSolutions()
                    };
                    res.Add(r);

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

                    if (r.Solutions.Any())
                    {
                        int cc = 0;
                        foreach (var p in r.Solutions.ToArray())
                        {
                            string error = null;
                            var check = SolverHelper.CheckSolution(puzzle, p, out error);
                            Report.WriteLine("Solution #{0} [{1}] =>\n{2}", cc++, check ? "Valid":"INVALID!"+error, p);
                            if (!check)
                            {
                                r.Solutions.Remove(p);
                                r.Summary += " (INVALID SOLUTION)";
                            }
                        }
                        // Write to DB?
                        if (dto != null)
                        {
                            if (Repository != null)
                            {
                                StoreSolution(solver, dto, r.Solutions);
                            }
                        }
                    }

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

                    var finalStats = solver.Statistics;
                    if (finalStats != null)
                    {
                        foreach (var fs in finalStats)
                        {
                            Report.WriteLine("Statistics | {0}", fs);
                        }
                    }

                    if (Tracking != null) Tracking.End(result);

                    Report.WriteLine("[DONE] {0}", r.Summary);
                    if (result.Exception != null)
                    {
                        Report.WriteLine("[EXCEPTION]");
                        WriteException(Report, result.Exception);
                    }

                    Progress.WriteLine();
                    Progress.WriteLine("Completed: {0} ==> {1}", PuzzleHelper.GetName(puzzle), r.Summary);
                    Progress.WriteLine();

                    if (result.Exit == ExitConditions.Conditions.Aborted)
                    {
                        Progress.WriteLine("ABORTING...");
                        WriteSummary(res, start);
                        return res;
                    }

                    if (start.DurationInSec > run.BatchExit.Duration.TotalSeconds)
                    {
                        Progress.WriteLine("BATCH TIMEOUT...");
                        WriteSummary(res, start);
                        return res;
                    }

                    Progress.WriteLine();
                }
                catch (Exception ex)
                {
                    if (result != null) result.Exception = ex;
                    Progress.WriteLine("ERROR: "+ex.Message);
                    WriteException(Report, ex);
                }
                finally
                {
                    result = null;
                    Report.WriteLine("Ending Memory: {0}", Environment.WorkingSet);
                    GC.Collect();
                    Report.WriteLine("Post-GC Memory: {0}", Environment.WorkingSet);
                    Report.WriteLine("===================================");
                    Report.WriteLine();
                }

                Report.Flush();
            }
            WriteSummary(res, start);
            return res;
        }
示例#2
0
        protected virtual bool Tick(SolverCommand command, CommandResult state, ISolverQueue queue, out SolverCommandResult solve)
        {
            state.Statistics.DepthCompleted = queue.Statistics.DepthCompleted;
            state.Statistics.DepthMax = queue.Statistics.DepthMax;

            if (command.Progress != null)
            {
                command.Progress.Update(this, state, state.Statistics);
            }

            if (command.CheckAbort != null)
            {
                if (command.CheckAbort(command))
                {
                    state.Exit = ExitConditions.Conditions.Aborted;
                    state.EarlyExit = true;
                    state.Statistics.Completed = DateTime.Now;
                    solve = state;
                    return true;
                }
            }

            var check = command.ExitConditions.ShouldExit(state);
            if (check != ExitConditions.Conditions.Continue)
            {
                state.EarlyExit = true;
                state.Statistics.Completed = DateTime.Now;
                state.Exit = check;
                solve = state;
                return true;

            }
            solve = null;
            return false;
        }