Example #1
0
            private void SolvePuzzle(int puzzle)
            {
                var initboard = new Board868(puzzle, new Board868(puzzle), 0);
                var res       = initboard.Solve(puzzle * puzzle);

                WriteLine(res.Count);
                foreach (var board in res)
                {
                    WriteLine(@"{0} {1} {2}", board.Row, board.Col, board.SquareSize);
                }
            }
Example #2
0
        /// <summary>
        /// Constructor for a child board in the search process
        /// </summary>
        /// <remarks>
        /// When created, this board will have the next cell in the board that needs filling in
        /// _placeRow, _placeCol.  We scan from the top down so everything above _placeRow is
        /// guaranteed to be filled in the resulting board.
        /// </remarks>
        /// <param name="boardSize">Size of the board</param>
        /// <param name="parent">Parent in the search process</param>
        /// <param name="searchRow">Where we should begin the search</param>
        public Board868(int boardSize, Board868 parent, int searchRow)
        {
            // Inherit stuff from the parent
            BoardSize = boardSize;
            _board    = (int[, ])parent._board.Clone();
            _ulSize   = parent._ulSize;
            _urSize   = parent._urSize;

            // Search out the next cell that needs filling
            for (var iRow = searchRow; iRow < BoardSize; iRow++)
            {
                for (var iCol = 0; iCol < BoardSize; iCol++)
                {
                    // Searching for an empty space
                    if (_board[iRow, iCol] == 0)
                    {
                        // If we find one then we'll start there
                        _placeCol = iCol;
                        _placeRow = iRow;
                        return;
                    }
                }
            }
        }
Example #3
0
        /// <summary>
        /// Solve the board using maxAllowed or fewer squares
        /// </summary>
        /// <remarks>
        /// This board will already be filled in completely above _curRow
        /// </remarks>
        /// <param name="maxAllowed"></param>
        /// <returns></returns>
        public List <Board868> Solve(int maxAllowed)
        {
            // List of child boards leading to a solution - no such solution yet
            List <Board868> curBest = null;

            // Are there no more squares available?
            if (maxAllowed == 0)
            {
                // Not solvable
                return(null);
            }

            // Have we filled up the board?
            if (_placeRow < 0)
            {
                // return the solution
                // ...which happens to be empty for this board - i.e., there are no
                // steps to solve this board - it's already solved - so return
                // the empty list.
                return(new List <Board868>());
            }

            // Still searching for a solution

            // Find biggest size we can fit below and to the right at the current placement location
            var biggestSize = FindBiggestFit(_placeRow, _placeCol);

            // ...and fill it up
            FillSquare(_placeRow, _placeCol, biggestSize);

            // For all squares which will fit here
            for (var iSize = biggestSize; iSize > 0; iSize--)
            {
                // Is this an acceptable size for symmetry breaking?
                if (!BreaksSymmetry(iSize))
                {
                    // Spawn a child board with the square set in place
                    var newBoard = new Board868(BoardSize, this, _placeRow);
                    // Recursively solve the new board with the minimal squares
                    var trialSolution = newBoard.Solve(maxAllowed - 1);

                    // Did we find a solution?
                    if (trialSolution != null)
                    {
                        // This is our best current solution
                        curBest = trialSolution;
                        // Ensure that future solutions do better than this
                        maxAllowed = trialSolution.Count + 1;
                        // Record the currently best size to place at this location
                        _bestSquareSize = iSize;
                    }
                }

                // Try the next smaller sized square
                // We do this by clearing the lower right border
                ClearLowerRightBorder(_placeRow, _placeCol, iSize);
            }

            // Did we find a solution among our children?
            // Add our board to it
            curBest?.Add(this);

            // Return best solution found
            return(curBest);
        }