Exemplo n.º 1
0
def ens_cell0(grid, reverse=False):
    """
    return all cells with a value equal at 0 or if reverse is True, return all cells with a value different at 0

    :param grid: a sudoku grid
    :type grid: grid
    :param reverse: (optional) defaults set to False. If True,
                    return the reverse of a normal using
    :type reverse: bool
    :return: a list of all cell with a value at 0 if reverse is True and the reverse if not
    :rtype: list of cells
    :UC: none
    :Examples:
    
    >>> grid = sudoku_grid.make_grid()
    >>> len(ens_cell0(grid))
    81
    >>> len(ens_cell0(grid,reverse=True))
    0
    """
    cell_list = list()
    for ind_line in range(9):
        for cell in sudoku_grid.get_line(grid, ind_line):
            if cells.get_cellvalue(cell) == '0' and not reverse:
                cell_list.append(cell)
            if reverse and cells.get_cellvalue(cell) != '0':
                cell_list.append(cell)
    return cell_list
Exemplo n.º 2
0
def is_solved(grid):
    """
    say if grid is a resolved grid

    :param grid: a sudoku's grid
    :type grid: grid
    :return: True if it's resolved and False if not
    :rtype: bool
    :UC: none
    """
    for ind_line in range(9):
        cell_list = sudoku_grid.get_line(grid, ind_line)
        if len(set(cells.get_cellvalue(cell) for cell in cell_list)) != 9:
            return False

    for ind_col in range(9):
        cell_list = sudoku_grid.get_colomn(grid, ind_col)
        if len(set(cells.get_cellvalue(cell) for cell in cell_list)) != 9:
            return False

    for ind_square in range(9):
        cell_list = sudoku_grid.get_square(grid, ind_square)
        if len(set(cells.get_cellvalue(cell) for cell in cell_list)) != 9:
            return False
    return True
Exemplo n.º 3
0
def __correction(button_grid):
    """
    This function manage the correction of values enter by the user.
    """
    global grid, string

    if not len(sudoku_solver.ens_cell0(grid, reverse=True)):
        showerror("ERROR", "Open a grid...")
        return None

    try:
        sudoku_solver.search_sol(sudoku_grid.make_grid(string),
                                 background=True)
    except:
        showerror("ERROR", "It's impossible to solve your grid")
        return None

    try:
        sol = sudoku_solver.ens_sol.pop()
    except:
        showwarning("WARNING", "There is no solution find for your grid")
        return None
    solved_grid = sudoku_grid.make_grid(sol)

    wrong_cells_list = list()
    for ind_line in range(9):
        for ind_col in range(9):
            cell = sudoku_grid.get_cell(grid, ind_line, ind_col)
            value = cells.get_cellvalue(cell)
            if int(value):
                solved_cell = sudoku_grid.get_cell(solved_grid, ind_line,
                                                   ind_col)
                solved_value = cells.get_cellvalue(solved_cell)
                button = sudoku_grid.get_cell(button_grid, ind_line, ind_col)
                if value != solved_value and button["state"] == "normal":
                    button.config(bg="red")
                    wrong_cells_list += [(cell, (ind_line, ind_col),
                                          solved_value, button)]

    if len(wrong_cells_list):
        boolean = askyesno(
            "Corrected",
            "Do you want that the algorithm corrected your errors?")
        if boolean:
            for saved_tuple in wrong_cells_list:
                cell = saved_tuple[0]
                ind_line, ind_col = saved_tuple[1][0], saved_tuple[1][1]
                solved_value = saved_tuple[2]
                button = saved_tuple[3]
                cells.set_cellvalue(cell, solved_value)
                __redraw(button_grid, ind_line, ind_col, solver=True)
                button.config(bg="green")
    else:
        showinfo("Corrected", "All cell's values are checked.")
