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

Python寫個小游戲:速算24點(下)

編輯:Python

文章目錄

  • 前言
  • 速算24點
    • 1. 玩法簡介
    • 2. 游戲流程
    • 3. 剩下的部分
      • 1). 關卡 / 分數信息
        • IntVar類
      • 2). 提示按鈕
        • 圖片
        • 按鈕
      • 3). 重新發牌
    • 4. 讓電腦計算24點
      • 1). 表達式的特征
      • 2). 代碼的實現
        • 將撲克牌轉換成數字
        • 數字的排列組合
        • 添加運算符
        • 插入小括號
        • 返回運算結果
      • 3). 調用計算函數
    • 5. 知識點回顧
  • 完整代碼


前言

大家好,最近實在是有點忙,下篇遲遲沒有動筆。上一篇文章也結束得很匆忙,實在抱歉。代碼部分其實早已寫好,但是問哥還是想盡力將其拆解、講解清楚,所以並不是直接分享代碼。當然,如果想跳過問哥啰嗦的廢話,直接參考代碼,也可以跳到文章末尾查閱。

廢話不多說,馬上進入我們剩下的部分:

上篇 —— 游戲界面搭建
下篇 —— 功能代碼實現


速算24點

1. 玩法簡介

游戲規則比較簡單:找一副撲克牌,去掉大小王,52張牌,每次隨機抽取四張牌,運用加減乘除四種計算方法,看看誰能最快計算出24點。雖說是單機游戲,沒有比賽的壓力,但還是增加了計時功能:如果90秒內未能找出答案,則視為當前測試失敗,自動進入下一關。同時,為了降低難度,提供了提示功能:闖關過程中,共有三次機會獲得提示參考答案。

游戲截圖:

2. 游戲流程

速算24點的簡易流程圖如下:

NoYesYesNoYesNo 更換下一組NoYes 游戲開始 牌堆是否為0 抽取4張牌 計算該組合是否有解 倒計時開始 玩家輸入答案 判斷答案是否正確 停止倒計時 是否進入下一局 游戲結束 洗牌 有三次機會使用提示 時間用完,自動進入下一局

3. 剩下的部分

上篇內容裡講解了大部分界面的搭建,還有兩個小地方,一個是關卡信息,一個是提示按鈕。

1). 關卡 / 分數信息

IntVar類

上篇我們引入了StringVar類,實例了變量後,用來和標簽綁定,可以直接將變量的內容顯示在標簽上,從而省去了不少麻煩。而StringVar是針對字符串,對於純粹的數字,tkinter還提供了類似功能的IntVar類。同樣地,將其和標簽或其他組件綁定,即可直接將IntVar類實例的值顯示出來。與StringVar相區別的是,IntVar是整數(int),可以直接參與計算,所以,用來記錄玩家已測試的關卡數,以及通過的關卡(分數),也是十分方便的。

於是,我們先定義兩個變量,實例化IntVar類:

level=IntVar()
score=IntVar()

再創建4個標簽,兩個用來顯示固定字符“已測試”、“已通過”,另外兩個用來和變量level、score綁定,以動態顯示當前的關卡和分數。

cv.create_text(600,350,text='已測試:',font =('方正楷體簡體',16,'bold'))
cv.create_text(600,400,text='已通過:',font =('方正楷體簡體',16,'bold'))
level_lable = Label(root,text='',font=('微軟雅黑',15),textvariable=level,bg='lightyellow')
cv_level = cv.create_window(670,350,window=level_lable)
score_lable = Label(root,text='',font=('微軟雅黑',15),textvariable=score,bg='lightyellow')
cv_score = cv.create_window(670,400,window=score_lable)

實現效果如下圖:

2). 提示按鈕

提示按鈕區域還分了兩部分,一部分是按鈕,另一部分是小燈泡的圖片,用來表示玩家還剩多少次機會。

圖片

問哥從網上找到的小燈泡的圖片,將它改成png格式,然後命名為idea。

先定義一個常量HINT,用來表示玩家可以有多少次提示機會。默認是3次,當然你也可以改成5次,更多或更少。然後再通過for循環,在指定的位置繪制3個燈泡圖片,並將這些繪制的組件放在一個列表ideas裡。

HINT = 3
idea = PhotoImage(file=r"image\poker\idea.png")
ideas = []
for i in range(HINT):
ideas.append(cv.create_image(450+i*25,450,image = idea))

為什麼放進列表呢?因為可以方便我們在按下提示按鈕後,自動減少圖片並在畫布上刷新。

