程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python writes a little game: guess idioms by looking at pictures (Part 2)

編輯:Python

List of articles

  • Preface
  • Look at the picture and guess the idiom
    • 1. How to play
    • 2. The flow of the game
    • 3. Code implementation
      • 1). Create idiom library and initialize
        • OS Built-in module
      • 2). Select idioms randomly
        • Random word selection
        • Drawing pictures
        • Prepare Chinese character library
        • Chinese characters on buttons
      • 3). Redefine the word selection button
        • Display the Chinese characters selected by the player
        • Custom button class
      • 4). Judge the player's choice
      • 5). Clear selection
      • 6). Computer tips
    • 4. Complete code
  • Summary and reflection


Preface

Hello everyone , In the first part, we have set up the game , Today we will continue the unfinished work , Use code to realize the function of the game , I don't say much nonsense , Let's get started .

Part 1 —— Build the game interface
The next part —— Implementation of background program


Look at the picture and guess the idiom

1. How to play

In the previous article, I have already introduced the playing method , It's a simple one here , I believe you can understand it as soon as you read it .

screenshots :

2. The flow of the game

In the previous article, we have drawn a flow chart :

NoYesYesNo Game begins The picture shows Players choose Chinese characters to form idioms Determine whether the player's input is correct Clear the player's choice Congratulations , Whether to go to the next level Choose new words Game over Player selection prompt

Here we review , It can help us understand what custom functions need to be created . In the previous article, we can say that we have finished “ The picture shows ” Part of , The only thing that needs to be supplemented , How to randomly display idiom pictures , After the player has answered correctly , Switch to the next .

Besides , We also need programs or custom functions that perform the following functions :

  1. Create idiom Library , And randomly select a single idiom
  2. Judge whether the player's choice is correct
  3. Clear player selection
  4. Prompt a Chinese character

Let's explain one by one .

3. Code implementation

1). Create idiom library and initialize

Brother Wen downloaded it from the Internet 444 A picture to guess idioms , Upload in here , Or you can ask me for it by private letter .

These pictures have three characteristics :

  1. Same size , All are 120x120
  2. All are PNG picture
  3. They are named after the idioms they represent

The first two features are convenient for us to show in the program , No more code to adjust the size and position of the picture . The third feature is more convenient for us to create an idiom database , We just need to put all the idiom pictures in the folder images Next , Then extract the names of all the files in the folder ( The format is xxxx.png), And then choose before 4 A character is our idiom library . When called , We just have to decide on the idiom first , Add... After the idiom .png This is the corresponding picture .

OS Built-in module

Extract the names of all files in the folder , Need to use Python Another built-in module of os. seeing the name of a thing one thinks of its function , This module is related to the operating system (operation system) dependent . It's easy to use :

import os
filenames = os.listdir(r'images\words')

Just use os In the module listdir Method , You can extract all the file names under the folder , Return a list .( Because brother Wen put the background picture in images Under the folder , So in order to save time , Another one is created below words The folder is specially used to store idiom pictures .)

When you get this list , We can use the list slicing operation , Extract the first four characters of each string , Form a list of idioms .

word_list = [i[:4] for i in filenames]

Of course , We hope that every time we start playing games , Idioms are displayed randomly , So we need to use what we learned before random.shuffle Method to randomly break up these lists , It's like shuffling , Then draw one card from the top or bottom of the stack at a time , It has become an idiom that we let players guess .

import random
random.shuffle(word_list)

In this way, we have created the idiom Library , Initialization is also done ( Shuffle ).

2). Select idioms randomly

Considering that the action of extracting idioms is to be operated at each level , Therefore, it is more convenient to customize a function for implementation , This saves you from having to write code repeatedly . Here I ask you to name this function create_random_word()

Random word selection

Let's customize a global variable first word, It is used to save the correct idioms extracted by the computer at each level . As the game goes on , We need to constantly change the value of this variable in the custom function ( The idioms extracted each time are different ), So it's best to use it inside a function global Keyword to declare it as a global variable , Avoid the trouble of transferring reference .

Besides , Because during initialization , We've used shuffle Methods to disorder the order of the idiom library , So we don't need to use random method to extract idioms , But directly from the idiom library ( Deck ) Just take one sheet from the top or bottom of the . Brother Wen uses a list pop() Method , That is, from the end of the list ( The bottom of the deck ) Take one , At the same time, the elements in the idiom list are subtracted by one . The code implementation is as follows :