Exemplo n.º 4
0
def __save():
    """
    This function save your sudoku grid.
    """
    global grid, string

    save_value = list()
    for ind_line in range(9):
        save_value.insert(ind_line, list())
        for ind_col in range(9):
            cell = sudoku_grid.get_cell(grid, ind_line, ind_col)
            value = cells.get_cellvalue(cell)
            save_value[ind_line].insert(
                ind_col, {
                    "value":
                    value,
                    "computer value":
                    string[ind_col + 9 * ind_line] == value and int(value)
                })

    stream = tkfdial.asksaveasfile(mode="wb",
                                   title="Save",
                                   filetypes=[("GRD", ".grd")],
                                   defaultextension=".grd")
    if stream:
        my_pickle = pickle.Pickler(stream)
        my_pickle.dump(save_value)
        stream.close()
        showinfo("Save", "You have saved your sudoku grid")
Exemplo n.º 5
0
def __write_grid(button_grid, var, root):
    """
    This function write a grid with th edifficulty choosen by the user.
    """
    global string, grid
    import random

    difficultys_list = ["easy", "medium", "hard", "fiendish"]
    if var.get() == 4:
        with open("data/sudoku17.bdd", "r") as stream:
            string = random.choice(stream.readlines())[:81]
    else:
        temp = ["", ""]
        while temp[0] != difficultys_list[var.get()]:
            with open("data/sudokus.bdd", "r") as stream:
                temp = random.choice(stream.readlines()).split(":")
        string = temp[-1][:81]

    grid = sudoku_grid.make_grid(string)
    for ind_line in range(9):
        for ind_col in range(9):
            __redraw(button_grid, ind_line, ind_col)
            cell = sudoku_grid.get_cell(grid, ind_line, ind_col)
            button = sudoku_grid.get_cell(button_grid, ind_line, ind_col)
            if int(cells.get_cellvalue(cell)):
                button.config(state="disabled")
            else:
                button.config(state="normal")
    root.destroy()
Exemplo n.º 6
0
def print_grid(grid):
    """
    print the sudoku's grid

    :param grid: a sudoku's grid
    :type grid: grid
    :return: None
    :rtype: NoneType
    :Action: print the grid
    :UC: none
    :Examples:

    >>> grid = make_grid(val_test)
    >>> print_grid(grid)
    +-------+-------+-------+
    | . 1 2 | 3 4 5 | 6 7 8 |
    | . 1 2 | 3 4 5 | 6 7 8 |
    | . 1 2 | 3 4 5 | 6 7 8 |
    +-------+-------+-------+
    | . 1 2 | 3 4 5 | 6 7 8 |
    | . 1 2 | 3 4 5 | 6 7 8 |
    | . 1 2 | 3 4 5 | 6 7 8 |
    +-------+-------+-------+
    | . 1 2 | 3 4 5 | 6 7 8 |
    | . 1 2 | 3 4 5 | 6 7 8 |
    | . 1 2 | 3 4 5 | 6 7 8 |
    +-------+-------+-------+
    """
    print('+' + '-------+' * 3)
    for l1 in range(3):
        for l2 in range(3):
            print('|', end='')
            for c1 in range(3):
                for c2 in range(3):
                    if cells.get_cellvalue(
                            get_cell(grid, l1 * 3 + l2, c1 * 3 + c2)) == '0':
                        print(' .', end='')
                    else:
                        print(' ' + cells.get_cellvalue(
                            get_cell(grid, l1 * 3 + l2, c1 * 3 + c2)),
                              end='')
                print(' |', end='')
            print()
        print('+' + '-------+' * 3)
Exemplo n.º 7
0
def __RAZ(button_grid):
    """
    This funciton redraws the board with all cell's values at '0'.

    :param button_grid: the board of buttons
    :type button_grid: list of list of ``button``
    """
    global grid

    for ind_line in range(9):
        for ind_col in range(9):
            cell = sudoku_grid.get_cell(grid,ind_line,ind_col)
            if int(cells.get_cellvalue(cell)):
                cells.set_cellvalue(cell,'0')
            __redraw(button_grid,ind_line,ind_col)
