Пример #1
0
        public PicrossBoard(PicrossBoard copySource)
        {
            Puzzle      = copySource.Puzzle;
            RowCount    = Puzzle.RowCount;
            ColumnCount = Puzzle.ColumnCount;

            Matrix = new PicrossCell[RowCount, ColumnCount];
            for (int rowIndex = 0; rowIndex < RowCount; rowIndex++)
            {
                for (int columnIndex = 0; columnIndex < ColumnCount; columnIndex++)
                {
                    PicrossCell otherCell = copySource.Matrix[rowIndex, columnIndex];
                    Matrix[rowIndex, columnIndex] = new PicrossCell()
                    {
                        State  = otherCell.State,
                        Row    = rowIndex,
                        Column = columnIndex
                    };
                }
            }

            Columns     = CopyColumns(copySource);
            Rows        = CopyRows(copySource);
            ActiveLines = (new[] { Columns, Rows }).SelectMany(collection => collection);
        }
Пример #2
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);
                }
            }
        }
Пример #3
0
        public void Copy(PicrossBoard source)
        {
            if (Puzzle != source.Puzzle)
            {
                throw new ArgumentException();
            }

            for (int rowIndex = 0; rowIndex < RowCount; rowIndex++)
            {
                for (int columnIndex = 0; columnIndex < ColumnCount; columnIndex++)
                {
                    PicrossCell otherCell = source.Matrix[rowIndex, columnIndex];
                    Matrix[rowIndex, columnIndex].State = otherCell.State;
                }
            }
        }
Пример #4
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);
        }
Пример #5
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);
        }
Пример #6
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);
        }
Пример #7
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));
                }
            }
        }