word=''
def create_random_word():
global word
word = word_list.pop()

Now we can draw the pictures corresponding to the randomly selected idioms to Canvas On the canvas .

In the first part , We define the picture statically , Take a look back. :

img = tk.PhotoImage(file=f"images\words\ everything is going smoothly .png")
cv_word = cv.create_image(150,120,image = img)

Drawing pictures

Now we have custom functions , You need to move these two sentences of code to the user-defined function . however We need to pay attention to Yes. , Draw on Canvas On the canvas img The picture variable needs to be brought into the loop of the main window (mainloop), If it is moved to a custom function and becomes a local variable , Once the program is running, it leaves the custom function , This variable disappears , There are no pictures . therefore , We need to take img Also declared as a global variable .

Can be directly in global Keyword together with the declaration , And separated by commas .

word=''
def create_random_word():
global word, img
word = word_list.pop()
img = tk.PhotoImage(file=f"images\words\{
word}.png")
cv.create_image(150,120,image = img)

Now we can call this function at the end ,( Be careful , Put it on cv.pack() In front of , Otherwise, idiom pictures can't be drawn )

create_random_word()
cv.pack() # Load canvas in main window 
root.mainloop() # The main window is displayed circularly 

Check to see the effect :

Prepare Chinese character library

The picture has , There is also a global variable word, Used to represent the correct idiom corresponding to the picture . But we also need to prepare a Chinese character library for players to choose from . In this way, players will be able to select the correct Chinese characters to form idioms .

We define a local list variable lib To represent this font . At the same time, we must make sure that there are correct idioms in the font word, And there are other 4 A random idiom , As a disturbing answer . So we can use it random.sample Methods calculate at random from the rest of the idiom database 4 An idiom , Then use the string splicing method (“join” and “+”) And correct idioms word Form a 20 A string of Chinese characters . And then put this 20 A string of Chinese characters is converted into a list and loaded into lib. Final use random.shuffle Method to scramble the list , To ensure that the font we finally display is out of order . The code is as follows :

def create_random_word():
lib = list(''.join(random.sample(word_list,4))+word)
random.shuffle(lib)

But here's a little problem , We are from “ Deck ”(word_list) Select another at random 4 A proverb , As the game goes on ,“ Deck ” It will be less and less . When there is less than 4 An idiom , This sampling method is bound to report errors , So we must find a way to ensure that even the last idiom , You can also find other 4 A disturbing idiom lib.

If the idiom thesaurus is compared to a pile of cards , We must have another deck list —— Discard pile , So we can consider using the discard pile . Define a new empty list word_copy, Used to collect idioms after each use word. as long as word Not empty ( At the beginning of the game ), Just add the word “ Discard pile ” list word_copy. And then at random , We can “ Discard pile ” and “ Deck ” Choose from these two lists , The problem can be solved . The revised code is as follows :

word=''
word_copy = []
def create_random_word():
global word, img, word_copy
if word: word_copy.append(word)
word = word_list.pop()
lib = list(''.join(random.sample(word_copy+word_list,4))+word)

So we're ready for 20 individual (5 A proverb ) Disordered Chinese characters , Now just put them “ Write ” Just go to the button .

Chinese characters on buttons

I still remember that we are ready for the last article 20 A bare button ?

for i in range(4):
for j in range(5):
btn = tk.Button(root, font =(' Square regular script, simplified Chinese ',11),width=2,relief='flat',bg='lightyellow')
btn_window = cv.create_window(300+40*i, 75+35*j, window=btn)

And now we can put lib The Chinese characters in the are written on the button , But at that time, the buttons were arranged for convenience , We call all the buttons btn, Now when we want to write different Chinese characters on each button , You must know the name of each button . So we define a list of buttons , Put all the buttons in the list , In this way, different buttons can be referenced through the list index . therefore , This part of the code is modified as follows :

btn = []
for i in range(4):
for j in range(5):
btn.append(tk.Button(root, font =(' Square regular script, simplified Chinese ',11),width=2,relief='flat',bg='lightyellow'))
btn_window = cv.create_window(300+40*i, 75+35*j, window=btn[i*5+j])

Now we can create_random_word The function is here 20 Chinese characters are written on the buttons , Just modify their... In turn text attribute . So finally create_random_word The code of the function is as follows :

word=''
word_copy=[]
def create_random_word():
global word, img, word_copy
if word: word_copy.append(word) # “ Discard pile ”
word = word_list.pop() # Extract new idioms 
lib = list(''.join(random.sample(word_copy+word_list,4))+word)
random.shuffle(lib) # Prepare to disturb the font 
for i in range(len(btn)):
btn[i]['text'] = lib[i] # Write Chinese characters on the buttons 
img = tk.PhotoImage(file=f"images\words\{
word}.png")
cv.create_image(150,120,image = img) # Draw the picture in the designated position 

Run to see the effect :

3). Redefine the word selection button

