У меня есть игра на память, в которой вам нужно найти пары плиток с одинаковыми изображениями. Я хочу модифицировать игру так, чтобы вам приходилось находить пары плитки с изображением и плитки с соответствующим текстом. Например, найдите плитку с изображением кота и плитку с текстом «кошка».
Чтобы понять проблему, вот код, который я считаю наиболее подходящим, показывающий, как я сейчас использую список изображений для создания пар плиток:
class Tile(object):
def __init__(self, canvas, x, y, image, cardback):
self.image = image
more stuff...
class MemGame(tk.Frame):
def __init__(self, master):
super(MemGame, self).__init__(master)
self.images = [
photoDog,
more images...
]
selected = []
for i in range(10):
randomInd = randint(0, len(self.images) - 1)
animalImg = self.images[randomInd]
selected.append(animalImg)
selected.append(animalImg)
del self.images[randomInd]
shuffle(selected)
self.flippedTiles = []
NUM_COLS = 5
NUM_ROWS = 4
for x in range(0, NUM_COLS):
for y in range(0, NUM_ROWS):
self.tiles.append(Tile(self.canvas, x * 108 + 10, y * 108 + 40, selected.pop(), photoCardback))
Я не уверен, должен ли я создать еще один список текстов или изменить список изображений на список списков с изображением и текстом.
Если нужно, вот полный код:
import tkinter as tk
from random import randint
from random import shuffle
import pygame
pygame.init()
class Controller(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
# the container is where we'll stack a bunch of frames
# on top of each other, then the one we want visible
# will be raised above the others
container = tk.Frame(self)
container.pack(side = "top", fill = "both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
if True:
self.frames = {}
for F in (PageMG,):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
# put all of the pages in the same location;
# the one on the top of the stacking order
# will be the one that is visible.
frame.grid(row=0, column=0, sticky = "nsew")
self.show_frame("PageMG")
self.geometry("800x480")
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
class PageMG(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
x = MemGame(self)
x.pack()
class Tile(object):
def __init__(self, canvas, x, y, image, cardback):
self.cardback = cardback
self.canvas = canvas
self.y = y
self.x = x
self.image = image
def drawFaceDown(self):
self.canvas.create_rectangle(self.x, self.y, self.x + 100, self.y + 100, fill = "white")
self.canvas.create_image(self.x + 50, self.y + 50, image=self.cardback)
self.isFaceUp = False
def drawFaceUp(self):
self.canvas.create_rectangle(self.x, self.y, self.x + 100, self.y + 100, fill = "white")
self.canvas.create_image(self.x + 50, self.y + 50, image=self.image)
self.isFaceUp = True
def isUnderMouse(self, event):
if (event.x > self.x and event.x < self.x + 100):
if (event.y > self.y and event.y < self.y + 100):
return True
class MemGame(tk.Frame):
def __init__(self, master):
super(MemGame, self).__init__(master)
photoRestart = tk.PhotoImage(file = "restart.png")
imgRestart = tk.Label(self, anchor = "s", image=photoRestart)
imgRestart.image = photoRestart
buttonRestart = tk.Button(self, activebackground = "white",
image=photoRestart, highlightthickness=0, borderwidth=0,
command=lambda: self.restart())
buttonRestart.place(x=560, y=200)
photoDog = tk.PhotoImage(file = "Dyr/dog.png")
photoElefant = tk.PhotoImage(file = "Dyr/elefant.png")
photoFlamingo = tk.PhotoImage(file = "Dyr/flamingo.png")
photoFlodhest = tk.PhotoImage(file = "Dyr/flodhest.png")
photoKamel = tk.PhotoImage(file = "Dyr/kamel.png")
photoKatt = tk.PhotoImage(file = "Dyr/katt.png")
photoKroko = tk.PhotoImage(file = "Dyr/krokodille.png")
photoNeshorn = tk.PhotoImage(file = "Dyr/neshorn.png")
photoSkilpadde = tk.PhotoImage(file = "Dyr/skilpadde.png")
photoStruts = tk.PhotoImage(file = "Dyr/struts.png")
photoZebra = tk.PhotoImage(file = "Dyr/zebra.png")
photoLove = tk.PhotoImage(file = "Dyr/love.png")
photoCardback = tk.PhotoImage(file = "cardback.png")
self.cardback = photoCardback
self.riktig_sound = pygame.mixer.Sound("riktig.wav")
self.click_sound = pygame.mixer.Sound("camerashutter.wav")
self.configure(width=650, height=480, bg = "white")
self.canvas = tk.Canvas(self, bg = "white", width=550, height=480, highlightthickness=0, borderwidth=0)
self.canvas.place(x=0, y=-30)
self.tiles = []
self.images = [
photoDog,
photoElefant,
photoFlamingo,
photoFlodhest,
photoKamel,
photoKatt,
photoKroko,
photoNeshorn,
photoSkilpadde,
photoStruts,
photoZebra,
photoLove
]
selected = []
for i in range(10):
randomInd = randint(0, len(self.images) - 1)
animalImg = self.images[randomInd]
selected.append(animalImg)
selected.append(animalImg)
del self.images[randomInd]
shuffle(selected)
self.flippedTiles = []
NUM_COLS = 5
NUM_ROWS = 4
for x in range(0, NUM_COLS):
for y in range(0, NUM_ROWS):
self.tiles.append(Tile(self.canvas, x * 108 + 10, y * 108 + 40, selected.pop(), photoCardback))
for i in range(len(self.tiles)):
self.tiles[i].drawFaceDown()
self.flippedThisTurn = 0
self.canvas.bind("<Button-1>", self.mouseClicked)
def mouseClicked(self, event):
for tile in self.tiles:
if tile.isUnderMouse(event) and (self.flippedThisTurn < 2):
if (not(tile.isFaceUp)):
self.clickSound()
tile.drawFaceUp()
self.flippedTiles.append(tile)
self.flippedThisTurn += 1
if (self.flippedThisTurn == 2):
if (self.flippedTiles[-1].image == self.flippedTiles[-2].image): #check last two elements
self.riktig()
self.after(1000, self.checkTiles)
def checkTiles(self):
self.flippedThisTurn = 0
if not(self.flippedTiles[-1].image == self.flippedTiles[-2].image):
self.flippedTiles[-1].drawFaceDown()
self.flippedTiles[-2].drawFaceDown()
del self.flippedTiles[-2:]
def restart(self):
for i in range(len(self.tiles)):
self.tiles[i].drawFaceDown()
def riktig(self):
pygame.mixer.Sound.play(self.riktig_sound)
pygame.mixer.music.stop()
def clickSound(self):
pygame.mixer.Sound.play(self.click_sound)
pygame.mixer.music.stop()
if __name__ == '__main__':
c = Controller()
c.mainloop()
Учитывая, что в коде нет set
, возможно, OP имеет в виду какую-либо коллекцию.
Я имел в виду список, извините. я обновлю пост
Почему бы не использовать дикт? photos = {'dog': tk.PhotoImage(file = "Dyr/dog.png"), ... }
Я думаю, что самый простой подход, который вызывает наименьшие изменения в вашем текущем коде, заключается в следующем:
Созданный словарь можно использовать двунаправленно, поэтому он найдет соответствие независимо от того, как выполняется сравнение.
In [6]: image_tiles = ['dog_img', 'cat_img', 'hen_img']
In [7]: tag_tiles = ['dog', 'cat', 'hen']
In [8]: all_tiles = image_tiles + tag_tiles # use this to draw tiles
In [9]: matches = { k:v for (k, v) in zip(image_tiles, tag_tiles) }
In [10]: # add opposite lookup
In [11]: matches.update([(k, v) for (k, v) in zip(tag_tiles, image_tiles)])
In [12]: matches
Out[12]:
{'dog_img': 'dog',
'cat_img': 'cat',
'hen_img': 'hen',
'dog': 'dog_img',
'cat': 'cat_img',
'hen': 'hen_img'}
Большое спасибо за совет. Завтра утром попробую :)
У меня проблема с методом drawFaceUp в классе Tile. Прямо сейчас он использует image
для рисования плиток, но я думаю, мне нужно каким-то образом передать переменную, такую как tile_type
, в метод, а затем создать операторы if для рисования разных типов плиток?
Я предполагал, что вы будете создавать плитки .png с текстом в них (что не должно быть так сложно), чтобы ВСЕ плитки были одного формата и размера.
О да, это имеет смысл, ха-ха, я сделаю это вместо этого
Не могли бы вы объяснить, как использовать словарь для создания новой функции «проверить плитки»?
Неважно, я понял. Я приму ваш ответ сейчас :) Спасибо за помощь!
Во-первых, вы не можете создать набор наборов, потому что
set
нельзя хэшировать. Однако можно создать наборfrozenset
s.