Exemplo n.º 8
0
def remove(grid):
    """
    print a random grid with removing cells from grid with one solution

    :param grid: a sudoku grid
    :type grid: grid
    :return: the string of a random sudoku's grid with removed cells
    :rtype: str
    :UC: none
    """
    global ens_sol

    cell_list = ens_cell0(grid, reverse=True)
    if len(
            cell_list
    ) <= 17:  #il est impossible d'avoir une grille de sudoku avec moins de 17 remplies si l'on veut avoir une unique solution
        ens_sol = set()  #on réinitialise les variables globales
        compt_rec = 0
        father = "SUDO"
        sol_way = list()

        return sudoku_grid.grid2string(grid)
    else:
        cell = cell_list[random.randint(
            1,
            len(cell_list) - 1
        )]  #on récupère une cellule au hasard dans l'ensemble des cellules non vides
        value = cells.get_cellvalue(cell)
        cells.set_cellvalue(cell, '0')
        string = sudoku_grid.grid2string(
            grid
        )  #le fait de faire cette transformation nous permet de faire une mise à jour des valeurs hipothétiques
        search_sol(sudoku_grid.make_grid(string), background=True)
        if len(ens_sol) == 1:
            ens_sol = set()  #on réinitialise les variables globales
            compt_rec = 0
            father = "SUDO"
            sol_way = list()

            return remove(sudoku_grid.make_grid(string))
        else:
            ens_sol = set()  #on réinitialise les variables globales
            compt_rec = 0
            father = "SUDO"
            sol_way = list()

            cells.set_cellvalue(cell, value)
            return sudoku_grid.grid2string(grid)
Exemplo n.º 9
0
def not_solved(grid):
    """
    say if it's impossible to find solution of the sudoku's grid
    
    :param grid: a sudoku's grid
    :type grid: grid
    :return: True if it's impossible to find solution and False if not
    :rtype: bool
    :UC: none
    """
    for i in range(9):
        for cell in sudoku_grid.get_line(grid, i):
            if cells.get_cellvalue(
                    cell) == '0' and not cells.get_cellhipo(cell):
                return True  #renvoie True si une cellules ne possède aucune valeur hipothetic et que sa valeur est 0
    return False
Exemplo n.º 10
0
def __redraw(button_grid, ind_line, ind_col, solver=False):
    """
    This function draws the board. Position ind_line and ind_col are used to test
    which number icon has to be drawn.
    It's also manage it must to create a finished popup with solver.
    """
    global grid

    button = sudoku_grid.get_cell(button_grid, ind_line, ind_col)
    cell = sudoku_grid.get_cell(grid, ind_line, ind_col)
    value = cells.get_cellvalue(cell)
    button.config(image=img[int(value)])
    if sudoku_solver.is_solved(grid) and not len(
            sudoku_solver.ens_cell0(grid)):
        __disabled_grid(button_grid)
        if not solver:
            showinfo("CONGRATULATIONS", "You have finished the sudoku")
Exemplo n.º 11
0
def __redraw(button_grid,ind_line,ind_col):
    """
    This function draws the board. Position ind_line and ind_col are used to test
    which number icon has to be drawn.

    :param button_grid: the board of buttons
    :type button_grid: list of list of ``button``
    :param ind_line: the line of the cell
    :type ind_line: int
    :param ind_col: the column of the cell
    :type ind_col: int
    """
    global grid

    button = sudoku_grid.get_cell(button_grid,ind_line,ind_col)
    cell = sudoku_grid.get_cell(grid,ind_line,ind_col)
    value = cells.get_cellvalue(cell)
    button.config(image=img[int(value)])
Exemplo n.º 12
0
def grid2string(grid):
    """
    return the string from the grid

    :param grid: a grid of sudoku
    :type grid: grid
    :return: a srting of values from the sudoku
    :rtype: str
    :UC: none
    :Examples:

    >>> string = "490001007000045030382600050003070401800902005907030600030006529020850000500700013"
    >>> grid = make_grid(string)
    >>> grid2string(grid) == string
    True
    """
    string = ''
    for ind_line in range(9):
        for cell in get_line(grid, ind_line):
            string += cells.get_cellvalue(
                cell
            )  #on cherche à reconstruire la chaîne de caractères correspondante à la grille que l'on donne
    return string
