Unable to modify variable outside of the method

M D :

I'm trying to make a bot for a sudoku game. It seem to work, but there's a small problem the solved grid is only printed inside the method. When I run it, the print(game.board) print the unsolved one.

this is my code:

import numpy as np


class Game:

    def solve(self):
        def possible(y,x,n):
            for i in range(9):
                if self.board[y][i] == n:
                    return(False)

            for i in range(9):
                if self.board[i][x] == n:
                    return(False)

            gridx = (x // 3) * 3
            gridy = (y // 3) * 3

            for i in range(3):
                for j in range(3):
                    if self.board[gridy + i][gridx + j] == n:
                        return(False)

            return(True)

        def solving():
            for y in range(9):
                for x in range(9):
                    if self.board[y][x] == 0:
                        for n in range(1,10):
                            if possible(y,x,n):

                                self.board[y][x] = n
                                solving()
                                self.board[y][x] = 0
                        return
            print(np.matrix(self.board))
        solving()  


game = Game()
game.board = [
    [7,8,0,4,0,0,1,2,0],
    [6,0,0,0,7,5,0,0,9],
    [0,0,0,6,0,1,0,7,8],
    [0,0,7,0,4,0,2,6,0],
    [0,0,1,0,5,0,9,3,0],
    [9,0,4,0,6,0,0,0,5],
    [0,7,0,3,0,0,0,1,2],
    [1,2,0,0,0,7,4,0,0],
    [0,4,9,2,0,6,0,0,7]
]
game.solve()
print(game.board)
gelonida :

Your code is calling recursively solving() however, it unsets the tried out numbers afterwards.

What you had to do is abort as soon as you find a solution.

Just change solving, such, that it stops when a solution is found:

        def solving():
            for y in range(9):
                for x in range(9):
                    if self.board[y][x] == 0:
                        for n in range(1,10):
                            if possible(y,x,n):

                                self.board[y][x] = n
                                solved = solving()
                                if solved:
                                    return True
                                self.board[y][x] = 0
                        return False
            return True

        solving()

Bonus:

Here a flattened out version (without function nesting) of your solver: I also added an __init__ function, so that the board is passed to the class.

import numpy as np


class Game:
    def __init__(self, board):
        self.board = board

    def possible(self, y, x, n):

        for i in range(9):
            if self.board[y][i] == n:
                return False

        for i in range(9):
            if self.board[i][x] == n:
                return False

        gridx = (x // 3) * 3
        gridy = (y // 3) * 3

        for i in range(3):
            for j in range(3):
                if self.board[gridy + i][gridx + j] == n:
                    return False

        return True

    def solving(self):
        for y in range(9):
            for x in range(9):
                if self.board[y][x] == 0:
                    for n in range(1,10):
                        if self.possible(y,x,n):

                            self.board[y][x] = n
                            solved = self.solving()
                            if solved:
                                return True
                            self.board[y][x] = 0
                    return False
        return True

    def solve(self):
        self.solving()
        return self.board


board = [
    [7,8,0,4,0,0,1,2,0],
    [6,0,0,0,7,5,0,0,9],
    [0,0,0,6,0,1,0,7,8],
    [0,0,7,0,4,0,2,6,0],
    [0,0,1,0,5,0,9,3,0],
    [9,0,4,0,6,0,0,0,5],
    [0,7,0,3,0,0,0,1,2],
    [1,2,0,0,0,7,4,0,0],
    [0,4,9,2,0,6,0,0,7]
]

game = Game(board)

print(np.matrix(game.board))
game.solve()
print(np.matrix(game.board))

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=297749&siteId=1