Example #1
0
        private void SetLineSolution(LineType lineType, int lineIndex, PicrossLine candidateToSet)
        {
            var targetSet            = lineType == LineType.Column ? Columns : Rows;
            PicrossActiveLine target = targetSet.First(line => line.Index == lineIndex);

            target.ApplyLine(candidateToSet);
        }
Example #2
0
        private PicrossActiveLine[] GatherRows()
        {
            var rows = new PicrossActiveLine[RowCount];

            for (int rowIndex = 0; rowIndex < RowCount; rowIndex++)
            {
                var rowCells = new List <PicrossCell>();
                for (int columnIndex = 0; columnIndex < ColumnCount; columnIndex++)
                {
                    rowCells.Add(Matrix[rowIndex, columnIndex]);
                }

                var rowRule =
                    new PicrossLineRule(
                        lineStructure: Puzzle.RowRules[rowIndex],
                        lineLength: ColumnCount);

                rows[rowIndex] = new PicrossActiveLine(
                    type: LineType.Row,
                    index: rowIndex,
                    cells: rowCells,
                    rule: rowRule);
            }

            return(rows);
        }
Example #3
0
        private PicrossActiveLine[] GatherColumns()
        {
            var columns = new PicrossActiveLine[ColumnCount];

            for (int columnIndex = 0; columnIndex < ColumnCount; columnIndex++)
            {
                var columnCells = new List <PicrossCell>();
                for (int rowIndex = 0; rowIndex < RowCount; rowIndex++)
                {
                    columnCells.Add(Matrix[rowIndex, columnIndex]);
                }

                var columnRule =
                    new PicrossLineRule(
                        lineStructure: Puzzle.ColumnRules[columnIndex],
                        lineLength: RowCount);

                columns[columnIndex] = new PicrossActiveLine(
                    type: LineType.Column,
                    index: columnIndex,
                    cells: columnCells,
                    rule: columnRule);
            }

            return(columns);
        }
Example #4
0
        public PicrossActiveLine(IEnumerable <PicrossCell> cells, PicrossActiveLine copySource)
            : base(cells)
        {
            Type  = copySource.Type;
            Index = copySource.Index;
            Rule  = copySource.Rule;
            CandidateSolutions = new List <PicrossLine>(copySource.CandidateSolutions);

            RegisterCellHandlers();
        }
Example #5
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 #6
0
        private PicrossActiveLine[] CopyRows(PicrossBoard copySource)
        {
            var rows = new PicrossActiveLine[RowCount];

            Parallel.ForEach(
                Enumerable.Range(0, RowCount),
                rowIndex =>
            {
                var rowCells = new List <PicrossCell>();
                for (int columnIndex = 0; columnIndex < ColumnCount; columnIndex++)
                {
                    rowCells.Add(Matrix[rowIndex, columnIndex]);
                }

                rows[rowIndex] = new PicrossActiveLine(
                    cells: rowCells,
                    copySource: copySource.Rows.ElementAt(rowIndex));
            });

            return(rows);
        }
Example #7
0
        private PicrossActiveLine[] CopyColumns(PicrossBoard copySource)
        {
            var columns = new PicrossActiveLine[ColumnCount];

            Parallel.ForEach(
                Enumerable.Range(0, ColumnCount),
                columnIndex =>
            {
                var columnCells = new List <PicrossCell>();
                for (int rowIndex = 0; rowIndex < RowCount; rowIndex++)
                {
                    columnCells.Add(Matrix[rowIndex, columnIndex]);
                }

                columns[columnIndex] = new PicrossActiveLine(
                    cells: columnCells,
                    copySource: copySource.Columns.ElementAt(columnIndex));
            });

            return(columns);
        }
Example #8
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));
                }
            }
        }