예제 #1
0
 def test_solver(self):
     """Use PuzzleTester class to test SudokuSolver"""
     for method in su.SOLVERS:
         with self.subTest(f"method: {method}"):
             solver = su.SudokuSolver(method=method)
             self.assertEqual(5, self.pt.num_test_cases())
             self.assertEqual(5, self.pt.run_tests(solver))
예제 #2
0
    def test_results(self):
        """Check test results"""
        solver = su.SudokuSolver()
        self.assertEqual(3, len(self.pt.get_test_results()))
        self.pt.run_tests(solver)
        self.assertEqual(4, len(self.pt.get_test_results()))
        self.assertEqual(1, len(self.pt.get_solver_labels()))

        results = self.pt.get_test_results()
        newpt = pt.PuzzleTester(puzzle_class=su.SudokuPuzzle)
        newpt.set_test_results(results)
        self.assertEqual(self.pt.get_test_results(), newpt.get_test_results())
예제 #3
0
 def test_all_solvers_all_puzzles(self):
     """Test that all available solvers can solve all test puzzles in sudoku.py"""
     for x in su.SOLVERS:
         if x == 'backtracking':
             continue
         solver = su.SudokuSolver(method=x)
         for p in su.SAMPLE_PUZZLES:
             with self.subTest(f"Method {x} on puzzle {p['label']}"):
                 puz = su.SudokuPuzzle(
                     starting_grid=ls.from_string(p['puzzle']))
                 self.assertTrue(solver.solve(puz))
                 self.assertTrue(puz.is_solved())
     return
예제 #4
0
    def test_all_solvers(self):
        """Test that all available solvers are supported"""
        for x in su.SOLVERS:
            with self.subTest(f"Method {x}"):
                solver = su.SudokuSolver(method=x)
                self.p.init_puzzle(EASY_PUZZLE)
                self.assertTrue(solver.solve(self.p))
                self.assertTrue(self.p.is_solved())

                self.p.init_puzzle(HARD_PUZZLE)
                self.assertTrue(solver.solve(self.p))
                self.assertTrue(self.p.is_solved())
        return
예제 #5
0
    def test_solver(self):
        """SudokuSolver can be vaguely useful"""
        with self.subTest("Default solver works"):
            solver = su.SudokuSolver()
            self.p.init_puzzle(EASY_PUZZLE)
            self.assertTrue(solver.solve(self.p))

            self.p.init_puzzle(HARD_PUZZLE)
            self.assertTrue(solver.solve(self.p))

        with self.subTest("Bad solver raises exception"):
            self.assertRaises(ValueError, su.SudokuSolver, method="banana")
        return
예제 #6
0
    def test_all_solvers_multisolution_puzzles(self):
        """Test all solvers on how they handle puzzles with multiple solutions"""
        for m in su.SOLVERS:
            solver = su.SudokuSolver(method=m)
            for i, puz in enumerate(MULTI_SOLUTION_STRINGS):
                with self.subTest(f"Method {m}; Multi-solution puzzle {i}"):
                    # Failure here would be test data error
                    self.p.init_puzzle(ls.from_string(puz))
                    self.assertTrue(self.p.is_valid())
                    self.assertFalse(self.p.is_solved())

                    # Requirement is to return *a* solution
                    self.assertTrue(solver.solve(self.p))
                    self.assertTrue(self.p.is_solved())

                    # TODO: Mechanism to report multiple solutions? SAT could
                    # do it. Others might take too long.
        return
예제 #7
0
    def test_all_solvers_unsolvable_puzzles(self):
        """Test all solvers on how they handle unsolvable puzzles"""
        for m in su.SOLVERS:
            solver = su.SudokuSolver(method=m)
            for i, puz in enumerate(UNSOLVABLE_STRINGS):
                with self.subTest(f"Method {m}; Unsolvable puzzle {i}"):
                    # These "unsolvable" puzzles are still valid initially
                    self.p.init_puzzle(ls.from_string(puz))
                    self.assertTrue(self.p.is_valid())
                    self.assertFalse(self.p.is_solved())

                    # Check method correctly reports it cannot be solved
                    self.assertFalse(solver.solve(self.p))

                    # Solver should leave puzzle in valid, but unsolved state
                    self.assertTrue(self.p.is_valid())
                    self.assertFalse(self.p.is_solved())
        return
예제 #8
0
    def test_all_solvers_all_sizes(self):
        """Solvers can solve different sizes of puzzles"""
        for m in su.SOLVERS:
            solver = su.SudokuSolver(method=m)
            for i, puz in enumerate(TEST_PUZZLE_STRINGS):
                # Skip backtracking on larger puzzles
                if m == 'backtracking' and len(puz) > 81:
                    continue

                with self.subTest(f"Method {m}; Puzzle {i} (len={len(puz)})"):
                    p = su.SudokuPuzzle(starting_grid=ls.from_string(puz))
                    s = su.SudokuPuzzle(
                        starting_grid=ls.from_string(TEST_SOLUTION_STRINGS[i]))
                    self.assertTrue(p.is_valid())
                    self.assertFalse(p.is_solved())
                    self.assertTrue(solver.solve(p))
                    self.assertTrue(p.is_solved())
                    self.assertEqual(str(s), str(p))
        return
예제 #9
0
 def test_callback(self):
     """Test that callback is called...back"""
     self._callback_called = False
     solver = su.SudokuSolver()
     self.pt.run_tests(solver, callback=self.callback)
     self.assertTrue(self._callback_called)