Esempio n. 1
0
		/**
		 * Sub-square identification on the Sudoku board
		 * based on the cell position
		 * @param emptyCell   Cell object, including cell position
		 * @return             Sub-square left-top and right-bottom indexes.
		 */
		internal static SubSquare getSubSqare(BoardCell boardCell) {
			return getSubSqare(boardCell.rowIndex, boardCell.colIndex);
		}
		/**
		 * Get all current board cells.
		 * @return  Array of current board cells.
		 */
		public BoardCell[] getAllBoardCells() {
			BoardCell[] boardCells = new BoardCell[BOARD_CELLS_NUMBER];
			int cellIndex = 0;
			for (int i = 0; i < BOARD_SIZE; i++)
				for (int j = 0; j < BOARD_SIZE; j++) {
					boardCells[cellIndex] = new BoardCell(i, j, sudokuBoard[i, j]);
					cellIndex++;
				}
			return boardCells;
		}
Esempio n. 3
0
		/**
		 * Returns string representation of the 'path' leading to the solution.
		 * @param solutionBoardCells  Array representing sequence of board cells.
		 * @return                      String representation of sequence of board cells.
		 */
		public static String solutionPathToString(BoardCell[] solutionBoardCells) {
			String solutionPath = "";
			solutionPath = solutionPath + " --------------- " + NEW_LINE_SEPARATOR;
			solutionPath = solutionPath + "| id | i, j | d |" + NEW_LINE_SEPARATOR;
			solutionPath = solutionPath + "|----|----- |---|" + NEW_LINE_SEPARATOR;
			if (solutionBoardCells != null)
				for (int i = 0; i < solutionBoardCells.Length; i++) {
					BoardCell b = solutionBoardCells[i];
					if (i + 1 < 10) solutionPath = solutionPath + "|  ";
					else solutionPath = solutionPath + "| ";
					solutionPath = solutionPath + (i+1) + " | " + (b.rowIndex+1) + ", " + (b.colIndex + 1) + " | " + b.digit + " |" + NEW_LINE_SEPARATOR;
				}
			solutionPath = solutionPath + " --------------- " + NEW_LINE_SEPARATOR;
			return solutionPath;
		}
		/**
		 * Counts number of digits still free
		 * for a specific cell.
		 *
		 * @param boardCell
		 */
		private void countDigitsStillFree(BoardCell boardCell) {
			int[] digitsStillFree = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
			int emptyCellsNumber = 0;
			for (int j = 0; j < BOARD_SIZE; j++) {
				int boardDigit = sudokuBoard[boardCell.rowIndex, j];
				if (boardDigit != CELL_EMPTY)
					digitsStillFree[boardDigit] = DIGIT_IN_USE;
				else if (j != boardCell.colIndex)
					emptyCellsNumber++;
			}
			for (int i = 0; i < BOARD_SIZE; i++) {
				int boardDigit = sudokuBoard[i, boardCell.colIndex];
				if (boardDigit != CELL_EMPTY)
					digitsStillFree[boardDigit] = DIGIT_IN_USE;
				else if (i != boardCell.rowIndex)
					emptyCellsNumber++;
			}
			SubSquare sub = SubSquare.getSubSqare(boardCell);
			/*
			 * Mark digits used in a sub-square.
			 */
			for (int i = sub.rowMin; i < sub.rowMax; i++)
				for (int j = sub.colMin; j < sub.colMax; j++) {
					int boardDigit = sudokuBoard[i, j];
					if (boardDigit != CELL_EMPTY)
						digitsStillFree[boardDigit] = DIGIT_IN_USE;
					else if ((i != boardCell.rowIndex) && (j != boardCell.colIndex))
						emptyCellsNumber++;
				}
			/*
			 * Find number of still free digits to use.
			 */
			digitsStillFree[boardCell.digit] = 0;
			boardCell.digitsStillFreeNumber = emptyCellsNumber;
			for (int digit = 1; digit < 10; digit++)
				if (digitsStillFree[digit] == DIGIT_STILL_FREE)
					boardCell.digitsStillFreeNumber++;
		}
		/**
		 * Sudoku puzzle generator.
		 *
		 * @return   Sudoku puzzle if process finished correctly, otherwise null.
		 */
		public int[,] generate() {
			if (generatorState != GENERATOR_INIT_FINISHED) {
				generatorState = GENERATOR_GEN_NOT_STARTED;
				addMessage("(SudokuGenerator) Generation process not started due to incorrect initialization.", MSG_ERROR);
				return null;
			}
			long solvingStartTime = DateTimeX.currentTimeMillis();
			generatorState = GENERATOR_GEN_STARTED;
			addMessage("(SudokuGenerator) Generation process started.", MSG_INFO);
			if (randomizeFilledCells == true)
				addMessage("(SudokuGenerator) >>> Will randomize filled cells within cells with the same impact.", MSG_INFO);
			boardCells = new BoardCell[BOARD_CELLS_NUMBER];
			int cellIndex = 0;
			for (int i = 0; i < BOARD_SIZE; i++)
				for (int j = 0; j < BOARD_SIZE; j++) {
					int d = sudokuBoard[i, j];
					if (d != CELL_EMPTY) {
						boardCells[cellIndex] = new BoardCell(i, j, d);
						cellIndex++;
					}
				}
			int filledCells = cellIndex;
			for (int i = 0; i < BOARD_SIZE; i++)
				for (int j = 0; j < BOARD_SIZE; j++) {
					int d = sudokuBoard[i, j];
					if (d == CELL_EMPTY) {
						boardCells[cellIndex] = new BoardCell(i, j, d);
						cellIndex++;
					}
				}
			updateDigitsStillFreeCounts();
			sortBoardCells(0, filledCells - 1);
			do {
				int r = 0;
				int i = boardCells[r].rowIndex;
				int j = boardCells[r].colIndex;
				int d = sudokuBoard[i, j];
				sudokuBoard[i, j] = CELL_EMPTY;
				SudokuSolver s = new SudokuSolver(sudokuBoard);
				if (s.checkIfUniqueSolution() != SudokuSolver.SOLUTION_UNIQUE)
					sudokuBoard[i, j] = d;
				int lastIndex = filledCells - 1;
				if (r < lastIndex) {
					BoardCell b1 = boardCells[r];
					BoardCell b2 = boardCells[lastIndex];
					boardCells[lastIndex] = b1;
					boardCells[r] = b2;
				}
				filledCells--;
				updateDigitsStillFreeCounts();
				if (filledCells > 0) sortBoardCells(0, filledCells - 1);
			} while (filledCells > 0);
			long solvingEndTime = DateTimeX.currentTimeMillis();
			computingTime = (solvingEndTime - solvingStartTime) / 1000.0;
			generatorState = GENERATOR_GEN_FINISHED;
			addMessage("(SudokuGenerator) Generation process finished, computing time: " + computingTime + " s.", MSG_INFO);
			return sudokuBoard;
		}
        /**
         * Counts number of digits still free
         * for a specific cell.
         *
         * @param boardCell
         */
        private void countDigitsStillFree(BoardCell boardCell)
        {
            int[] digitsStillFree  = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            int   emptyCellsNumber = 0;

            for (int j = 0; j < BOARD_SIZE; j++)
            {
                int boardDigit = sudokuBoard[boardCell.rowIndex, j];
                if (boardDigit != CELL_EMPTY)
                {
                    digitsStillFree[boardDigit] = DIGIT_IN_USE;
                }
                else if (j != boardCell.colIndex)
                {
                    emptyCellsNumber++;
                }
            }
            for (int i = 0; i < BOARD_SIZE; i++)
            {
                int boardDigit = sudokuBoard[i, boardCell.colIndex];
                if (boardDigit != CELL_EMPTY)
                {
                    digitsStillFree[boardDigit] = DIGIT_IN_USE;
                }
                else if (i != boardCell.rowIndex)
                {
                    emptyCellsNumber++;
                }
            }
            SubSquare sub = SubSquare.getSubSqare(boardCell);

            /*
             * Mark digits used in a sub-square.
             */
            for (int i = sub.rowMin; i < sub.rowMax; i++)
            {
                for (int j = sub.colMin; j < sub.colMax; j++)
                {
                    int boardDigit = sudokuBoard[i, j];
                    if (boardDigit != CELL_EMPTY)
                    {
                        digitsStillFree[boardDigit] = DIGIT_IN_USE;
                    }
                    else if ((i != boardCell.rowIndex) && (j != boardCell.colIndex))
                    {
                        emptyCellsNumber++;
                    }
                }
            }

            /*
             * Find number of still free digits to use.
             */
            digitsStillFree[boardCell.digit] = 0;
            boardCell.digitsStillFreeNumber  = emptyCellsNumber;
            for (int digit = 1; digit < 10; digit++)
            {
                if (digitsStillFree[digit] == DIGIT_STILL_FREE)
                {
                    boardCell.digitsStillFreeNumber++;
                }
            }
        }
        /**
         * Sudoku puzzle generator.
         *
         * @return   Sudoku puzzle if process finished correctly, otherwise null.
         */
        public int[,] generate()
        {
            if (generatorState != GENERATOR_INIT_FINISHED)
            {
                generatorState = GENERATOR_GEN_NOT_STARTED;
                addMessage("(SudokuGenerator) Generation process not started due to incorrect initialization.", MSG_ERROR);
                return(null);
            }
            long solvingStartTime = DateTimeX.currentTimeMillis();

            generatorState = GENERATOR_GEN_STARTED;
            addMessage("(SudokuGenerator) Generation process started.", MSG_INFO);
            if (randomizeFilledCells == true)
            {
                addMessage("(SudokuGenerator) >>> Will randomize filled cells within cells with the same impact.", MSG_INFO);
            }
            boardCells = new BoardCell[BOARD_CELLS_NUMBER];
            int cellIndex = 0;

            for (int i = 0; i < BOARD_SIZE; i++)
            {
                for (int j = 0; j < BOARD_SIZE; j++)
                {
                    int d = sudokuBoard[i, j];
                    if (d != CELL_EMPTY)
                    {
                        boardCells[cellIndex] = new BoardCell(i, j, d);
                        cellIndex++;
                    }
                }
            }
            int filledCells = cellIndex;

            for (int i = 0; i < BOARD_SIZE; i++)
            {
                for (int j = 0; j < BOARD_SIZE; j++)
                {
                    int d = sudokuBoard[i, j];
                    if (d == CELL_EMPTY)
                    {
                        boardCells[cellIndex] = new BoardCell(i, j, d);
                        cellIndex++;
                    }
                }
            }
            updateDigitsStillFreeCounts();
            sortBoardCells(0, filledCells - 1);
            do
            {
                int r = 0;
                int i = boardCells[r].rowIndex;
                int j = boardCells[r].colIndex;
                int d = sudokuBoard[i, j];
                sudokuBoard[i, j] = CELL_EMPTY;
                SudokuSolver s = new SudokuSolver(sudokuBoard);
                if (s.checkIfUniqueSolution() != SudokuSolver.SOLUTION_UNIQUE)
                {
                    sudokuBoard[i, j] = d;
                }
                int lastIndex = filledCells - 1;
                if (r < lastIndex)
                {
                    BoardCell b1 = boardCells[r];
                    BoardCell b2 = boardCells[lastIndex];
                    boardCells[lastIndex] = b1;
                    boardCells[r]         = b2;
                }
                filledCells--;
                updateDigitsStillFreeCounts();
                if (filledCells > 0)
                {
                    sortBoardCells(0, filledCells - 1);
                }
            } while (filledCells > 0);
            long solvingEndTime = DateTimeX.currentTimeMillis();

            computingTime  = (solvingEndTime - solvingStartTime) / 1000.0;
            generatorState = GENERATOR_GEN_FINISHED;
            addMessage("(SudokuGenerator) Generation process finished, computing time: " + computingTime + " s.", MSG_INFO);
            return(sudokuBoard);
        }