/** * Default constructor based on provided initial board. * * @param initialBoard Array with the board definition. * @param parameters Optional parameters * * @see #PARAM_DO_NOT_SOLVE * @see #PARAM_DO_NOT_TRANSFORM * @see #PARAM_GEN_RND_BOARD */ public SudokuGenerator(int[,] initialBoard, params char[] parameters) { setParameters(parameters); initInternalVars(); if (initialBoard == null) { generatorState = GENERATOR_INIT_FAILED; addMessage("(SudokuGenerator) Generator not initialized - null initial board.", MSG_ERROR); } else if (initialBoard.GetLength(0) != BOARD_SIZE) { generatorState = GENERATOR_INIT_FAILED; addMessage("(SudokuGenerator) Generator not initialized - incorrect number of rows in initial board, is: " + initialBoard.GetLength(0) + ", expected: " + BOARD_SIZE + ".", MSG_ERROR); } else if (initialBoard.GetLength(1) != BOARD_SIZE) { generatorState = GENERATOR_INIT_FAILED; addMessage("(SudokuGenerator) Generator not initialized - incorrect number of columns in initial board, is: " + initialBoard.GetLength(1) + ", expected: " + BOARD_SIZE + ".", MSG_ERROR); } else if (SudokuStore.checkPuzzle(initialBoard) == false) { generatorState = GENERATOR_INIT_FAILED; addMessage("(SudokuGenerator) Generator not initialized - initial board contains an error.", MSG_ERROR); } else { int[,] board = SudokuStore.boardCopy(initialBoard); if (transformBeforeGeneration == true) { boardInit(SudokuStore.seqOfRandomBoardTransf(board), "transformed board provided by the user"); } else { boardInit(board, "board provided by the user"); } } }
/** * Test scenario implementation. * @param testId Test id. * @param threadId Thread id. * @return True is test successful, otherwise false. */ static bool runTest(int testId, int threadId) { SudokuSolver solverGen, solverInit; SudokuGenerator g; int solUnq; int[,] genPuzzle; int[,] solvedGen, solvedInit, initBoard; bool testResult = true; switch (testId) { case 0: for (int example = 0; example < SudokuPuzzles.NUMBER_OF_PUZZLE_EXAMPLES; example++) { g = new SudokuGenerator(example, SudokuGenerator.PARAM_DO_NOT_TRANSFORM); genPuzzle = g.generate(); solverGen = new SudokuSolver(genPuzzle); ErrorCodes.consolePrintlnIfError(solverGen.solve()); solverInit = new SudokuSolver(example); ErrorCodes.consolePrintlnIfError(solverInit.solve()); solUnq = solverGen.checkIfUniqueSolution(); ErrorCodes.consolePrintlnIfError(solUnq); solvedGen = solverGen.getSolvedBoard(); solvedInit = solverInit.getSolvedBoard(); if ((solUnq == SudokuSolver.SOLUTION_UNIQUE) && (SudokuStore.boardsAreEqual(solvedGen, solvedInit) == true)) { //SudokuStore.consolePrintln("(Thread: " + threadId + ") " + "Test: " + testId + ", generate by example number, example: " + example + ", solution unique and correct: YES, time (g, s1, s2): " + g.getComputingTime() + " s., " + solverGen.getComputingTime() + " s., " + solverInit.getComputingTime() + " s."); } else { testResult = false; SudokuStore.consolePrintln("(Thread: " + threadId + ") " + "Test: " + testId + ", generate by example number, example: " + example + ", solution unique and correct: NO, time (g, s1, s2): " + g.getComputingTime() + " s., " + solverGen.getComputingTime() + " s., " + solverInit.getComputingTime() + " s."); Console.WriteLine("Initial board"); SudokuStore.consolePrintBoard(SudokuStore.getPuzzleExample(example)); Console.WriteLine("Generated puzzle"); SudokuStore.consolePrintBoard(genPuzzle); Console.WriteLine("Solved initial board"); SudokuStore.consolePrintBoard(solvedInit); Console.WriteLine("Solved generated puzzle"); SudokuStore.consolePrintBoard(solvedGen); } } break; case 1: for (int example = 0; example < SudokuPuzzles.NUMBER_OF_PUZZLE_EXAMPLES; example++) { initBoard = SudokuStore.getPuzzleExample(example); g = new SudokuGenerator(initBoard, SudokuGenerator.PARAM_DO_NOT_TRANSFORM, SudokuGenerator.PARAM_DO_NOT_SOLVE); genPuzzle = g.generate(); solverGen = new SudokuSolver(genPuzzle); ErrorCodes.consolePrintlnIfError(solverGen.solve()); solverInit = new SudokuSolver(initBoard); ErrorCodes.consolePrintlnIfError(solverInit.solve()); solUnq = solverGen.checkIfUniqueSolution(); ErrorCodes.consolePrintlnIfError(solUnq); solvedGen = solverGen.getSolvedBoard(); solvedInit = solverInit.getSolvedBoard(); if ((solUnq == SudokuSolver.SOLUTION_UNIQUE) && (SudokuStore.boardsAreEqual(solvedGen, solvedInit) == true)) { //SudokuStore.consolePrintln("(Thread: " + threadId + ") " + "Test: " + testId + ", generate by example board, example: " + example + ", solution unique and correct: YES, time (g, s1, s2): " + g.getComputingTime() + " s., " + solverGen.getComputingTime() + " s., " + solverInit.getComputingTime() + " s."); } else { testResult = false; SudokuStore.consolePrintln("(Thread: " + threadId + ") " + "Test: " + testId + ", generate by example board, example: " + example + ", solution unique and correct: NO, time (g, s1, s2): " + g.getComputingTime() + " s., " + solverGen.getComputingTime() + " s., " + solverInit.getComputingTime() + " s."); Console.WriteLine("Initial board"); SudokuStore.consolePrintBoard(initBoard); Console.WriteLine("Generated puzzle"); SudokuStore.consolePrintBoard(genPuzzle); Console.WriteLine("Solved initial board"); SudokuStore.consolePrintBoard(solvedInit); Console.WriteLine("Solved generated puzzle"); SudokuStore.consolePrintBoard(solvedGen); } } break; case 2: for (int example = 0; example < SudokuPuzzles.NUMBER_OF_PUZZLE_EXAMPLES; example++) { g = new SudokuGenerator(example); genPuzzle = g.generate(); solverGen = new SudokuSolver(genPuzzle); ErrorCodes.consolePrintlnIfError(solverGen.solve()); solUnq = solverGen.checkIfUniqueSolution(); ErrorCodes.consolePrintlnIfError(solUnq); solvedGen = solverGen.getSolvedBoard(); if ((solUnq == SudokuSolver.SOLUTION_UNIQUE) && (SudokuStore.checkPuzzle(genPuzzle) == true)) { //SudokuStore.consolePrintln("(Thread: " + threadId + ") " + "Test: " + testId + ", generate by example number, example: " + example + ", solution unique and correct: YES, time (g, s): " + g.getComputingTime() + " s., " + solverGen.getComputingTime() + " s., "); } else { testResult = false; SudokuStore.consolePrintln("(Thread: " + threadId + ") " + "Test: " + testId + ", generate by example number, example: " + example + ", solution unique and correct: NO, time (g, s): " + g.getComputingTime() + " s., " + solverGen.getComputingTime() + " s., "); Console.WriteLine("Generated puzzle"); SudokuStore.consolePrintBoard(genPuzzle); Console.WriteLine("Solved generated puzzle"); SudokuStore.consolePrintBoard(solvedGen); } } break; case 3: for (int example = 0; example < SudokuPuzzles.NUMBER_OF_PUZZLE_EXAMPLES; example++) { initBoard = SudokuStore.getPuzzleExample(example); g = new SudokuGenerator(initBoard, SudokuGenerator.PARAM_DO_NOT_SOLVE); genPuzzle = g.generate(); solverGen = new SudokuSolver(genPuzzle); ErrorCodes.consolePrintlnIfError(solverGen.solve()); solUnq = solverGen.checkIfUniqueSolution(); ErrorCodes.consolePrintlnIfError(solUnq); solvedGen = solverGen.getSolvedBoard(); if ((solUnq == SudokuSolver.SOLUTION_UNIQUE) && (SudokuStore.checkPuzzle(genPuzzle) == true)) { //SudokuStore.consolePrintln("(Thread: " + threadId + ") " + "Test: " + testId + ", generate by example board, example: " + example + ", solution unique and correct: YES, time (g, s): " + g.getComputingTime() + " s., " + solverGen.getComputingTime() + " s., "); } else { testResult = false; SudokuStore.consolePrintln("(Thread: " + threadId + ") " + "Test: " + testId + ", generate by example board, example: " + example + ", solution unique and correct: NO, time (g, s): " + g.getComputingTime() + " s., " + solverGen.getComputingTime() + " s., "); Console.WriteLine("Generated puzzle"); SudokuStore.consolePrintBoard(genPuzzle); Console.WriteLine("Solved initial board"); SudokuStore.consolePrintBoard(solvedGen); } } break; case 5: initBoard = SudokuPuzzles.PUZZLE_EMPTY; g = new SudokuGenerator(initBoard); genPuzzle = g.generate(); solverGen = new SudokuSolver(genPuzzle); ErrorCodes.consolePrintlnIfError(solverGen.solve()); solUnq = solverGen.checkIfUniqueSolution(); ErrorCodes.consolePrintlnIfError(solUnq); solvedGen = solverGen.getSolvedBoard(); if ((solUnq == SudokuSolver.SOLUTION_UNIQUE) && (SudokuStore.checkPuzzle(genPuzzle) == true)) { //SudokuStore.consolePrintln("(Thread: " + threadId + ") " + "Test: " + testId + ", generate by empty board, solution unique and correct: YES, time (g, s): " + g.getComputingTime() + " s., " + solverGen.getComputingTime() + " s., "); } else { testResult = false; SudokuStore.consolePrintln("(Thread: " + threadId + ") " + "Test: " + testId + ", generate by empty board, solution unique and correct: NO, time (g, s): " + g.getComputingTime() + " s., " + solverGen.getComputingTime() + " s., "); Console.WriteLine("Generated puzzle"); SudokuStore.consolePrintBoard(genPuzzle); Console.WriteLine("Solved initial board"); SudokuStore.consolePrintBoard(solvedGen); } break; case 6: initBoard = SudokuPuzzles.PUZZLE_EMPTY; g = new SudokuGenerator(initBoard, SudokuGenerator.PARAM_DO_NOT_SOLVE); if (g.getGeneratorState() == SudokuGenerator.GENERATOR_INIT_FAILED) { SudokuStore.consolePrintln("(Thread: " + threadId + ") " + "Test: " + testId + ", generate by empty board, solution unique and correct: YES, time (g, s): "); } else { testResult = false; SudokuStore.consolePrintln("(Thread: " + threadId + ") " + "Test: " + testId + ", generate by empty board, solution unique and correct: NO, time (g, s): "); SudokuStore.consolePrintln("Generator state: " + g.getGeneratorState()); Console.WriteLine(g.getMessages()); } break; case 7: initBoard = SudokuPuzzles.PUZZLE_ERROR; g = new SudokuGenerator(initBoard, SudokuGenerator.PARAM_DO_NOT_SOLVE); if (g.getGeneratorState() == SudokuGenerator.GENERATOR_INIT_FAILED) { SudokuStore.consolePrintln("(Thread: " + threadId + ") " + "Test: " + testId + ", generate by PUZZLE_ERROR + PARAM_DO_NOT_SOLVE, init failed: YES."); } else { testResult = false; SudokuStore.consolePrintln("(Thread: " + threadId + ") " + "Test: " + testId + ", generate by PUZZLE_ERROR + PARAM_DO_NOT_SOLVE, init failed: NO."); SudokuStore.consolePrintln("Generator state: " + g.getGeneratorState()); Console.WriteLine(g.getMessages()); } break; case 8: initBoard = SudokuPuzzles.PUZZLE_NON_UNIQUE_SOLUTION; g = new SudokuGenerator(initBoard); genPuzzle = g.generate(); solverGen = new SudokuSolver(genPuzzle); ErrorCodes.consolePrintlnIfError(solverGen.solve()); solUnq = solverGen.checkIfUniqueSolution(); ErrorCodes.consolePrintlnIfError(solUnq); solvedGen = solverGen.getSolvedBoard(); if ((solUnq == SudokuSolver.SOLUTION_UNIQUE) && (SudokuStore.checkPuzzle(genPuzzle) == true)) { //SudokuStore.consolePrintln("(Thread: " + threadId + ") " + "Test: " + testId + ", generate by empty board, solution unique and correct: YES, time (g, s): " + g.getComputingTime() + " s., " + solverGen.getComputingTime() + " s., "); } else { testResult = false; SudokuStore.consolePrintln("(Thread: " + threadId + ") " + "Test: " + testId + ", generate by empty board, solution unique and correct: NO, time (g, s): " + g.getComputingTime() + " s., " + solverGen.getComputingTime() + " s., "); Console.WriteLine("Generated puzzle"); SudokuStore.consolePrintBoard(genPuzzle); Console.WriteLine("Solved initial board"); SudokuStore.consolePrintBoard(solvedGen); } break; case 9: initBoard = SudokuPuzzles.PUZZLE_NON_UNIQUE_SOLUTION; g = new SudokuGenerator(initBoard, SudokuGenerator.PARAM_DO_NOT_SOLVE); if (g.getGeneratorState() == SudokuGenerator.GENERATOR_INIT_FAILED) { SudokuStore.consolePrintln("(Thread: " + threadId + ") " + "Test: " + testId + ", generate by PUZZLE_NON_UNIQUE_SOLUTION + PARAM_DO_NOT_SOLVE, init failed: YES."); } else { testResult = false; SudokuStore.consolePrintln("(Thread: " + threadId + ") " + "Test: " + testId + ", generate by PUZZLE_NON_UNIQUE_SOLUTION + PARAM_DO_NOT_SOLVE, init failed: NO."); SudokuStore.consolePrintln("Generator state: " + g.getGeneratorState()); Console.WriteLine(g.getMessages()); } break; } if (testResult == true) { SudokuStore.consolePrintln("(Thread: " + threadId + ") " + "Test: " + testId + " >>>>>>>>>>>>>>>>>>>>>> SudokuGenerator, result: OK"); } else { SudokuStore.consolePrintln("(Thread: " + threadId + ") " + "Test: " + testId + " >>>>>>>>>>>>>>>>>>>>>> SudokuGenerator, result: ERROR"); } return(testResult); }
/** * Board initialization method. * @param initBoard Initial board. * @param info The string to pass to the msg builder. */ private void boardInit(int[,] initBoard, String info) { SudokuSolver puzzle; if ((initBoard == null) && (generateRandomBoard == true)) { puzzle = new SudokuSolver(SudokuPuzzles.PUZZLE_EMPTY); puzzle.solve(); if (puzzle.getSolvingState() == SudokuSolver.SOLVING_STATE_SOLVED) { sudokuBoard = puzzle.solvedBoard; addMessage("(SudokuGenerator) Generator initialized using random board (" + info + ").", MSG_INFO); generatorState = GENERATOR_INIT_FINISHED; return; } else { addMessage("(SudokuGenerator) Generator initialization using random board (" + info + ") failed. Board with error?", MSG_ERROR); addMessage(puzzle.getLastErrorMessage(), MSG_ERROR); generatorState = GENERATOR_INIT_FAILED; return; } } if (SudokuStore.checkPuzzle(initBoard) == false) { generatorState = GENERATOR_INIT_FAILED; addMessage("(SudokuGenerator) Generator initialization (" + info + ") failed. Board with error?", MSG_ERROR); return; } if (solveBeforeGeneration == true) { puzzle = new SudokuSolver(initBoard); puzzle.solve(); if (puzzle.getSolvingState() == SudokuSolver.SOLVING_STATE_SOLVED) { sudokuBoard = puzzle.solvedBoard; addMessage("(SudokuGenerator) Generator initialized usign provided board + finding solution (" + info + ").", MSG_INFO); generatorState = GENERATOR_INIT_FINISHED; return; } else { addMessage("(SudokuGenerator) Generator initialization usign provided board + finding solution (" + info + ") failed. Board with error?", MSG_ERROR); addMessage(puzzle.getLastErrorMessage(), MSG_ERROR); generatorState = GENERATOR_INIT_FAILED; return; } } int[,] board = initBoard; puzzle = new SudokuSolver(board); if (puzzle.checkIfUniqueSolution() == SudokuSolver.SOLUTION_UNIQUE) { sudokuBoard = board; addMessage("(SudokuGenerator) Generator initialized usign provided board (" + info + ").", MSG_INFO); generatorState = GENERATOR_INIT_FINISHED; return; } else { addMessage("(SudokuGenerator) Generator initialization usign provided board (" + info + ") failed. Solution not exists or is non unique.", MSG_ERROR); addMessage(puzzle.getLastErrorMessage(), MSG_ERROR); generatorState = GENERATOR_INIT_FAILED; return; } }