Esempio n. 1
0
 def test_invalid_move(self):
     s = SudokuPuzzle([['A', 'B', 'C', 'D'],
                       ['C', 'D', 'A', 'B'],
                       ['B', 'A', '', ''],
                       ['D', 'C', '', '']])
     with self.assertRaises(ValueError):
         s.move('(2, 2) -> C')
Esempio n. 2
0
 def test_bad_format(self):
     s = SudokuPuzzle([['A', 'B', 'C', 'D'],
                       ['C', 'D', 'A', 'B'],
                       ['B', 'A', '', ''],
                       ['D', 'C', '', '']])
     with self.assertRaises(ValueError):
         s.move('2 2 C')
def test_has_unique_solution_doctest() -> None:
    """Test has_unique_solution on a SudokuPuzzle with a non-unique solution."""
    s = SudokuPuzzle(4, [["D", "C", "B", "A"], ["B", "A", "D", "C"],
                         ["C", " ", "A", " "], ["A", " ", "C", " "]],
                     {"A", "B", "C", "D"})

    assert s.has_unique_solution() is False
 def test_sample(self):
     s = SudokuPuzzle([['A', 'B', 'C', 'D'], ['C', 'D', 'A', 'B'],
                       ['B', 'A', '', ''], ['D', 'C', '', '']])
     new_s = s.move('(2, 2) -> D')
     s1 = SudokuPuzzle([['A', 'B', 'C', 'D'], ['C', 'D', 'A', 'B'],
                        ['B', 'A', 'D', ''], ['D', 'C', '', '']])
     self.assertEqual(str(new_s), str(s1))
Esempio n. 5
0
 def test_hint_can_reach_solution(self):
     s = SudokuPuzzle([['A', 'B', 'C', 'D'],
                       ['C', 'D', '', 'B'],
                       ['B', 'A', 'D', 'C'],
                       ['D', 'C', 'B', 'A']])
     for p in s.extensions():
         print(p)
     self.assertEqual(hint_by_depth(s, 10), '(1, 2) -> A')
Esempio n. 6
0
 def test_sample(self):
     s = SudokuPuzzle([['A', 'B', 'C', 'D'],
                       ['C', 'D', 'A', 'B'],
                       ['B', 'A', '', ''],
                       ['D', 'C', '', '']])
     new_s = s.move('(2, 2) -> D')
     s1 = SudokuPuzzle([['A', 'B', 'C', 'D'],
                        ['C', 'D', 'A', 'B'],
                        ['B', 'A', 'D', ''],
                        ['D', 'C', '', '']])
     self.assertEqual(str(new_s), str(s1))
    def test_nine_extensions(self):
        big = SudokuPuzzle([['E', 'C', '', '', 'G', '', '', '', ''],
                            ['F', '', '', 'A', 'I', 'E', '', '', ''],
                            ['', 'I', 'H', '', '', '', '', 'F', ''],
                            ['H', '', '', '', 'F', '', '', '', 'C'],
                            ['D', '', '', 'H', '', 'C', '', '', 'A'],
                            ['G', '', '', '', 'B', '', '', '', 'F'],
                            ['', 'F', '', '', '', '', 'B', 'H', ''],
                            ['', '', '', 'D', 'A', 'I', '', '', 'E'],
                            ['', '', '', '', 'H', '', '', 'G', 'I']])

        self.assertEqual(big._possible_letters(4, 4), ['E'])
        self.assertEqual(big._possible_letters(3, 3), ['E', 'G', 'I'])
def test_dfs_solver_example() -> None:
    """Test DfsSolver.solve on a SudokuPuzzle."""
    # This SudokuPuzzle is a more filled-in version of the one in the
    # example from the handout.
    s = SudokuPuzzle(4, [["C", "D", "B", "A"], ["B", "A", "D", "C"],
                         ["D", " ", "A", " "], ["A", " ", "C", " "]],
                     {"A", "B", "C", "D"})

    solver = DfsSolver()
    actual = solver.solve(s)[-1]

    expected = SudokuPuzzle(4, [["C", "D", "B", "A"], ["B", "A", "D", "C"],
                                ["D", "C", "A", "B"], ["A", "B", "C", "D"]],
                            {"A", "B", "C", "D"})

    assert actual == expected