按鈕

按鈕的創建很簡單,我們之前也介紹過。問哥為了加速完成這個小項目,就不使用特效了,於是默認使用tkinter的Button組件。

btn = Button(root,text='提示',width=5,command=hint)
cv_btn = cv.create_window(400,450,window=btn)

關鍵是我們需要為這個按鈕綁定一個回調函數,起名叫hint,在該函數裡,我們要完成以下三個功能:

  1. 獲取正確答案right_answer,並顯示在標簽上
  2. 將按鈕禁用,以防止玩家不小心點擊了多次,從而浪費了提示次數
  3. 減少一個“小燈泡”

實現代碼如下:

def hint():
answer.set(right_answer)
btn['state']=DISABLED
idea = ideas.pop()
cv.delete(idea)

同樣的道理,為了防止玩家誤操作(你永遠無法完全預見玩家或用戶大開腦洞的操作),也為了減少程序的可能,我們規定該按鈕只允許在被點擊的時候啟用,換句話說,除了倒計時開始,玩家開始答題時,而且提示次數沒有用完(ideas>0),按鈕的狀態是NORMAL,其他時間該按鈕都應該處於DISABLED狀態。

於是,我們分別在其他位置做以下更新:

def initialize():
# 省略代碼
btn['state']=DISABLED
def draw_card():
# 省略代碼
if len(ideas)>0: btn['state']=NORMAL

測試效果基本OK:

3). 重新發牌

代碼寫到這裡,除了還沒有讓電腦替我們找出正確答案,已經實現基本的輸入、判斷等功能了。試著運行一下:

發現回答正確、在選擇繼續下一局後,桌面上的發牌混亂了,不知道新的四張牌跑到哪裡去了,這是怎麼回事?

原來,我們在上篇用了一個數組cv_card來儲存抽出來的四張牌,並使用for循環將這四張牌顯示在桌面上,但是沒有考慮到當一局游戲結束,需要重新抽四張牌的情況。在這種情況下,我們需要把桌面上的4張牌從畫布上擦去,用代碼的話主要是兩步:

  1. 刪除圖片
  2. 清空列表

為了避免重復操作,我們再定義一個子程序來完成清除clear的操作:

def clear(cv_card):
for i in cv_card:
cv.delete(i)
cv_card.clear()

然後,我們再把該函數放在抓牌函數的開始,這樣,每次開始抓牌前,我們都先清除(如果有的話)上一輪的四張牌,從而保證代碼對新的四張牌依然適用。

def draw_card():
clear(cv_card)

同樣的理由,我們在重新開始下一局後,答案標簽的內容也需要清空,所以我們需要在initialize函數以及myanswer函數裡添加以下代碼:

def initialize():
answer.set('')
# 省略代碼
def myanswer(event):
# 省略代碼
if s=='BackSpace':
txt=txt[:-1]
elif s=='Return':
if is_right(txt):
root.after_cancel(cd)
c = tm.askyesno(message='繼續下一局嗎?')
if c:
# 省略代碼
return # 添加 return,表示進入下一局後就不繼續顯示標簽

經測試,在沒有電腦幫助的情況下,已經可以成功地“自食其力”進行闖關了。可問題是,常常會出現這種情況:抽出四張牌,卻很難寫出答案,因為我們也無法確定是我們沒有想出答案,還是這四張牌根本沒有答案。所以,我們需要設計一個方法,讓電腦替我們先算好答案,保存在變量right_answer裡,如果沒有答案的話,就自動更換下一組。有了right_answer,提示按鈕也就可以發揮作用了。

4. 讓電腦計算24點

算起來,這部分其實是相對獨立的代碼,因為我們可以把要解決的問題從這個游戲裡抽離出來,轉換為“給定4個數,計算出能否通過排列組合,使得這四個數組成的算式運算結果等於24。”

1). 表達式的特征

為了解決這個問題,我們觀察一下四個數字組成的算術表達式的特征:

  1. 不考慮小括號的情況(也相當於一對小括號把四個數字包起來)。算式的形式為:(a+b+c+d),其中有4個數字,3個運算符(這裡加號+只是代表運算符,可以是加減乘除的任意一種)。
  2. 考慮小括號的情況又分為兩種:
第一種情況:一對小括號第二種情況:兩對小括號(a+b)+c+d(a+b)+(c+d)a+(b+c)+d((a+b)+c)+da+b+(c+d)(a+(b+c))+d(a+b+c)+da+((b+c)+d)a+(b+c+d)a+(b+(c+d))
  1. 再進一步觀察可以發現,就像(a+b+c+d)的括號可以省略一樣,(a+b+c)+d,a+(b+c+d)也一定與兩對括號的情況重復:(a+b+c)+d 必定等價於 ((a+b)+c)+d 或 (a+(b+c))+d;a+(b+c+d) 必定等價於 a+((b+c)+d) 或 a+(b+(c+d))。所以最終,我們只需要考慮8種情況:
    (a+b)+c+d
    a+(b+c)+d
    a+b+(c+d)
    (a+b)+(c+d)
    ((a+b)+c)+d
    (a+(b+c))+d
    a+((b+c)+d)
    a+(b+(c+d))
    當然,這裡仍然存在較大重復計算的可能性,假如三個運算符都是加法或乘法的話,上面八個表達式都是等價的,所以這並不是一個最優的算法。

2). 代碼的實現

雖然存在很多重復計算,但在不考慮時間復雜度,以及運算量並不算大的情況下,完全可以讓電腦進行窮舉運算,把所有的可能性都檢查一遍。於是我們可以把代碼的實現過程分成三步:

  1. 找出4個數字所有不重復的排列組合,最多有24種可能(4!)
  2. 找出3個運算符(加減乘除)的排列組合,因為運算符可重復使用,所以是4^3=64種可能。(這裡面有一些組合是不可能計算出24點的,比如連續三個減號或除號,但是如果添加小括號使得計算順序發生改變的話,結果將有所不同。為了省事,這裡就把所有排列組合都考慮了)
  3. 在算式的不同位置添加小括號。根據前面列舉的,總共有8種可能。

於是,不考慮存在重復的情況下,最多總共有 24*64*8 = 12288 種可能。這點計算量對人類來說可能望而卻步,但是對電腦來說簡直不值一提。更何況,我們並不用找出所有正確答案,而是只要找到一個即可。

下面我們開始寫代碼:

將撲克牌轉換成數字

我們首先要做的,就是把抽取的4張牌轉化為數字。因為撲克牌的數字是從0到51,但是所代表的用於計算的數字卻是從1到13,這其實可以通過簡單的求余運算來實現。

於是,我們定義一個函數:

def calnum(n):
global nums
nums=[i%13+1 for i in n]
formula=form(nums)

這個函數接收一個變量n,代表含有4張牌的列表,然後通過列表生成式(或稱為推導式)將其轉換成一個實際用於計算的數字的列表nums。然後再調用另一個自定義函數form()將這個列表通過排列組合轉化成含有最多12288個表達式的列表,保存為formula。

需要注意的是,我們還要將nums聲明成全局變量。這樣做的唯一目的,是為了在判斷玩家輸入的時候,是否只使用了給定的4個數字。於是,我們順便將判斷玩家輸入的函數 is_right() 也更新如下:

def is_right(txt):
# 省略代碼
if sorted(txt)!=sorted(nums):
tm.showinfo(message='請使用給定的數字!')
return False
# 省略代碼

下面我們接著寫form()函數。

數字的排列組合

為了不重復制造輪子,我們可以直接使用Python提供的內置模塊來計算排列組合。

from itertools import permutations
def form(nums):
numlist=set(permutations(nums))

從itertools模塊中導入permutations函數以後,就可以使用它來計算列表的排列組合了。這個函數接收兩個參數,第一個是列表等可迭代對象,第二個是數字,表示從前面的列表裡取出幾個元素進行排列組合,可以省略,如果省略的話,則表示默認對所有元素進行排列組合。於是在這裡,我們可以省略第二個參數,直接將含有4個數字的nums列表交給permutations函數,返回一個可迭代對象。同時,為了去重,比如四張牌裡有重復的數字,3,3,4,4這種,我們可以將這個結果轉換為集合set,最終將結果保存在numlist裡。

在控制台測試結果:

>>> from itertools import permutations
>>> nums = [1,2,3,4]
>>> numlist = permutations(nums)
>>> type(numlist)
<class 'itertools.permutations'>
>>> for i in numlist: print(i,end=' ')
(1, 2, 3, 4) (1, 2, 4, 3) (1, 3, 2, 4) (1, 3, 4, 2) (1, 4, 2, 3) (1, 4, 3, 2) (2, 1, 3, 4) (2, 1, 4, 3) (2, 3, 1, 4) (2, 3, 4, 1) (2, 4, 1, 3) (2, 4, 3, 1) (3, 1, 2, 4) (3, 1, 4, 2) (3, 2, 1, 4) (3, 2, 4, 1) (3, 4, 1, 2) (3, 4, 2, 1) (4, 1, 2, 3) (4, 1, 3, 2) (4, 2, 1, 3) (4, 2, 3, 1) (4, 3, 1, 2) (4, 3, 2, 1)
>>>