Now we have two questions before us :

  1. How to click a button , You can get the corresponding Chinese characters ;
  2. How to display the Chinese characters that players get by clicking the button in the four square grids below the picture .

Let's start with the 2 A question , Because this is easier to implement .

Display the Chinese characters selected by the player

In the first chapter , The four square grids are actually ordinary rectangles , We can't write in it .

for i in range(4):
cv.create_rectangle(50*i+50,210,50*i+86,246,fill='ivory')

But we can write on them . Suppose that the string variable composed of Chinese characters selected by the player is txt, Then we just use the canvas in the corresponding position create_text Method creation 4 Just a text .

txt = ' One after another '
for i in range(4):
cv.create_text(50*i+68,228,fill='black', text=txt[i], font =(' Square regular script, simplified Chinese ',18,'bold'))

But because we have to change these four texts at any time , So it's better to put them in the array . The code is modified as follows :

txt = ' One after another '
text=[]
for i in range(4):
text.append(cv.create_text(50*i+68,228,fill='black',text=txt[i], font =(' Square regular script, simplified Chinese ',18,'bold')))

Look at the effect :

Next, we just need to change the variable through the button txt The value of . Of course, at the beginning of the game ,txt The value of should be empty (“”).

Custom button class

Now let's take a look at the first question we just mentioned .tkinter You can add one to all the button components of command Parameters , Used to specify the function to be executed after the button is pressed . But the problem is , This command The specified function cannot pass arguments , Our buttons need to perform different actions when pressed ( Add the word on the button to txt in ).

At this time, we can use the method of object-oriented programming , Think of each button as a living object . Each button has its own method , Is to add your name to txt. besides , These buttons also need to be associated with tkinter Of Button Class has the same properties and methods . So we can create a subclass , Inherit tkinter Of Button class . Because you just need to add your own unique method , So there is no need to define initialization , By default, class members use tkinter Of Button Class initialization . The code is as follows :

class MyButton(tk.Button):
def click(self):
global txt
if len(txt)<4: # Judge whether the player has chosen 4 The Chinese characters 
txt+=self['text'] # Add the button's own Chinese characters to txt
for i in range(len(txt)):
cv.itemconfig(text[i],text=txt[i]) # Change the content of the text 
self.config(state=tk.DISABLED)

self Represents each call click Method . In this way , We need to judge txt Is there already 4 A character. ( Because only 4 The Chinese characters ), If not , Let's just put the Chinese characters on the button (self[‘text’]) Added to the txt in . meanwhile , According to the changing txt, Use canvas Of itemconfig Method to change the text component text Value . In this way, we can achieve the goal of different players' choices , The effect of real-time change of text content . then , When the player selects a Chinese character ( Press a button ), We want that button to be grayed out , So it can be used directly self.config Method to change the state of the button to DISABLED( You can also directly use the dictionary to call ,self[‘state’]=tk.DISABLED).

Last , We just need to change the previously created button to this new subclass , Put the previous cycles together , The code is modified as follows :

txt = ''
text=[]
btn = []
for i in range(4):
cv.create_rectangle(50*i+50,210,50*i+86,246,fill='ivory')
text.append(cv.create_text(50*i+68,228,fill='black', font =(' Square regular script, simplified Chinese ',18,'bold')))
for j in range(5):
btn.append(MyButton(root, font =(' Square regular script, simplified Chinese ',11),width=2,relief='flat',bg='lightyellow'))
btn_window = cv.create_window(300+40*i, 75+35*j, window=btn[i*5+j])
for i in btn:
i['command']=i.click

The effect is as follows :

4). Judge the player's choice

In the button subclass we just created click In the method , We need to first judge whether the Chinese characters selected by the player have reached 4 individual . If it reaches 4 individual , We need to judge it . So we are click In the method , Add the following code :

 if len(txt)==4:
is_winner()

If txt The length of is 4, It means that there is 4 If Chinese characters are selected , call is_winner() Method , To determine whether the player wins , And subsequent operations . So we started writing is_winner() Method , Or call it a custom function .