Esempio n. 9
0
    def test_nine_extensions(self):
        big = SudokuPuzzle([
            ['E', 'C', '', '', 'G', '', '', '', ''],
            ['F', '', '', 'A', 'I', 'E', '', '', ''],
            ['', 'I', 'H', '', '', '', '', 'F', ''],
            ['H', '', '', '', 'F', '', '', '', 'C'],
            ['D', '', '', 'H', '', 'C', '', '', 'A'],
            ['G', '', '', '', 'B', '', '', '', 'F'],
            ['', 'F', '', '', '', '', 'B', 'H', ''],
            ['', '', '', 'D', 'A', 'I', '', '', 'E'],
            ['', '', '', '', 'H', '', '', 'G', 'I']])

        self.assertEqual(big._possible_letters(4, 4),
                         ['E'])
        self.assertEqual(big._possible_letters(3, 3),
                         ['E', 'G', 'I'])
Esempio n. 10
0
    def test_solve_complete(self):
        s = SudokuPuzzle([['A', 'B', '', ''], ['C', 'D', '', ''],
                          ['B', '', '', ''], ['D', '', 'A', '']])

        solutions = solve_complete(s)
        self.assertEqual(len(solutions), 2)
        for solution in solutions:
            self.assertTrue(solution.is_solved())
 def check_relatives(self, cell, solver):
     if cell.current_value:
         if SudokuPuzzle.check_relatives(self, cell, solver):
             for killer_relation in self.killer_relations:
                 if not killer_relation.check_relations(cell, solver):
                     return False
             return True
     return False
Esempio n. 12
0
 def extensions(self) -> List[RandomizedSudokuPuzzle]:
     """
     Return a list of extensions of this sudoku puzzle.
     The order of the extensions is randomized.
     """
     exts = SudokuPuzzle.extensions(self)
     shuffle(exts)
     return exts
Esempio n. 13
0
def load_puzzle(filename):
  """
  utility method for loading a SudokuPuzzle from a csv file.
  zeros should be used to denote an 'unset' cell.
  """
  puzzle = SudokuPuzzle()
  with open(filename, 'rb') as csvfile:
    reader = csv.reader(csvfile, delimiter=',')
    row_idx = 0
    for row in reader:
      col_idx = 0
      for col_str in row:
        col = int(col_str)
        if col > 0:
          puzzle.get_cell(row_idx, col_idx).fix_value(col)
        col_idx += 1
      row_idx += 1
  return puzzle
Esempio n. 14
0
 def test_solve_one(self):
     s = SudokuPuzzle([['A', 'B', 'C', 'D'], ['C', 'D', 'A', 'B'],
                       ['B', 'A', '', ''], ['D', 'C', '', '']])
     solved = solve(s)
     # Note: when we run our tests, we will replace
     # this with our own "is_solved" method
     # to make sure the puzzle is correctly solved.
     # This means you should *not* change the internal state
     # of the Sudoku Puzzle class!
     self.assertTrue(solved.is_solved())
Esempio n. 15
0
def main():
    """Prompt the user to configure and play the game.

    @rtype: None
    """
    game = input("Do you want to play Sudoku (s) or Word Ladder (w)? ")
    while game != "s" and game != "w":
        print("That is not a valid input.")
        game = input(
            "Do you want to play Sudoku (s) or Word Ladder (w)? ").lower()

    if game == "s":
        view_type = "text"
        g = SudokuPuzzle([['', '', '', 'A'], ['D', '', 'B', ''],
                          ['C', '', '', ''], ['', 'B', '', 'D']])
        print(
            "\n\nTo make a move: use the format (<row>, <column>) -> letter.")
    elif game == "w":
        view_type = input(
            "Would you like to play in text mode or web mode? ").lower()
        if view_type != "web" and view_type != "text":
            print(
                "That is not a valid mode, you will be playing in text mode.")
            view_type = "text"
        choice = input(
            "Do you want to choose your start and end words? (y/n) ")
        if choice == "y":
            print(
                "Your starting and ending words should have the same length.")
            start = input("What would you like your starting word to be? ")
            end = input("What would you like your ending word to be? ")
            while len(start) != len(end):
                print(
                    "Your starting and ending words don't have the same length. Please try again."
                )
                start = input("What would you like your starting word to be? ")
                end = input("What would you like your ending word to be? ")
        else:
            start = "rock"
            end = "taco"
        g = WordLadderPuzzle(start, end)
        print(
            "\n\nTo make a move, type a word which does not differ by more than one letter from the current word."
        )

    if view_type == "text":
        print("To quit the game, type exit.")
        print("To ask for a solution, type :SOLVE.")
        print("To ask for a hint, type :HINT.")
        print("To undo a move, type :UNDO.")
        print(
            "To look at your past moves from this current game state, type :ATTEMPTS.\n"
        )

    c = Controller(g, mode=view_type)