可以看到,如我們所預想的,4個不重復的數字可以組成最多24個互不重復的組合。

添加運算符

接下來,我們需要在這四個數字中間插入三個運算符,當然,我們首先要找到運算符組成的64種組合,使用三層循環即可實現,並將結果保存在列表operations裡。

operations=[]
for i in '+-*/':
for j in '+-*/':
for k in '+-*/':
operation = i+j+k
operations.append(operation)

因為這個列表會被頻繁調用(每發四張牌,就要插入運算符),所以我們可以將它放在主程序裡,這樣只要在游戲開始時運算一次,在函數裡就可以一直調用(而不修改)。

接著,在函數form裡,我們同樣使用for循環來將3個運算符插入到4個數字之間:

def form(nums):
numlist=set(permutations(nums))
combo=[]
for num in numlist:
for i in operations:
temp=[]
for j in range(3):
temp+=[str(num[j]),i[j]]
temp.append(str(num[j+1]))
combo.append(temp)

因為最終我們需要將表達式轉換成字符串,所以在這裡我們就可以使用str函數將數字轉換成字符串,保存在列表combo裡。根據之前計算的,combo裡最多應該存在 24*64 = 1536 個元素,代表了1536個表達式。但是現在它們任然是單個的字符,因為我們還需要插入小括號。

插入小括號

小括號用於提升運算等級、改變運算順序。根據前面所分析的,由於默認計算順序為先乘除、後加減、從左到右依次運算,所以不包含小括號的情況(a+b+c+d)一定等價於某種使用小括號的情況。所以最終我們只需要考慮8種小括號的情況:三種一對小括號的情況,和五種兩對小括號的情況。但是該怎樣插入呢?

通過之前的計算,我們得到的combo二維列表裡的表達式列表應該類似這個樣子:
[‘1’, ‘+’, ‘2’, ‘+’, ‘3’, ‘+’, ‘4’]

可見,每個表達式都是包含7個字符串元素(4個數字、3個運算符)的列表。於是,我們只要事先找到需要添加小括號的位置(索引),就可以通過循環添加了。

通過比較,我們將兩種情況(一對和兩對小括號)的左右小括號的位置索引找到,並創建列表如下:

 one=[(3,0),(5,2),(7,4)]
two=[(7,3,5,0),(5,3,0,0),(5,5,2,0),(7,5,2,2),(7,7,4,2)]

需要注意的是,我們要先插入右邊的小括號,再插入左邊小括號。因為插入元素以後,列表的長度改變,為了方便計算,先插入右邊小括號可以最大程度保持相對位置。在兩對小括號的時候也是如此(先插入右側的括號),只需要注意其中一種情況:(a+b)+(c+d)。在這種情況下,插入兩個右括號之後,夾在兩個右括號中間的左括號位置發生了變化,只要記錄新的位置即可。

於是,通過索引列表,我們可以將form函數補全:

def form(nums):
numlist=set(permutations(nums))
combo=[]
for num in numlist:
for i in operations:
temp=[]
for j in range(3):
temp+=[str(num[j]),i[j]]
temp.append(str(num[j+1]))
combo.append(temp)
one=[(3,0),(5,2),(7,4)]
two=[(7,3,5,0),(5,3,0,0),(5,5,2,0),(7,5,2,2),(7,7,4,2)]
formula=[]
for i in combo:
for j in one:
temp=i[:]
temp.insert(j[0],')')
temp.insert(j[1],'(')
formula.append(''.join(temp)) # 將列表轉化為字符串
for j in two:
temp=i[:]
temp.insert(j[0],')')
temp.insert(j[1],')')
temp.insert(j[2],'(')
temp.insert(j[3],'(')
formula.append(''.join(temp)) # 將列表轉化為字符串
return formula

返回運算結果

最後,我們得到包含最多12288個表達式的列表formula,並返回到函數calnum裡使用eval函數進行計算。

def calnum(n):
# 省略代碼
formula=form(nums)
for i in formula:
try:
result = eval(i)
except:
continue
if math.isclose(result,24):
return i
return 'None'

