Bildrätsel PIL tkinter
Ich bin ein Hobby-Programmierer (der nur Spaß hat), der ein kleines Skript erstellt hat, das ein Foto aufnimmt, seine Größe ändert und es dann in 24 Teile zerlegt. Die Stücke werden transponiert und zu Knöpfen verarbeitet. Ihre Aufgabe ist es, den ursprünglichen Zustand wiederherzustellen, ohne Punkte zu verlieren. Meine Fragen sind: Hat es Spaß gemacht? Könnten Sie es auf Windows- oder ISO-Plattformen spielen?
from PIL.ImageTk import Image, PhotoImage
from PIL import ImageChops
from tkinter import (Canvas,Tk,Frame,Button,YES,BOTH,filedialog,
Toplevel,IntVar,Label)
from tkinter.messagebox import showinfo, showerror
import logging
from random import choice
from functools import partial
#logging.basicConfig(level= logging.DEBUG)
logging.disable(logging.CRITICAL)
class Puzzle_One(Frame):
"""Grab a picture, then cuts it up into 24 pieces and transpose,
make them into buttons. Repeatedly pressing the buttons to it's
origional state before getting a negative score."""
def __init__(self, parent=None):
self.parent= parent
Frame.__init__(self, self.parent)
self.pack(expand=YES, fill=BOTH)
self.canvas= Canvas(self)
self.canvas.config(width= 800, height= 700, bg='gray90')
self.canvas.pack(expand=YES, fill=BOTH)
self.puzzle_points= IntVar()
self.lbl_1= Label(self.canvas, textvariable=self.puzzle_points,
font=('arial',50,'bold'))
self.lbl_1.place(x=500,y=30)
self.puzzle_points.set(2500)
self.btn= Button(self.canvas, text='find image',
command= self.get_image)
self.btn.place(x=400,y=600)
self.buttons= []
self.image_ref= []
self.transitions= [ Image.FLIP_LEFT_RIGHT, Image.FLIP_TOP_BOTTOM,
Image.ROTATE_180, Image.ROTATE_270,
Image.ROTATE_90]
self.t_count=0
self.t_pics=[]
self.buttons= []
self.image_compare= []
self.mydict= {}
def get_image(self):
"""Find your photo, it will be displayed on the canvas as a reference.
A new button will be made to create the puzzle"""
self.btn.config(state='disabled')
self.file= filedialog.askopenfilename(filetypes=[('PNG','.png'),
('JPG','.jpg'),
('GIF','.gif'),
]
)
self.image= Image.open(self.file)
self.im= self.image.resize((600,400))
image= PhotoImage(self.im)
self.canvas.create_image(360,320,image=image,tag='my_image')
self.t_pics.append(image)
self.btn2= Button(self.canvas,text='make puzzle',
command=self.make_puzzle)
self.btn2.place(x=200,y=600)
def rotate_btn(self,pic_name, index):
"""Reapeatedly pressing the image buttons scrolls through a list of
image transitions. Find the correct position"""
if self.t_count >4:
self.t_count =0
img= pic_name.transpose(self.transitions[self.t_count])
self.mydict[index]= img
image= PhotoImage(image=img)
self.buttons[index].config(image=image)
self.t_pics.append(image)
self.t_count +=1
def compare(self):
"""Compares the puzzle button with the original. Numbering starts
in the upper left corner with 0, lower right corner is 23.
Need a better way to indicate which buttons image is incorrect.
Updating the score
"""
points= self.puzzle_points.get()
res= []
for num in range(0,24):
image_1= self.image_compare[num]
image_2= self.mydict.get(num, '')
diff= ImageChops.difference(image_1,image_2)
if diff.getbbox():
pts= points- 500
if pts < 0:
self.puzzle_points.set(pts)
self.buttons[num].config(borderwidth=10)
txt= 'Your total points is {}'.format(pts)
showinfo('Loss',txt)
self.buttons[num].config(borderwidth=2)
self.btn3.config(state='disabled')
break
else:
self.puzzle_points.set(pts)
self.buttons[num].config(borderwidth=10)
text_= "There's an error {}".format(num)
showerror('No bueno', text_)
self.buttons[num].config(borderwidth=2)
break
else:
res.append(num)
if len(res) == 24:
total= self.puzzle_points.get()
text='Winner your total points are {}'.format(total)
showinfo('Win', text)
self.btn3.config(state='disabled')
def make_puzzle(self):
"""A popup window containing 24 buttons. x1,y1,x2,y2 are the position of the cut pieces
of the image. A reference of each region is transposed and converted to a Tk image,
then saved to a list to prevent being garbage collected. Passing the region of each
image and the index as an argument for each button. The buttons are in a list so they
can be accessed by the index."""
self.btn3= Button(self.canvas, text='I solved it!',
command=self.compare)
self.btn3.place(x=600,y=600)
self.btn2.config(state='disabled')
self.top= Toplevel()
x1=0
y1=0
x2=100
y2=100
count=0
b_count=0
for r in range(1,5):
for c in range(1,7):
box= x1,y1,x2,y2
reg= self.im.crop(box)
self.image_compare.append(reg)
tran= choice(self.transitions)
reg= reg.transpose(tran)
self.mydict[b_count]= reg
image= PhotoImage(reg)
self.buttons.append(Button(self.top,image=image,
command=partial(self.rotate_btn,reg,b_count))
)
self.buttons[-1].grid(row=r,column=c,padx=0.5,pady=0.5)
self.image_ref.append(image)
if count == 5:
count= 0
b_count +=1
x1 = 0
y1 += 100
x2= 100
y2 += 100
else:
x1 +=100
x2 +=100
count +=1
b_count +=1
if __name__ == '__main__':
root= Tk()
Puzzle_One(root)
root.mainloop()
Antworten
Schönes Spiel und tolle Arbeit, meine Tochter mag es!
Es funktionierte unter Windows. Nach Abschluss des Puzzles konnte ich kein anderes Bild auswählen und erneut spielen. Ich denke, dies kann leicht implementiert werden, indem eine Methode hinzugefügt wird play_game(self), die die Gesamtkontrolle über das Spiel übernimmt und über eine Schaltfläche zum Beenden verfügt.
Ein Folge-Puzzle wäre, die Bildelemente dort zu verschieben, wo Sie sie in die richtige Reihenfolge bringen müssen.
Dann ein Vorschlag, können Sie versuchen, das gleiche Spiel in PyQt5 zu implementieren. Persönlich mag ich diese GUI besser als tkinter.