This user-defined function actually has many functions to realize , Let's draw a partial flow chart to explain .

YesYesYesYesNoNo Guess right NoNo Missed Start judging Whether the player guessed ? Pop-up dialog box , Ask if you want to continue Judge whether you have guessed the thesaurus Ask the player whether to restart Re import Thesaurus , Clear the level Start the game from scratch Game over Clear the player's choice call create_random_word Back to the game

thus it can be seen , When the player makes the right choice , There are a lot of things to do :

  1. Ask if you want to continue
  2. Check whether the thesaurus has been guessed
  3. Ask if you want to play again

I'll post the code first :

import tkinter.messagebox as tm
def is_winner():
global word, txt, level, word_list
if txt==word:
for i in btn:
i.config(state=tk.DISABLED)
result=tm.askquestion (" Congratulations "," congratulations , bingo ! Continue with the next question ?")
if result == 'yes':
if len(word_list)==0:
newgame = tm.askquestion (" Congratulations ",f' congratulations ! You have passed all {
level} Turn off , Continue to play from scratch ?')
if newgame == 'yes':
word_list = [i[:4] for i in filenames]
random.shuffle(word_list)
level = 0
else:
root.destroy()
level += 1
cv.itemconfig(level_indicator,text=f' The first {
level} Turn off ')
clean_word()
create_random_word()
else:
tm.showinfo(title=' bye ', message=f' You have passed {
level} Turn off ')
root.destroy()
else:
clean_word()

First , In order to achieve windows The effect of the message box , We need to import tkinter Another sub module of messagebox. Use the following statement to import the module , And abbreviated as tm

import tkinter.messagebox as tm

And then you can use it tkinter Several message boxes come with it . In this small game, we only need to use two kinds , One is to ask the player whether to continue , You need to get the player's choice , The other is that you don't need players to choose , Just tell players some information . The former we use is tm Of askquestion Method , The method is different according to the user's choice , Returns a string , Or “yes”, Or “no”.

The latter is just a notification message box , Wait for the player to click “ confirm ” after , The program automatically executes the following commands , That is to say “ The destruction ” main window , Quit the game .

root.destroy()


It should be noted that , If the player really guessed all the idioms , When you choose to start over , You need to put word_list Reinitialize ( Import idioms from file names 、 Random disruption ). At the same time, clear the level count , Counting from the beginning .

Whether you guessed wrong , Or guess right and start a game , You need to call another custom function clean(), Used to put the selected in the text box 4 Chinese characters are cleared .

5). Clear selection

It is easier to clear the selected custom function , But there are three things to be done :

  1. Clear the Chinese character variable selected by the player txt
  2. Empty Canvas Text box on canvas
  3. Change the status of all buttons to NORMAL( Because some buttons are set to... After being pressed DISABLE), In this way, the player can reselect .

The code implementation is as follows :

def clean_word():
global txt
txt = ''
for i in range(4):
cv.itemconfig(text[i],text='')
for i in btn:
i.config(state=tk.NORMAL)

At the same time, we have another two buttons in the lower right corner of the game ,“ Empty ” and “ Tips ”. Now we can put the custom function directly clean_word() Bound to the “ Empty ” The button is on .

btn_clean=ttk.Button(root, text=' Empty ', width=5, command=clean_word)

6). Computer tips

The last step , It's a computer prompt button . In fact, I think this button is a little redundant , Basically, there will be no unpredictable situation . But considering that the game can be changed , For example, do not guess idioms by selecting Chinese characters , Instead, let the player manually input ( Need to increase the Entry Input box or use Label Components ), The difficulty will be greatly increased , In that case, computer prompts may still be useful . So let's do the function first , Do you want to use it .

In fact, it's very simple , Is to choose a Chinese character at random , And then let Canvas Just show the Chinese character in the text box of . So we can define a local variable hint_word, Then use a random function to generate a 0 To 3 The number of , Represents the position of the Chinese character we want to select in the idiom . And then hint_word Just assign a value to the text box .

And don't forget , It is possible for players to guess a word or two and then use the prompt , Such button states may be DISABLED, So we need to restore the state of all buttons here to NORMAL.

The code is as follows :

def hint():
global word
hint_word = ['']*4
i = random.randint(0,3)
hint_word[i] = word[i]
for i in range(4):
cv.itemconfig(text[i],text=hint_word[i])
for i in btn:
i.config(state=tk.NORMAL)