通過for循環遍歷formula列表,依次計算結果是否等於24。如果正確,則把正確答案(表達式)返回,如果遍歷所有12288種可能都沒有結果,則返回字符串None。

3). 調用計算函數

按照我們之前的邏輯,在每次抓取4張牌之後,我們都需要電腦幫忙計算,看看當前4張牌能否計算出24點,如果不能,則自動進入下一局(重新抓牌),如果可以,則將答案保存在變量right_answer裡,方便提示(hint)按鈕調用。於是,我們更新相應部位的代碼即可:

def draw_card():
global cv_card, right_answer
invalid=True
while invalid:
clear(cv_card)
draw=[]
if len(cardnum)==0:
tm.showinfo(message='牌堆已用完,為您重新洗牌')
shuffle_card()
for i in range(4):
draw.append(cardnum.pop())
cv_card.append(cv.create_image(100,200,image=card[draw[i]]))
if len(cardnum)==0:cv.delete(cv_back)
for _ in range(150*(i+1)):
cv.move(cv_card[i],1,0)
cv.update()
right_answer = calnum(draw) # 調用函數計算12288種可能
if right_answer=='None':
tm.showinfo(message='本組數字無解,為您自動更換下一組')
else:
countdown()
if len(ideas)>0: btn['state']=NORMAL
invalid=False

如果4張牌無法計算24點,就需要一直重新抽牌,直到可以計算為止。於是這裡使用一個while循環,並給定一個標記 invalid 假定當前組合無法計算24點。只有當得到答案時(right_answer的值不是None),invalid變為False,結束while循環,開始計時等後續程序。

5. 知識點回顧

  1. Canvas的delete方法
  2. IntVar類型
  3. permutations函數

到這裡,我們這個“速算24點”的小游戲就做好了。大家可以繼續在裡面添加其他想要的功能,改變布局、顏色等等。最終運行效果如下:


完整代碼

