Example #1
0
        public async Task SolveAsync(SpeculativeCallContext context = null)
        {
            if (!IsValid)
            {
                return;
            }

            if (context == null)
            {
                SetDetermibableCells();
            }

            await CandidateExclusionSolveAsync();

            if (IsValid && !IsSolved)
            {
                PicrossBoard speculationBaseBoard = new PicrossBoard(this);
                PicrossBoard solvedBoard          = await speculationBaseBoard.SpeculativeSolveAsync(context);

                if (solvedBoard != null)
                {
                    this.Copy(solvedBoard);
                }
            }
        }
Example #2
0
 public static string BoardName(SpeculativeCallContext context)
 {
     if (context == null)
     {
         return("main board");
     }
     else
     {
         return
             ($"speculative board of depth {context.depth}, option {context.optionIndex + 1} of {context.optionsCount}");
     }
 }
Example #3
0
        private async Task <PicrossBoard> SpeculativeSolveAsync(SpeculativeCallContext context)
        {
            var undeterminedLines = ActiveLines
                                    .Where(line => !line.IsSet);

            PicrossActiveLine speculationTarget = undeterminedLines
                                                  .First(line => line.CandidateCount ==
                                                         undeterminedLines.Min(l => l.CandidateCount)); //todo: review this criteria. Max reduces memory footprint

            Random rng = new Random();
            var    candidateSolutions = speculationTarget.CandidateSolutions
                                        .OrderBy(cs => rng.Next()).ToArray();
            int candidatesCount = candidateSolutions.Count();

            for (int i = 0; i < candidatesCount; i++)
            {
                PicrossBoard speculativeBoard = new PicrossBoard(this);
                speculativeBoard.SetLineSolution(
                    lineType: speculationTarget.Type,
                    lineIndex: speculationTarget.Index,
                    candidateToSet: candidateSolutions[i]
                    );

                SpeculativeCallContext speculativeContext = new SpeculativeCallContext()
                {
                    depth        = context?.depth + 1 ?? 1,
                    optionIndex  = i,
                    optionsCount = candidatesCount
                };

                var speculativeTask = new Task(() => speculativeBoard.Solve(VerboseLevel.Silent, speculativeContext));
                speculativeTask.Start();
                await speculativeTask.ConfigureAwait(false);

                if (speculativeBoard.IsValid && speculativeBoard.IsSolved)
                {
                    return(speculativeBoard);
                }
            }

            return(null);
        }
Example #4
0
        public void Solve(
            VerboseLevel verboseLevel      = VerboseLevel.Silent,
            SpeculativeCallContext context = null)
        {
            if (!IsValid)
            {
                if (verboseLevel != VerboseLevel.Silent)
                {
                    log.Info("Solving aborted, board invalid - " + BoardName(context));
                }
                return;
            }

            if (verboseLevel != VerboseLevel.Silent)
            {
                log.Info("Start solving - " + BoardName(context));
            }

            if (context == null)
            {
                SetDetermibableCells();
            }

            CandidateExclusionSolve(verboseLevel);

            if (IsValid && !IsSolved)
            {
                var undeterminedLines = ActiveLines
                                        .Where(line => !line.IsSet);

                PicrossActiveLine speculationTarget = undeterminedLines
                                                      .First(line => line.CandidateCount ==
                                                             undeterminedLines.Min(l => l.CandidateCount)); //todo: review this criteria. Max reduces memory footprint

                Random rng = new Random();
                var    candidateSolutions = speculationTarget.CandidateSolutions
                                            .OrderBy(cs => rng.Next()).ToArray();
                int candidatesCount = candidateSolutions.Count();

                for (int i = 0; i < candidatesCount; i++)
                {
                    PicrossBoard speculativeBoard = new PicrossBoard(this);
                    speculativeBoard.SetLineSolution(
                        lineType: speculationTarget.Type,
                        lineIndex: speculationTarget.Index,
                        candidateToSet: candidateSolutions[i]
                        );

                    SpeculativeCallContext speculativeContext = new SpeculativeCallContext()
                    {
                        depth        = context?.depth + 1 ?? 1,
                        optionIndex  = i,
                        optionsCount = candidatesCount
                    };

                    speculativeBoard.Solve(verboseLevel, speculativeContext);
                    if (speculativeBoard.IsValid && speculativeBoard.IsSolved)
                    {
                        this.Copy(speculativeBoard);
                        return;
                    }
                }
            }

            if (verboseLevel != VerboseLevel.Silent)
            {
                if (!IsSolved)
                {
                    log.Info("Solving failed - " + BoardName(context));
                }
                else
                {
                    log.Info("Solving succeeded - " + BoardName(context));
                }
            }
        }