Пятнашки. Нужна оценка кода и логики

Проба пера как в python так и в проработке логики простой игры в пятнашки. Прошу критиков оценить работу.

#-------------------------------------------------------------------------------
from tkinter import *
from tkinter import messagebox
# Подключение модуля для использования функции перемешивания
from random import shuffle

root = Tk()
root.title('Fifteens')

##### Отладка
# Индикатор хода - координаты
a = StringVar()
a.set('Ход')

# Индикатор хода - значение клетки
m = StringVar()
m.set(' ')
#####

##### Первичное назначение кнопок и текстовых полей
# Добавляем больше переменных в класс кнопок
class Bbut(Button):
    pos_x: ''
    pos_y: ''
    defvalue: ''

# Определение поля и заполнение его первоначальными значениями - КОНСТАНТА
H = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, " ")

# Массив кнопок
btn = []
for x in range (4):
    for y in range(4):
      foo = Bbut(width='5', height='3', relief= 'groove')
      foo.pos_x, foo.pos_y = x, y
      btn.append(foo)
for i in range (16):
    btn[i].configure(text = H[i])
    btn[i].defvalue = H[i]

# z - пустое поле
z = btn[15]

# Выход
button17 = Button(bg = 'dark red', width = '5', height = '3',text = 'E')
# Рестарт
button18 = Button(bg = 'dark green', width = '5', height = '3',text = 'S')

# Отладка
label2 = Label()
label3 = Label()
label1 = Label(width = '5', height = '3', bg = 'light green', textvariable = a)
label4 = Label(width = '5', height = '3', bg = 'light green', textvariable = m)
#####

def on_enter(e):
    if (highlights(e)):
                e.widget.configure(bg="khaki")

def on_leave(e):
    chk_color()

def highlights(e):
    txt = e.widget['text']
    # Если не пустое поле и не Выход/Рестарт
    if txt != ' ' and txt != 'E' and txt != 'S':
        # Координаты кнопки и пустого поля
        x, y = int(e.widget.pos_x), int(e.widget.pos_y)
        zx, zy = int(z.pos_x), int(z.pos_y)
        # Проверка координат на нахождение внутри игрового поля
        if (-1 < x < 4) and (-1 < y < 4) :
            # Проверка координат на возможность хода
            if (x in [zx - 1, zx + 1] and y == zy or y in [zy - 1, zy + 1] and x == zx):
                return True
    return False


# Обработка события нажатия кнопки
def callback(e):
    txt = e.widget['text']
    # Если пустое поле - ничего не делаем
    if txt == ' ':
        return
    # Выход
    elif txt == 'E':
        root.destroy()
    # Рестарт
    elif txt == 'S':
        shf()
        chk_color()
    # Ход
    else:
        a.set(txt)
        m.set((e.widget.pos_x, e.widget.pos_y))
        if (move(e)):
            chk_color()
            check_win()

# Проверка выигрышной позиции
def check_win():
    foo = 0
    for i in btn:
        if i.defvalue == i.cget('text'):
            foo += 1
    if foo == 16:
        messagebox.showinfo( "Победил!", "Ещё раз?")
        shf()
        chk_color()
        a.set(' ')


# Передвижение "фишки"
def move(e):
    global z
    # Если поле подсвечено
    if e.widget.cget('bg') == 'khaki':
        # Переносим "фишку" в пустое поле
        z.configure(text = e.widget.cget('text'))
        # Опустошаем поле с которого сделан ход
        e.widget.configure(text = ' ')
        # Запоминаем новый объект пустого поля
        z = e.widget
        return True;
    else: return False;

# Рестарт
def shf():
    global z
    # Временный массив для перемешивания значений.
    s = list(H)
    # Функция перемешивания
    shuffle(s)
    # Обновляем поле
    for i in range (16):
              btn[i].configure(text = s[i])
    # Ищем пустое поле
    for i in btn:
        if i.cget('text') == ' ':
            # Запоминаем новый объект пустого поля
            z = i
            m.set((z.pos_x, z.pos_y))
            break

# Окрашиваем поле
def chk_color():
    for i in btn:
        foo = i.cget('text');
        # Если "фишка" на своем месте
        if foo == i.defvalue and foo != ' ':
            i.configure(bg = 'light green')
        # Если поле пустое
        elif foo == ' ':
            i.configure(bg = 'light pink')
        # Если "фишка" не на своем месте
        else:
            i.configure(bg = 'SystemButtonFace')


def main():

    for i in btn:
        i.grid(row = i.pos_x, column = i.pos_y)

    button17.grid(row = 1, column = 5)
    button18.grid(row = 2, column = 5)

    label2.grid(row = 1, column = 4)
    label3.grid(row = 2, column = 4)

    label1.grid(row = 3, column = 5)
    label4.grid(row = 0, column = 5)

    root.bind_class('Button','<1>', callback)
    root.bind_class('Button','<Enter>', on_enter)
    root.bind_class('Button','<Leave>', on_leave)
    chk_color()
    messagebox.showinfo( "Начнем?", "'S' - новая игра\n'E' - выход")

    root.mainloop()
    pass

if __name__ == '__main__':
    main()

Ответы (0 шт):