def test_sudoku_fail_fast_doctest() -> None:
    """Test SudokuPuzzle.fail_fast on the provided doctest."""
    s = SudokuPuzzle(4, [["A", "B", "C", "D"], ["C", "D", " ", " "],
                         [" ", " ", " ", " "], [" ", " ", " ", " "]],
                     {"A", "B", "C", "D"})

    assert s.fail_fast() is False

    s = SudokuPuzzle(4, [["B", "D", "A", "C"], ["C", "A", "B", "D"],
                         ["A", "B", " ", " "], [" ", " ", " ", " "]],
                     {"A", "B", "C", "D"})
    assert s.fail_fast() is True
class KillerSudokuPuzzle(SudokuPuzzle):
    class KillerRelation:
        def __init__(self, total_value, cells):
            self.total_value = total_value
            self.relatives = cells
            #self.set_cage_member_values()

        def set_cage_member_values(self):
            available_values = cage_member_calculator.get_cage_members(
                len(self.relatives), self.total_value)
            for cell in self.relatives:
                cell.available_values = available_values

        def have_relation(self, cell):
            return cell in self.relatives

        def check_relations(self, cell, solver):
            if self.have_relation(cell):
                assigned_relatives = [
                    c for c in self.relatives if c.current_value != 0
                ]
                if len(self.relatives) == len(assigned_relatives):
                    if sum([v.current_value
                            for v in self.relatives]) != self.total_value:
                        return False
                    else:
                        return True
                if len(self.relatives) > len(assigned_relatives):
                    if sum([v.current_value
                            for v in self.relatives]) >= self.total_value:
                        return False
            return True

    def __init__(self, initial_values):
        self.killer_relations = []
        SudokuPuzzle.__init__(self, initial_values)
        self.verify_relatives()

    def parse_puzzle(self, (initial_values, killer_relations)):
        SudokuPuzzle.parse_puzzle(self, initial_values)
        for killer_relation in killer_relations:
            total_value, relatives = killer_relation
            self.killer_relations.append(
                KillerSudokuPuzzle.KillerRelation(
                    total_value, [self.cells.get(c_id) for c_id in relatives]))
Esempio n. 18
0
        messages.append(outputs[i])
        if i < len(commands):
            messages.append('Enter a command:\n> ')
            messages.append(commands[i] + '\n')

    if filename == '':
        print(''.join(messages))
    else:
        with open(filename, 'w') as result_file:
            result_file.writelines(messages)


