Чайный сервиз — логическая игра-головоломка на поле по 3 клетки в две строки. На поле выставлены чайник, сахарница и три чашки. Цель игры: переставить чайник и сахарницу местами, а чашки пусть стоят так же, как в начале игры. Напишем программу игры чайный сервиз на Python с библиотекой tkinter.
Для создания этой игры нам понадобятся изображения чайника, сахарницы и два вида чашек, а так же прозрачная картинка по размеру совпадающая с предыдущими картинками:
Рис. 1
В этой программе игровое поле из Button объектов создадим по шаблону, разработанному в статье Игровое поле из Button:
from tkinter import * # графическая библиотека
from random import shuffle # перемешать список suffle(A)
column = 5 # столбцы
row = 5 # строки
btn = [] # список кнопок
img = []
files = ['red.png', 'yellow.png', 'gold.png',
'green.png', 'emerald.png', 'cyan.png',
'blue.png', 'pink.png','azure.png',
'bronze.png', 'purple.png', 'scarlet.png',
'steel.png', 'silver.png']
def play(n): # функция обработчик нажатия на кнопку
shuffle(img)
btn[n].config(image = img[0])
tk = Tk()
imgBL = PhotoImage(file="blank.png")
for i in files:
img += [PhotoImage(file=i)]
for i in range(row):
f = Frame()
f.pack(expand=YES, fill=BOTH)
for j in range(column):
btn += [Button(f, image=imgBL)]
btn[-1].pack(expand=YES, fill=BOTH, side=LEFT)
btn[-1].config(command=lambda n=i*column+j:play(n))
mainloop()
Лист. 1.
Изменим количество кнопок (переменные column и row) и картинки. Строка imgBL = PhotoImage(file="blank.png") в этой программе нам не нужна.
from tkinter import * # графическая библиотека
from random import shuffle # перемешать список suffle(A)
column = 3 # столбцы
row = 2 # строки
btn = [] # список кнопок
img = []
files = ['tea.png','blank.png','sugar.png','cups.png','cup.png',]
def play(n): # функция обработчик нажатия на кнопку
shuffle(img)
btn[n].config(image = img[0])
tk = Tk()
for i in files:
img += [PhotoImage(file=i)]
for i in range(row):
f = Frame()
f.pack(expand=YES, fill=BOTH)
for j in range(column):
btn += [Button(f, image=img[i*column+j])]
btn[-1].pack(expand=YES, fill=BOTH, side=LEFT)
btn[-1].config(command=lambda n=i*column+j:play(n))
mainloop()
Лист. 2.
Программа листинг 2 выполняется с ошибкой "IndexError: list index out of range".
from tkinter import * # графическая библиотека
from random import shuffle # перемешать список suffle(A)
column = 3 # столбцы
row = 2 # строки
btn = [] # список кнопок
img = []
files = ['tea.png','blank.png','sugar.png','cups.png','cup.png',]
playGround = [0,1,2,3,4,3]
def play(n): # функция обработчик нажатия на кнопку
m = playGround.index(1)
playGround[n], playGround[m] = playGround[m], playGround[n]
btn[n].config(image = img[playGround[n]])
btn[m].config(image = img[playGround[m]])
tk = Tk()
for i in files:
img += [PhotoImage(file=i)]
for i in range(row):
f = Frame()
f.pack(expand=YES, fill=BOTH)
for j in range(column):
btn += [Button(f, image=img[playGround[i*column+j]])]
btn[-1].pack(expand=YES, fill=BOTH, side=LEFT)
btn[-1].config(command=lambda n=i*column+j:play(n))
mainloop()
Лист. 3.
#!/usr/bin/env python3
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-
#
# puzzle.py
# Copyleft (C) 2021 Aleksandr Diorditsa, see <https://adior.ru>
# I want to thank Sergey Polozkov for checking the code for hidden errors.
# I want to thank Sergey Polozkov for the idea of creating this puzzle.
# I want to thank all my students for the inspiration they give me.
#
# puzzle.py is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# puzzle.py is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
from tkinter import * # графическая библиотека
from random import shuffle # перемешать список suffle(A)
column = 3 # столбцы
row = 2 # строки
btn = [] # список кнопок
img = []
files = ['tea.png','blank.png','sugar.png','cups.png','cup.png',]
playGround = [0,1,2,3,4,3]
def play(n): # функция обработчик нажатия на кнопку
m = playGround.index(1)
if (abs(m - n) + abs(n//3 - m//3)) == 1 or abs(m - n) == 3:
playGround[n], playGround[m] = playGround[m], playGround[n]
btn[n].config(image = img[playGround[n]])
btn[m].config(image = img[playGround[m]])
tk = Tk()
for i in files:
img += [PhotoImage(file=i)]
for i in range(row):
f = Frame()
f.pack(expand=YES, fill=BOTH)
for j in range(column):
btn += [Button(f, image=img[playGround[i*column+j]])]
btn[-1].pack(expand=YES, fill=BOTH, side=LEFT)
btn[-1].config(command=lambda n=i*column+j:play(n))
mainloop()
Лист. 4.