Next / Previous / Contents / Shipman's homepage

6.6. solveFile(): Solve one puzzle

This function reads one puzzle and feeds it to the solver. The output comes back through an Observer function that is called whenever a solution is found.

sudoku
# - - -   s o l v e F i l e   - - -

def solveFile ( fileName ):
    """Try to solve one puzzle.

      [ fileName is a string ->
          if fileName names a readable, valid sudoku puzzle
          file ->
            sys.stdout  +:=  solution(s) to that puzzle if any
            sys.stderr  +:=  message if there are no solutions
          else ->
            sys.stderr  +:=  error message about a bad puzzle ]
    """

First we'll try to open and read the file all into a single string, which is how the SudokuSolver wants it.

sudoku
    #-- 1 --
    # [ if fileName names a readable file ->
    #     rawPuzzle  :=  contents of that file
    #   else ->
    #     sys.stderr  +:=  error message
    #     return ]
    try:
        inFile  =  open ( fileName )
        rawPuzzle  =  inFile.read()
    except IOError, detail:
        message ( "*** Can't open file '%s' for reading. %s\n" %
                (fileName, detail) )
        return

Next we instantiate a SudokuSolver and feed it the puzzle. If any solutions are found, they will be reported by a callback to Section 6.7, “solutionFound(): The observer callback for solutions”.

sudoku
    #-- 2 --
    # [ if rawPuzzle is a valid sudoku puzzle ->
    #     solver  :=  an instance of SudokuSolver to solve
    #         rawPuzzle that will call solutionFound when it
    #         finds a solution
    #   else ->
    #     sys.stderr  +:=  error message
    #     return ] 
    try:
        solver  =  sudosolver.SudokuSolver ( rawPuzzle, solutionFound )
    except ValueError, detail:
        message ( "Invalid puzzle: %s" % detail )
        return

Next, we echo the puzzle's name and content.

sudoku
    #-- 3 --
    # [ sys.stdout  +:=  (fileName) + (puzzle in its initial
    #                    state ]
    separator  =  "=" * 9
    print "\n%s %s %s" % (separator, fileName, separator)
    solver.write ( sys.stdout )

Now we ask the solver to solve. If any solutions are found, they'll be written in this step.

sudoku
    #-- 4 --
    # [ sys.stdout  +:=  solutions to solver, if any ]
    startClock  =  time.clock()
    solver.solve()
    endClock  =  time.clock()

Lastly, we report the number of solutions found. If the puzzle is properly constructed, this step should display a solution count of one. A value of zero means there was no solution.

sudoku
    #-- 5 --
    # [ sys.stdout  +:=  report on the number of solutions in
    #                    solver ]
    print "\nNumber of solutions found:", solver.nSolutions
    print "Elapsed cpu time: %.2f seconds." % (endClock-startClock)