Пятнашки. Нужна оценка кода и логики
Проба пера как в 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()