Last , Don't forget to bind this custom function to “ Tips ” On the button .

btn_submit=ttk.Button(root, text=' Tips ', width=5, command=hint)

4. Complete code

Come here , Our little game is finished . You might as well share it with your friends .

Attach complete code :

import tkinter as tk
from tkinter import ttk
import tkinter.messagebox as tm
import os
import random
class MyButton(tk.Button):
def click(self):
global txt
if len(txt)<4:
txt+=self['text']
for i in range(len(txt)):
cv.itemconfig(text[i],text=txt[i])
self.config(state=tk.DISABLED)
if len(txt)==4:
is_winner()
def create_random_word():
global word, img, word_copy
if word: word_copy.append(word)
word = word_list.pop()
lib = list(''.join(random.sample(word_copy+word_list,4))+word)
random.shuffle(lib)
for i in range(len(btn)):
btn[i]['text'] = lib[i]
img = tk.PhotoImage(file=f"images\words\{
word}.png")
cv.create_image(150,120,image = img)
def is_winner():
global word, txt, level, word_list
if txt==word:
for i in btn:
i.config(state=tk.DISABLED)
result=tm.askquestion (" Congratulations "," congratulations , bingo ! Continue with the next question ?")
if result == 'yes':
if len(word_list)==0:
newgame = tm.askquestion (" Congratulations ",f' congratulations ! You have passed all {
level} Turn off , Continue to play from scratch ?')
if newgame == 'yes':
word_list = [i[:4] for i in filenames]
random.shuffle(word_list)
level = 0
else:
root.destroy()
level += 1
cv.itemconfig(level_indicator,text=f' The first {
level} Turn off ')
clean_word()
create_random_word()
else:
tm.showinfo(title=' bye ', message=f' You have passed {
level} Turn off ')
root.destroy()
else:
clean_word()
def clean_word():
global txt
txt = ''
for i in range(4):
cv.itemconfig(text[i],text='')
for i in btn:
i.config(state=tk.NORMAL)
def hint():
global word
hint_word = ['']*4
i = random.randint(0,3)
hint_word[i] = word[i]
for i in range(4):
cv.itemconfig(text[i],text=hint_word[i])
for i in btn:
i.config(state=tk.NORMAL)
# The game starts here 
filenames = os.listdir(r'images\words')
word_list = [i[:4] for i in filenames]
random.shuffle(word_list)
# Initialization complete 
word=''
word_copy=[]
txt = ''
text=[]
btn = []
level=1
# Start to create GUI window 
root = tk.Tk()
root.geometry("500x300")
root.resizable(0,0)
root.title(' Look at the picture and guess the idiom ')
cv=tk.Canvas(root,bg='white',width=500,height=300)
bg = tk.PhotoImage(file=r"images\bg.png")
cv_bg = cv.create_image(250,150,image = bg)
title = tk.PhotoImage(file=r"images\title.png")
cv_tt = cv.create_image(250,30,image = title)
cv.create_rectangle(90,60,210,180,fill='moccasin',outline = '')
for i in range(4):
cv.create_rectangle(50*i+50,210,50*i+86,246,fill='ivory')
text.append(cv.create_text(50*i+68,228,fill='black', font =(' Square regular script, simplified Chinese ',18,'bold')))
for j in range(5):
btn.append(MyButton(root, font =(' Square regular script, simplified Chinese ',11),width=2,relief='flat',bg='lightyellow'))
btn_window = cv.create_window(300+40*i, 75+35*j, window=btn[i*5+j])
for i in btn:
i['command']=i.click
btn_clean=ttk.Button(root, text=' Empty ', width=5, command=clean_word)
btn_submit=ttk.Button(root, text=' Tips ', width=5, command=hint)
cv.create_window(320, 265, window=btn_clean)
cv.create_window(400, 265, window=btn_submit)
level_indicator = cv.create_text(150,270,text=f' The first {
level} Turn off ', fill='black', font=(' Microsoft regular script ',9,'bold'))
create_random_word()
cv.pack()
root.mainloop()

Summary and reflection

After a week of staying up late , Brother Wen finally explained this little game completely . I don't know if it was detailed enough , Is there anything you don't understand ? You are welcome to send me a private message or leave me a message . meanwhile , Through this little game , We also learned Python Built in graphical components tkinter Some basic operations , I hope that if you feel that you have not explained anything thoroughly , You can also learn by searching similar articles on the Internet , Or ask me directly in a private letter .

Thank you for reading here , See you next time !


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved