Give you Amway a Python version of the memory flop game! Talent!!

Posted by greatepier on Wed, 26 Jan 2022 20:43:35 +0100

Related documents

Pay attention to Xiaobian and receive private letter Xiaobian!
Of course, don't forget a three in a row~~

Yes, we can pay attention to the official account of Xiaobian yo ~ ~
Python log

development environment

Python version: 3.7.4
Related modules:
pygame module;
tkinter module;
Pilot module;
And some python built-in modules.

Environment construction

Install Python and add it to the environment variable. pip can install the relevant modules required.

Principle introduction

ok, let's briefly introduce the implementation principle of the game.
First, let's play a favorite background music with pygame:

'''Play background music'''
def playbgm(self):
    pygame.init()
    pygame.mixer.init()
    pygame.mixer.music.load(cfg.AUDIOPATHS['bgm'])
    pygame.mixer.music.play(-1, 0.0)

Then, we initialize the main interface of tkinter:

# Main interface handle
self.root = Tk()
self.root.wm_title('Memory flop games - speed and boldness')

And 16 cards that have not been turned over are displayed on the main interface:

# Card dictionary in game interface
self.game_matrix = {}
# background image 
self.blank_image = PhotoImage(data=cfg.IMAGEPATHS['blank'])
# Back of card
self.cards_back_image = PhotoImage(data=cfg.IMAGEPATHS['cards_back'])
# Index of all cards
cards_list = list(range(8)) + list(range(8))
random.shuffle(cards_list)
# Display the back of all cards on the interface
for r in range(4):
    for c in range(4):
        position = f'{r}_{c}'
        self.game_matrix[position] = Label(self.root, image=self.cards_back_image)
        self.game_matrix[position].back_image = self.cards_back_image
        self.game_matrix[position].file = str(cards_list[r * 4 + c])
        self.game_matrix[position].show = False
        self.game_matrix[position].bind('<Button-1>', self.clickcallback)
        self.game_matrix[position].grid(row=r, column=c)

These 16 cards contain 8 completely different images. The goal of our game is to pair the 16 cards with the same image in a limited time. The matching rule is to click two cards continuously. If the images on the back of the cards are the same, the matching is successful, otherwise the matching fails. The game mainly examines the player's memory, because the game also stipulates that the number of cards opened by the game is at most two, otherwise the card opened by clicking at the beginning will be covered again (if the card is not matched successfully).

Next, let's define some useful variables:

 The front card has been displayed
self.shown_cards = []
# Number of cards in the field
self.num_existing_cards = len(cards_list)
# Show game time remaining
self.num_seconds = 30
self.time = Label(self.root, text=f'Time Left: {self.num_seconds}')
self.time.grid(row=6, column=3, columnspan=2)

And make the interface appear in the center of the computer screen at the beginning:

# Center display
self.root.withdraw()
self.root.update_idletasks()
x = (self.root.winfo_screenwidth() - self.root.winfo_reqwidth()) / 2
y = (self.root.winfo_screenheight() - self.root.winfo_reqheight()) / 2
self.root.geometry('+%d+%d' % (x, y))
self.root.deiconify()

Since the matching of all cards is completed in a limited time, let's write a timing function and update it in real time to display the remaining time of the current game:

'''time'''
def tick(self):
    if self.num_existing_cards == 0: return
    if self.num_seconds != 0:
        self.num_seconds -= 1
        self.time['text'] = f'Time Left: {self.num_seconds}'
        self.time.after(1000, self.tick)
    else:
        is_restart = messagebox.askyesno('Game Over', 'You fail since time up, do you want to play again?')
        if is_restart: self.restart()
        else: self.root.destroy()

Finally, when we click the card with the left mouse button, we use the code to define the response rules of the game to realize the functions we want:

'''Click callback function'''
def clickcallback(self, event):
    card = event.widget
    if card.show: return
    # No card has been opened before
    if len(self.shown_cards) == 0:
        self.shown_cards.append(card)
        image = ImageTk.PhotoImage(Image.open(os.path.join(self.card_dir, card.file+'.png')))
        card.configure(image=image)
        card.show_image = image
        card.show = True
    # Only one card was opened before
    elif len(self.shown_cards) == 1:
        # --The card opened before is the same as the card now
        if self.shown_cards[0].file == card.file:
            def delaycallback():
                self.shown_cards[0].configure(image=self.blank_image)
                self.shown_cards[0].blank_image = self.blank_image
                card.configure(image=self.blank_image)
                card.blank_image = self.blank_image
                self.shown_cards.pop(0)
                self.score_sound.play()
            self.num_existing_cards -= 2
            image = ImageTk.PhotoImage(Image.open(os.path.join(self.card_dir, card.file+'.png')))
            card.configure(image=image)
            card.show_image = image
            card.show = True
            card.after(300, delaycallback)
        # --The card opened before is different from the card now
        else:
            self.shown_cards.append(card)
            image = ImageTk.PhotoImage(Image.open(os.path.join(self.card_dir, card.file+'.png')))
            card.configure(image=image)
            card.show_image = image
            card.show = True
    # Two cards were opened before
    elif len(self.shown_cards) == 2:
        # --The first card opened before is the same as the current card
        if self.shown_cards[0].file == card.file:
            def delaycallback():
                self.shown_cards[0].configure(image=self.blank_image)
                self.shown_cards[0].blank_image = self.blank_image
                card.configure(image=self.blank_image)
                card.blank_image = self.blank_image
                self.shown_cards.pop(0)
                self.score_sound.play()
            self.num_existing_cards -= 2
            image = ImageTk.PhotoImage(Image.open(os.path.join(self.card_dir, card.file+'.png')))
            card.configure(image=image)
            card.show_image = image
            card.show = True
            card.after(300, delaycallback)
        # --The second card opened before is the same as the current card
        elif self.shown_cards[1].file == card.file:
            def delaycallback():
                self.shown_cards[1].configure(image=self.blank_image)
                self.shown_cards[1].blank_image = self.blank_image
                card.configure(image=self.blank_image)
                card.blank_image = self.blank_image
                self.shown_cards.pop(1)
                self.score_sound.play()
            self.num_existing_cards -= 2
            image = ImageTk.PhotoImage(Image.open(os.path.join(self.card_dir, card.file+'.png')))
            card.configure(image=image)
            card.show_image = image
            card.show = True
            card.after(300, delaycallback)
        # --The cards opened before are different from those now
        else:
            self.shown_cards.append(card)
            self.shown_cards[0].configure(image=self.cards_back_image)
            self.shown_cards[0].show = False
            self.shown_cards.pop(0)
            image = ImageTk.PhotoImage(Image.open(os.path.join(self.card_dir, card.file+'.png')))
            self.shown_cards[-1].configure(image=image)
            self.shown_cards[-1].show_image = image
            self.shown_cards[-1].show = True
    # Determine whether the game has won
    if self.num_existing_cards == 0:
        is_restart = messagebox.askyesno('Game Over', 'Congratulations, you win, do you want to play again?')
        if is_restart: self.restart()
        else: self.root.destroy()

Let's see the effect:
The home page hasn't turned over yet

If the picture after the flop is not the same picture, it will not be eliminated and will be flipped again:


Many children always encounter some problems and bottlenecks when learning python. They don't have a sense of direction and don't know where to start to improve. For this, I have sorted out some materials and hope to help them. You can add Python learning and communication skirt: 773162165

Well, today's game is for everyone here, Amway, what do not understand, you can comment below, you need to find the source code can be found Xiaobian yo, remember to pay attention to Xiaobian official account ha.

Topics: Python Programming Game Development pygame