from tkinter import *
import tkinter.messagebox as tm
import random
import math
from itertools import permutations
def shuffle_card():
global cardnum, back, cv_back
cardnum = list(range(52))
random.shuffle(cardnum)
back = PhotoImage(file=r"image\poker\back1.png")
cv_back = cv.create_image(100,200,image = back)
def clear(cv_card):
for i in cv_card:
cv.delete(i)
cv_card.clear()
def draw_card():
global cv_card, right_answer
invalid=True
while invalid:
clear(cv_card)
draw=[]
if len(cardnum)==0:
tm.showinfo(message='牌堆已用完,為您重新洗牌')
shuffle_card()
for i in range(4):
draw.append(cardnum.pop())
cv_card.append(cv.create_image(100,200,image=card[draw[i]]))
if len(cardnum)==0:cv.delete(cv_back)
for _ in range(150*(i+1)):
cv.move(cv_card[i],1,0)
cv.update()
right_answer = calnum(draw)
if right_answer=='None':
tm.showinfo(message='本組數字無解,為您自動更換下一組')
else:
countdown()
if len(ideas)>0: btn['state']=NORMAL
invalid=False
def initialize():
global angle,count,cv_arc,cv_inner,cv_text
count=90
angle=360
btn['state']=DISABLED
answer.set('')
cv_arc=cv.create_oval(100,330,200,430,fill='red',outline='yellow')
cv_inner=cv.create_oval(120,350,180,410,fill='yellow',outline='yellow')
cv_text=cv.create_text(150,380,text=count,font =('微軟雅黑',20,'bold'),fill='red')
draw_card()
def countdown():
global angle,count,cv_arc,cv_inner,cv_text,cd
if angle == 360:
angle -= 1
else:
cv.delete(cv_arc)
cv.delete(cv_inner)
cv.delete(cv_text)
cv_arc=cv.create_arc(100,330,200,430,start=90,extent=angle,fill="red",outline='yellow')
angle -= 1
if angle%4 == 0: count-=1
cv_inner=cv.create_oval(120,350,180,410,fill='yellow',outline='yellow')
cv_text=cv.create_text(150,380,text=count,font =('微軟雅黑',20,'bold'),fill='red')
if count==0:
tm.showinfo(message='倒計時結束!自動進入下一局')
level.set(int(level.get())+1)
cv.delete(cv_arc)
cv.delete(cv_inner)
cv.delete(cv_text)
initialize()
else:
cd = root.after(250,countdown)
def myanswer(event):
s=event.keysym
txt=answer.get()
if s=='BackSpace':
txt=txt[:-1]
elif s=='Return':
if is_right(txt):
level.set(int(level.get())+1)
score.set(int(score.get())+1)
root.after_cancel(cd)
c = tm.askyesno(message='繼續下一局嗎?')
if c:
cv.delete(cv_arc)
cv.delete(cv_inner)
cv.delete(cv_text)
initialize()
return
else:root.destroy()
else:
txt=''
elif s.isnumeric():
txt+=s
elif s in trans:
txt+=trans[s]
answer.set(txt)
def is_right(txt):
try:
result = eval(txt)
except:
tm.showinfo(message='算式不正確,請重新輸入!')
return False
for i in '+-*/()':
txt=txt.replace(i,' ')
txt=[int(i) for i in txt.split()]
if sorted(txt)!=sorted(nums):
tm.showinfo(message='請使用給定的數字!')
return False
if math.isclose(result,24):
tm.showinfo(message='恭喜您!回答正確!')
return True
def hint():
answer.set(right_answer)
btn['state']=DISABLED
idea = ideas.pop()
cv.delete(idea)
def calnum(n):
global nums
nums=[i%13+1 for i in n]
formula=form(nums)
for i in formula:
try:
result = eval(i)
except:
continue
if math.isclose(result,24):
return i
return 'None'
def form(nums):
numlist=set(permutations(nums))
combo=[]
for num in numlist:
for i in operations:
temp=[]
for j in range(3):
temp+=[str(num[j]),i[j]]
temp.append(str(num[j+1]))
combo.append(temp)
one=[(3,0),(5,2),(7,4)]
two=[(7,3,5,0),(5,3,0,0),(5,5,2,0),(7,5,2,2),(7,7,4,2)]
formula=[]
for i in combo:
for j in one:
temp=i[:]
temp.insert(j[0],')')
temp.insert(j[1],'(')
formula.append(''.join(temp))
for j in two:
temp=i[:]
temp.insert(j[0],')')
temp.insert(j[1],')')
temp.insert(j[2],'(')
temp.insert(j[3],'(')
formula.append(''.join(temp))
return formula
# 游戲從這裡開始
HINT = 3
operations=[]
for i in '+-*/':
for j in '+-*/':
for k in '+-*/':
operation = i+j+k
operations.append(operation)
trans={
'plus':'+','minus':'-','asterisk':'*','slash':'/','parenleft':'(','parenright':')'}
root = Tk()
root.geometry('800x500+400+200')
root.resizable(0,0)
root.title('速算24點')
# 畫布大小和主窗口大小一致
cv = Canvas(root,width=800,height=500)
# 背景圖片
bg = PhotoImage(file=r"image\poker\bg.png")
cv_bg = cv.create_image(400,250,image = bg)
# 標題圖片
title = PhotoImage(file=r"image\poker\title.png")
cv_title = cv.create_image(400,60,image = title)
# 顯示答案及關卡分數等信息
answer=StringVar()
level=IntVar()
score=IntVar()
cv.create_text(400,350,text='請輸入您的答案',font =('方正楷體簡體',18,'bold'))
lb = Label(root,text='',font=('微軟雅黑',15),textvariable=answer,bg='lightyellow')
cv_lb = cv.create_window(400,400,window=lb)
cv.create_text(600,350,text='已測試:',font =('方正楷體簡體',16,'bold'))
cv.create_text(600,400,text='已通過:',font =('方正楷體簡體',16,'bold'))
level_lable = Label(root,text='',font=('微軟雅黑',15),textvariable=level,bg='lightyellow')
cv_level = cv.create_window(670,350,window=level_lable)
score_lable = Label(root,text='',font=('微軟雅黑',15),textvariable=score,bg='lightyellow')
cv_score = cv.create_window(670,400,window=score_lable)
# 提示圖片及按鈕
idea = PhotoImage(file=r"image\poker\idea.png")
ideas = []
for i in range(HINT):
ideas.append(cv.create_image(450+i*25,450,image = idea))
btn = Button(root,text='提示',width=5,command=hint)
cv_btn = cv.create_window(400,450,window=btn)
# 綁定從鍵盤獲取輸入<Key>,並傳給自定義函數myanswer
lb.bind('<Key>',myanswer)
# 使標簽組件獲得焦點,不然無法從鍵盤輸入
lb.focus_set()
card = [PhotoImage(file=f'image/poker/{
i:0>2}.png') for i in range(1,53)]
cv_card=[]
cv.pack()
shuffle_card()
initialize()
root.mainloop()

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