示例#1
0
        public Grid Generate(Difficulty difficulty, GeneratorContext generatorContext)
        {
            if (generatorContext == null)
            {
                throw new ArgumentNullException("generatorContext");
            }

            DateTime startTime    = DateTime.Now;
            Grid     solutionGrid = GenerateTerminalPattern();
            Grid     problemGrid  = DigHoles(solutionGrid, difficulty);

            Propagate(problemGrid, solutionGrid);

            Solver        solver        = new Solver();
            SolverContext solverContext = new SolverContext();

            solver.Solve(problemGrid, solverContext);

            Grader  grader  = new Grader();
            Grading grading = grader.Grade(solverContext);

            generatorContext.Solution           = solverContext.UniqueSolution;
            generatorContext.TargetedDifficulty = difficulty;
            generatorContext.GradedDifficulty   = grading.GradedDifficulty;
            generatorContext.NumberOfGiven      = problemGrid.GetNumberOfGiven();
            generatorContext.LowerBound         = problemGrid.GetLowerBoundInRowAndCol();
            generatorContext.CalculationTime    = DateTime.Now.Subtract(startTime).TotalMilliseconds;

            return(problemGrid);
        }
示例#2
0
        private static void Solve(string filepath)
        {
            try
            {
                Parser        parser  = new Parser();
                Grid          grid    = parser.Parse(File.OpenText(filepath));
                Solver        solver  = new Solver();
                SolverContext context = new SolverContext();
                Grading       grading = null;

                solver.Solve(grid, context);

                if (context.UniqueSolution != null)
                {
                    Grader grader = new Grader();
                    grading = grader.Grade(context);
                }

                WriteSolution(filepath, context, grading);
            }
            catch
            {
                Console.WriteLine(UnexpectedErrorStr);
            }
        }
示例#3
0
        private void Search(Grid grid, SolverContext solverContext, bool exitAtFirst = false, TimeSpan?maxTime = null)
        {
            searchCallCount++;

            if (grid.IsSolution())
            {
                solverContext.AddSolution(grid);
            }
            else
            {
                IEnumerable <Grid> moves = grid.GenerateMoves();

                if (moves != null)
                {
                    foreach (var move in moves)
                    {
                        Search(move, solverContext, exitAtFirst, maxTime);

                        if ((exitAtFirst && solverContext.UniqueSolution != null) || HasMaxTimeExceeded(solverContext, maxTime))
                        {
                            break;
                        }
                    }
                }
            }
        }
示例#4
0
        public void Solve(Grid grid, SolverContext solverContext, bool exitAtFirst = false, TimeSpan?maxTime = null)
        {
            if (grid == null)
            {
                throw new ArgumentNullException("grid");
            }
            if (solverContext == null)
            {
                throw new ArgumentNullException("context");
            }

            solverContext.StartTime = DateTime.Now;
            searchCallCount         = 0;
            solverContext.Problem   = grid;

            Grid reducedGrid = grid.Reduce();

            if (reducedGrid != null)
            {
                Search(reducedGrid, solverContext, exitAtFirst, maxTime);
            }

            solverContext.SearchCallCount = searchCallCount;
            solverContext.EndTime         = DateTime.Now;
        }
示例#5
0
        public bool CheckUniqueSolution(Grid grid)
        {
            Solver        solver  = new Solver();
            SolverContext context = new SolverContext();

            solver.Solve(grid, context);
            return(context.UniqueSolution != null);
        }
示例#6
0
        private bool HasMaxTimeExceeded(SolverContext solverContext, TimeSpan?maxTime)
        {
            if (maxTime != null)
            {
                return(DateTime.Now.Subtract(solverContext.StartTime) > maxTime);
            }

            return(false);
        }
示例#7
0
        private static void WriteSolution(string filepath, SolverContext solverContext, Grading grading)
        {
            int solutionCount = solverContext.Solutions.Count;

            if (solverContext.UniqueSolution != null)
            {
                WriteUniqueSolution(solverContext.UniqueSolution);
            }
            else if (solutionCount == 0)
            {
                WriteNoSolution();
            }
            else
            {
                WriteMultipleSolutions(solverContext.Solutions);
            }

            WriteSolutionInfo(filepath, solverContext, grading);
        }
示例#8
0
        /// <summary>
        /// Generate a valid terminal pattern using Las Vegas randomized approach, letting
        /// the solver produce the final pattern.
        /// </summary>
        /// <returns>The terminal pattern.</returns>
        private Grid GenerateTerminalPattern()
        {
            Grid    grid    = null;
            Reducer reducer = new Reducer();
            Solver  solver  = new Solver();
            bool    solved  = false;

            while (!solved)
            {
                int givenCount = 0;
                grid = new Grid();

                while (givenCount < InitialGivenCount)
                {
                    int square = RandomSquare(random);

                    if (!grid.IsSquareUnique(square))
                    {
                        SquareValue value   = RandomSquareValue(random);
                        Grid        tryGrid = (Grid)grid.Clone();
                        tryGrid.SetSquare(square, value);
                        tryGrid = tryGrid.Reduce();

                        if (tryGrid != null)
                        {
                            grid = tryGrid;
                            givenCount++;
                        }
                    }
                }

                SolverContext solverContext = new SolverContext();
                solver.Solve(grid, solverContext, true, TimeSpan.FromSeconds(5));

                if (solverContext.UniqueSolution != null)
                {
                    grid   = solverContext.UniqueSolution;
                    solved = true;
                }
            }

            return(grid);
        }
示例#9
0
        private static void WriteSolutionInfo(string filepath, SolverContext context, Grading grading)
        {
            Console.WriteLine(ThickDividerStr);
            Console.WriteLine(string.Format(CalculationTimeStr0, Math.Round(context.CalculationTime)));
            Console.WriteLine(string.Format(SearchCallsStr0, context.SearchCallCount));
            Console.WriteLine(string.Format(NumberOfGivenStr0, context.Problem.GetNumberOfGiven()));
            Console.WriteLine(string.Format(InputProblemStr0, filepath));
            Console.Write(context.Problem);

            if (grading != null)
            {
                Console.WriteLine(string.Format(GradedDifficultyStr0, grading.GradedDifficulty));
                Console.WriteLine(string.Format(GradingNumGivenScoreStr0, grading.NumGivenScore));
                Console.WriteLine(string.Format(GradingLowerBoundScoreStr0, grading.LowerBoundScore));
                Console.WriteLine(string.Format(GradingNumSearchCallsScoreStr0, grading.NumSearchCallsScore));
                Console.WriteLine(string.Format(GradingWeightedScoreValueStr0, grading.Score));
            }

            Console.WriteLine(ThickDividerStr);
        }