Commits

Josh VanderLinden committed 5be2dcf

Refactoring.

I moved the decorators out into their own module. Also did some more reorganizing of the code in the main module. Adding a SQLite database to store solutions.

Comments (0)

Files changed (4)

sudokulib/db_structure.sql

+create table solution (id integer primary key autoincrement, grid_size integer, solution text unique);
+create table starting_grid (id integer primary key autoincrement, solution_id integer references solution(id), difficulty int, grid text);
+create unique index start_grid on starting_grid(solution_id, difficulty, grid);
+

sudokulib/decorators.py

+"""Decorators used in Sudoku"""
+
+def check_length(func):
+    """Ensures that the provided list of values has a valid length"""
+
+    def wrapped(self, num, values):
+        if len(values) == self.side_length:
+            return func(self, num, values)
+        else:
+            raise ValueError('Invalid values.  Please specify a list of %i values.' % self.side_length)
+    return wrapped
+
+def handle_negative(func):
+    """Handles negative values for get_row and get_col"""
+
+    def wrapped(self, num):
+        if num < 0:
+            num = self.side_length + num
+        return func(self, num)
+    return wrapped
+

sudokulib/solutions.db

Binary file added.

sudokulib/sudoku.py

 """
 
 from copy import copy
-from curses.wrapper import wrapper
-from pprint import pprint
-import curses
 import math
 import random
 import time
 
+from decorators import handle_negative, check_length
+
 MIN = -1
 EASY = 0
 MEDIUM = 1
 INSANE = 4
 GOOD_LUCK = 5
 
-# ------------------- decorators ------------------
-
-def check_length(func):
-    """Ensures that the provided list of values has a valid length"""
-
-    def wrapped(self, num, values):
-        if len(values) == self.side_length:
-            return func(self, num, values)
-        else:
-            raise ValueError('Invalid values.  Please specify a list of %i values.' % self.side_length)
-    return wrapped
-
-def handle_negative(func):
-    """Handles negative values for get_row and get_col"""
-
-    def wrapped(self, num):
-        if num < 0:
-            num = self.side_length + num
-        return func(self, num)
-    return wrapped
-
-# ------------------- Sudoku --------------------
-
 class Sudoku(object):
     SCALE =  {
         MIN: 0.50,
     def set_difficulty(self, difficulty):
         self.difficulty = difficulty
 
+    @property
+    def masked_grid(self):
+        """Generates and caches a Sudoku with several squares hidden"""
+
+        if self._masked is None:
+            min = math.floor(Sudoku.SCALE[self.difficulty] * self.square)
+            max = math.ceil(Sudoku.SCALE.get(self.difficulty - 1, min) * self.square)
+            numbers_to_show = random.randint(min, max)
+
+            self._masked = [True for i in range(numbers_to_show)] + \
+                           ['_' for i in range(self.square - numbers_to_show)]
+            random.shuffle(self._masked)
+            for i, value in enumerate(self.solution):
+                if self._masked[i] == True:
+                    self._masked[i] = value
+
+        return self._masked
+
     @handle_negative
     def get_row(self, row):
         """Returns all values for the specified row"""
         self.iterations = 0
         self.fill_square(0)
 
-    @property
-    def masked_grid(self):
-        """Generates and caches a Sudoku with several squares hidden"""
-
-        if self._masked is None:
-            self._masked = copy(self.solution)
-            min = math.ceil(Sudoku.SCALE[self.difficulty] * self.square)
-            max = math.ceil(Sudoku.SCALE.get(self.difficulty - 1, min) * self.square)
-            numbers_to_show = random.randint(min, max)
-
-            uncleared_squares = [i for i in range(len(self.solution))]
-            for i in range(self.square - numbers_to_show):
-                index = random.choice(uncleared_squares)
-                self._masked[index] = '_'
-                uncleared_squares.remove(index)
-
-        return self._masked
-
-    def print_solution(self):
-        """Prints the generated solution nicely formatted"""
-
-        print 'Required %i iterations' % self.iterations
-        return self.__print_grid(self.solution)
-
-    def print_masked(self):
-        """Prints a masked version of the grid"""
-
-        return self.__print_grid(self.masked_grid)
-
     def __print_grid(self, grid):
         """Prints a nicely formatted version of the Sudoku grid"""
 
             if row < self.side_length - 1 and (row + 1) % self.grid_size == 0:
                 print '+'.join('-' * field_width * self.grid_size for i in range(self.grid_size))
 
+    def print_solution(self):
+        """Prints the generated solution nicely formatted"""
+
+        return self.__print_grid(self.solution)
+
+    def print_masked(self):
+        """Prints a masked version of the grid"""
+
+        return self.__print_grid(self.masked_grid)
+
 def main():
-    s = Sudoku(difficulty=GOOD_LUCK)
+    s = Sudoku(4, difficulty=GOOD_LUCK)
     s.generate()
+
     s.print_masked()
     s.print_solution()