Exemplo n.º 13
0
def create(string='0'*81):
    """
    this function creates the graphical board from a solver. It also
    launches the event loop. Thus, this is the only function to run to
    have a functional graphical board.

    :param string: the sudoku
    :type string: str
    :return: None
    :rtype: NoneType
    """
    global img,win,grid,recursion_check,image_check,remove_check,talkative_check,start_button,enter_button

    grid = sudoku_grid.make_grid(string)
    win = tk.Tk()
    win.title('Sudoku Solver')
    iconpath = os.path.join(os.path.dirname(os.path.abspath(__file__)), "icons")
    img = [
        tk.PhotoImage(file=os.path.join(iconpath, "0.gif")),
        tk.PhotoImage(file=os.path.join(iconpath, "1.gif")),
        tk.PhotoImage(file=os.path.join(iconpath, "2.gif")),
        tk.PhotoImage(file=os.path.join(iconpath, "3.gif")),
        tk.PhotoImage(file=os.path.join(iconpath, "4.gif")),
        tk.PhotoImage(file=os.path.join(iconpath, "5.gif")),
        tk.PhotoImage(file=os.path.join(iconpath, "6.gif")),
        tk.PhotoImage(file=os.path.join(iconpath, "7.gif")),
        tk.PhotoImage(file=os.path.join(iconpath, "8.gif")),
        tk.PhotoImage(file=os.path.join(iconpath, "9.gif"))
        ]
    button_grid = list()

    grid_frame = tk.Frame(win,bd=1.5,bg="black")
    grid_frame.grid(column=0,row=0,columnspan=9,rowspan=9,padx=3,pady=3)

    for ind_line in range(9):
        button_grid.insert(ind_line,[])
        for ind_col in range(9):
            cell = sudoku_grid.get_cell(grid, ind_line, ind_col)
            value = cells.get_cellvalue(cell)
            
            button = tk.Button(grid_frame, padx=0, pady=0, width=30, height=30, image=img[int(value)])
            button.grid(column=ind_col, row=ind_line)
            button_grid[ind_line].insert(ind_col, button)
            button.config(command=partial(__change,button_grid,ind_line,ind_col))

    for ind_square in range(9):
        button_list = sudoku_grid.get_square(button_grid,ind_square)
        for button in button_list:
            if ind_square%2:
                button.config(bg="grey")
            else:
                button.config(bg="white")

    options_frame = tk.Frame(win)
    options_frame.grid(column=9,row=0,rowspan=10)
    
    text = tk.Label(options_frame,text = "options:",font = "bold 16 italic")
    text.grid(row = 1,pady=10)

    image_var = tk.IntVar()
    image_check = tk.Checkbutton(options_frame,text = "arbre",variable = image_var)
    image_check.grid(row = 2,sticky="nw",padx=2,pady=5)

    remove_var = tk.IntVar()
    remove_check = tk.Checkbutton(options_frame,text = "remove",variable = remove_var)
    remove_check.grid(row = 3,sticky="nw",padx=2,pady=5)

    talkative_var = tk.IntVar()
    talkative_check = tk.Checkbutton(options_frame,text = "talkative",variable = talkative_var)
    talkative_check.grid(row = 4,sticky="nw",padx=2,pady=5)
    
    recursion_var = tk.IntVar()
    recursion_check = tk.Checkbutton(options_frame,text = "recursion",variable = recursion_var)
    recursion_check.grid(row = 5,sticky="nw",padx=2,pady=5)

    enter_button = tk.Button(options_frame, text = "Write a grid")
    enter_button.grid(row = 6,padx=2,pady=30)
    enter_button.config(bd=2,command = partial(__popup,button_grid))

    image = tk.PhotoImage(file = 'icons/help-icon.png')
    can = tk.Canvas(options_frame,width = 40,height = 40)
    item = can.create_image(24,24,image = image)
    can.grid(row = 7)
    can.bind("<Button-1>",help_option)
    

    start_button = tk.Button(win, text="run")
    start_button.grid(column=1,row=9,pady=5)
    start_button.config(bd=2,command = partial(__run,button_grid,rec=recursion_var,img=image_var,rm=remove_var,t=talkative_var))

    raz_button = tk.Button(win, text="RAZ")
    raz_button.grid(column=4,row=9)
    raz_button.config(bd=2,command = partial(__RAZ,button_grid))

    quit_button = tk.Button(win, text="exit")
    quit_button.grid(column=7,row=9)
    quit_button.config(bd=2,command = back)

    win.mainloop()