if __name__ == '__main__':
    from sudoku_puzzle import SudokuPuzzle
    from word_ladder_puzzle import WordLadderPuzzle
    s = SudokuPuzzle([['A', 'B', 'C', 'D'], ['C', 'D', 'A', 'B'],
                      ['B', 'A', '', ''], ['D', 'C', '', '']])

    run_controller(
        s,
        [
            '(2, 2) -> D',
            '(2, 3) -> D',  # Note: invalid move
            ':UNDO',
            '(2, 3) -> C',
            ':UNDO',
            ':ATTEMPTS',
            ':UNDO',
            ':UNDO',
            ':ATTEMPTS',
            ':SOLVE'
        ],
Esempio n. 19
0
 def test_sample3(self):
     s = SudokuPuzzle([['A', 'B', '', 'D'], ['C', 'D', '', 'B'],
                       ['B', '', '', ''], ['D', '', 'A', '']])
     self.assertEqual(s._possible_letters(2, 3), ['C'])
Esempio n. 20
0
 def test_hint_no_possible_extensions(self):
     s = SudokuPuzzle([['A', 'B', 'C', 'D'], ['C', 'D', '', 'B'],
                       ['B', 'A', 'D', 'C'], ['C', '', 'A', 'A']])
     self.assertEqual(hint_by_depth(s, 10), 'No possible extensions!')
Esempio n. 21
0
 def test_invalid_move(self):
     s = SudokuPuzzle([['A', 'B', 'C', 'D'], ['C', 'D', 'A', 'B'],
                       ['B', 'A', '', ''], ['D', 'C', '', '']])
     with self.assertRaises(ValueError):
         s.move('(2, 2) -> C')
Esempio n. 22
0
 def test_bad_format(self):
     s = SudokuPuzzle([['A', 'B', 'C', 'D'], ['C', 'D', 'A', 'B'],
                       ['B', 'A', '', ''], ['D', 'C', '', '']])
     with self.assertRaises(ValueError):
         s.move('2 2 C')
 def __init__(self, initial_values):
     self.killer_relations = []
     SudokuPuzzle.__init__(self, initial_values)
     self.verify_relatives()
Esempio n. 24
0
 def test_sample3(self):
     s = SudokuPuzzle([['A', 'B', '', 'D'],
                       ['C', 'D', '', 'B'],
                       ['B', '', '', ''],
                       ['D', '', 'A', '']])
     self.assertEqual(s._possible_letters(2, 3), ['C'])
Esempio n. 25
0
 def test_hint_already_solved(self):
     s = SudokuPuzzle([['A', 'B', 'C', 'D'], ['C', 'D', 'A', 'B'],
                       ['B', 'A', 'D', 'C'], ['D', 'C', 'B', 'A']])
     self.assertEqual(hint_by_depth(s, 10), 'Already at a solution!')
Esempio n. 26
0
 def test_hint_valid_state(self):
     s = SudokuPuzzle([['', 'B', 'C', 'D'], ['C', 'D', '', 'B'],
                       ['B', '', 'D', 'C'], ['D', 'C', 'B', '']])
     self.assertTrue(
         hint_by_depth(s, 3) in
         ['(0, 0) -> A', '(1, 2) -> A', '(2, 1) -> A', '(3, 3) -> A'])
Esempio n. 27
0
    hard_sudoku.append(
        '000570030100000020700023400000080004007004000490000605042000300000700900001800000'
    )
    hard_sudoku.append(
        '700152300000000920000300000100004708000000060000000000009000506040907000800006010'
    )
    hard_sudoku.append(
        '100007090030020008009600500005300900010080002600004000300000010040000007007000300'
    )
    hard_sudoku.append(
        '100034080000800500004060021018000000300102006000000810520070900006009000090640002'
    )
    hard_sudoku.append(
        '000920000006803000190070006230040100001000700008030029700080091000507200000064000'
    )
    hard_sudoku.append(
        '060504030100090008000000000900050006040602070700040005000000000400080001050203040'
    )
    hard_sudoku.append(
        '700000400020070080003008079900500300060020090001097006000300900030040060009001035'
    )
    hard_sudoku.append(
        '000070020800000006010205000905400008000000000300008501000302080400000009070060000'
    )

    for sudoku in easy_sudoku:
        SudokuSolver(SudokuPuzzle(sudoku)).solve()

    for sudoku in hard_sudoku:
        SudokuSolver(SudokuPuzzle(sudoku)).solve()
Esempio n. 28
0
                return [(puzzle.generate_hint(extension), True)]

            extension_hints = possible_hints(extension, n - 1)

            for hint in extension_hints:
                if hint[1]:  # if this hint will lead to a solution
                    return [(puzzle.generate_hint(extension), True)]

            # Else all the hints in extension do not lead to a solution
            # Only adds if lst is empty, since only one hint is necessary
            if len(lst) == 0 and len(extension_hints) > 0:
                lst.append((puzzle.generate_hint(extensions[0]), False))

    return lst


if __name__ == '__main__':
    from sudoku_puzzle import SudokuPuzzle
    from word_ladder_puzzle import WordLadderPuzzle
    s = SudokuPuzzle([['A', 'D', 'C', ''], ['B', 'C', '', ''],
                      ['C', 'B', 'A', 'D'], ['D', 'A', 'B', 'C']])
    print(s.extensions()[0])
    print('The puzzle:')
    print(s)
    print('SOLVE')
    solve(s, True)
    print('\nSOLVE-ALL')
    solve_complete(s, True)
    print('\nHINT 1')
    print(hint_by_depth(s, 1))
Esempio n. 29
0
 def test_hint_can_reach_solution(self):
     s = SudokuPuzzle([['A', 'B', 'C', 'D'], ['C', 'D', '', 'B'],
                       ['B', 'A', 'D', 'C'], ['D', 'C', 'B', 'A']])
     for p in s.extensions():
         print(p)
     self.assertEqual(hint_by_depth(s, 10), '(1, 2) -> A')