pygame實(shí)現(xiàn)井字棋之第二步邏輯實(shí)現(xiàn)
一、前言
我們?cè)?a target="_blank" href="http://www.dbjr.com.cn/article/211469.htm">上一篇博客中實(shí)現(xiàn)了九宮格的繪制,為我們打下了基礎(chǔ)。
這次我們來(lái)實(shí)現(xiàn)基本的邏輯,比如判斷輸贏、玩家和電腦分別下棋的邏輯。
二、下棋
2.1 玩家
我們之前在Lattice
類(lèi)中,有一個(gè)stats變量來(lái)表示格子的狀態(tài),
# 0表示初始,1表示個(gè)人-1表示電腦 self.stats = 0
所以下棋本質(zhì)上就是修改這個(gè)變量。
首先,我們是用鼠標(biāo)點(diǎn)擊的方式來(lái)實(shí)現(xiàn)下棋的,所以應(yīng)當(dāng)修改事件響應(yīng)部分:
for event in pygame.event.get(): # 退出 if event.type == pygame.QUIT: sys.exit() # 點(diǎn)擊鼠標(biāo) elif event.type == pygame.MOUSEBUTTONDOWN: # 獲得鼠標(biāo)點(diǎn)擊的位置 mouse_x, mouse_y = pygame.mouse.get_pos() for i in rect: # 確定玩家下了一步 if not i.stats and i.rect.collidepoint(mouse_x,mouse_y): i.stats = -1
pygame.event模塊主要是負(fù)責(zé)游戲中的事件。
第一個(gè)事件表示點(diǎn)擊界面的右上角關(guān)閉鍵,退出程序;
第二個(gè)事件是鼠標(biāo)點(diǎn)擊,可以使用pygame.mouse.get_pos得到點(diǎn)擊位置。
因?yàn)橹暗母褡樱↙attice類(lèi))中有一個(gè)rect類(lèi)的實(shí)例,我們可以使用collidepoint函數(shù),傳入坐標(biāo)判斷是在哪個(gè)格子中。
隨后我們需要判斷格子有沒(méi)有被占用,沒(méi)被占用,那么我們就可以修改stats。
2.2 電腦
對(duì)于電腦來(lái)說(shuō),實(shí)際情況差不多,不過(guò)我們選擇了隨機(jī)生成的方式:
def computer(): """電腦的回合,隨機(jī)生成一個(gè)位置""" global judge random_num = [i for i in range(len(rect)) if not rect[i].stats] # 沒(méi)位子下了,平局 if not random_num: judge = 1 print("draw") exit() rect[random.choice(random_num)].stats = 1 return #result = Button("your choice")
我們先給出了所有沒(méi)有被占用的格子,使用列表解析形成列表。
如果列表為空,沒(méi)位子下了,就說(shuō)明平局(在每一次落子之后,都會(huì)有輸贏的判斷,后面再說(shuō));
反之,我們就用random.choice函數(shù),在列表中選擇一個(gè)元素(這個(gè)元素為L(zhǎng)attice類(lèi)的實(shí)例),將其stats修改為1。
judge這個(gè),是判斷是否結(jié)束游戲的標(biāo)志,初始為0。
三、輸贏判斷
這個(gè)可能會(huì)麻煩一點(diǎn)。
這里,我的想法是每一個(gè)格子都有一個(gè)下標(biāo),將所有可能贏的格子組合的下標(biāo)都寫(xiě)出來(lái)。
win_list = [ # 行 [0, 1, 2], [3, 4, 5], [6, 7, 8], # 列 [0, 3, 6], [1, 4, 7], [2, 5, 8], # 對(duì)角 [0, 4, 8], [2, 4, 6] ]
隨后,我們同樣使用列表解析,將所有stats為1和-1的組成兩個(gè)列表:
stats1 = [i for i in range(len(rect)) if rect[i].stats == 1] stats2 = [i for i in range(len(rect)) if rect[i].stats == -1]
那么問(wèn)題來(lái)了,stats1、2中,可能只有部分元素在win_list中,瞬間找到了被leecode支配的恐懼。
for i in win_list: # 取出每一個(gè)可能獲勝的條件 if i == [j for j in i if j in stats1]: judge = 1 print("Computer win!") exit() elif i == [j for j in i if j in stats2]: judge = 1 print("You win!") exit()
我們的邏輯是對(duì)每一個(gè)獲勝可能組合,分別取出每一個(gè)元素,并在stats列表中查找,如果都能找到,列表解析式的結(jié)果就一定和原先的獲勝組合相同,此時(shí)我們就可以判斷一方獲勝。
四、一人一子
井字棋和五子棋的玩法差不多,所以必須做到在玩家下子后,電腦能下子。
(正常電腦的反應(yīng),可是比玩家快多了。
當(dāng)然可以設(shè)置一個(gè)變量,0、1分別表示誰(shuí)該下子了,但是我有更好的選擇——在玩家下子后進(jìn)行輸出。
if not i.stats and i.rect.collidepoint(mouse_x,mouse_y): # 玩家下棋 i.stats = -1 win_or_lose() # 電腦下棋 computer() win_or_lose()
還有一個(gè)問(wèn)題,就是不管哪方下子了,我們都需要對(duì)輸贏進(jìn)行判斷。
五、顯示問(wèn)題
當(dāng)你完成了上述操作,會(huì)發(fā)現(xiàn),其實(shí)屏幕上什么都看不到。
因?yàn)槲覀冞€沒(méi)有顯示格子的圖標(biāo)。
這里我選擇使用經(jīng)典的'x'、‘o',用渲染文字的方式實(shí)現(xiàn)。(這部分也可以自己找圖貼上去)
渲染文字的步驟:
- self.font = pygame.font.SysFont設(shè)置字體
- self.font.render函數(shù),生成一個(gè)含有文本信息的圖像
- 將圖像使用get_rect方法處理成矩形,進(jìn)行對(duì)齊
- 使用blit方法渲染
lattice.py文件:
import pygame class Lattice(): def __init__(self,rect,screen): self.rect = rect self.screen = screen # 0表示初始,1表示個(gè)人-1表示電腦 self.stats = 0 # 文本顏色 self.text_color = (30, 30, 30) # 背景顏色,也就是我們screen渲染的顏色 self.bg_color = (255, 255, 255) # 設(shè)置字體 self.font = pygame.font.SysFont(None,48) def draw(self): # 按照狀態(tài)賦值文本信息 msg = "" if self.stats == -1: msg = "x" elif self.stats == 1: msg = "o" if msg: self.msg_image = self.font.render(msg,True,self.text_color,self.bg_color) self.msg_rect = self.msg_image.get_rect() self.msg_rect.center = self.rect.center self.screen.blit(self.msg_image,self.msg_rect)
render函數(shù):
傳入?yún)?shù):文本信息,Boolean(控制曲線(xiàn)是否光滑,沒(méi)試過(guò)),文本顏色,背景顏色(也就是我們screen渲染的顏色)
返回一個(gè)圖片類(lèi)型。
get_rect()方法:
將圖片處理成矩形,pygame有一點(diǎn)很好,就是不管什么樣的圖形都能當(dāng)成矩形處理
rect對(duì)象,有centerx、centery、x、y等一系列屬性,方便我們進(jìn)行對(duì)齊操作,在這里不展開(kāi)說(shuō)了。
blit方法:
輸入圖片和矩形(這里的矩形實(shí)質(zhì)上是給方法指明顯示的坐標(biāo)),
在screen上顯示。
在主模塊中:
def update(): for i in rect: i.draw() # 將界面顯示 pygame.display.flip()
如果只是在while循環(huán)的開(kāi)始寫(xiě)一個(gè)update,會(huì)發(fā)現(xiàn)實(shí)際上我們是不能及時(shí)看到結(jié)果的,這樣很明顯有影響,所以在每一次落子之后,我們都會(huì)進(jìn)行一次刷新,然后再判斷輸贏。
if not i.stats and i.rect.collidepoint(mouse_x,mouse_y): # 玩家下棋 i.stats = -1 update() win_or_lose() # 電腦下棋 computer() update() win_or_lose()
六、結(jié)語(yǔ)
這樣,我們這個(gè)井字棋基本上就可以玩了,但是我們還是需要進(jìn)行一些修改。
下一篇博客,我將對(duì)細(xì)節(jié)進(jìn)行整改。
下一篇:pygame實(shí)現(xiàn)井字棋——3.邏輯優(yōu)化
上一篇:pygame實(shí)現(xiàn)井字棋——1.繪制九宮格
到此這篇關(guān)于pygame實(shí)現(xiàn)井字棋之第二步邏輯實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)pygame井字棋游戲內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python深度學(xué)習(xí)tensorflow安裝調(diào)試教程
這篇文章主要為大家介紹了python深度學(xué)習(xí)tensorflow安裝調(diào)試教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06pyhton Sanic框架的文件上傳功能開(kāi)發(fā)實(shí)戰(zhàn)示例教程
Sanic是一個(gè)Python 3.5+的異步Web框架,它的設(shè)計(jì)理念與Flask相似,但采用了更高效的異步I/O處理,在處理文件上傳時(shí),Sanic同樣提供了方便、高效的方法,本教程將結(jié)合實(shí)際案例,詳細(xì)介紹如何在Sanic框架中實(shí)現(xiàn)文件上傳的功能,感興趣的朋友跟隨小編一起看看吧2024-08-08PyTorch實(shí)現(xiàn)FedProx聯(lián)邦學(xué)習(xí)算法
這篇文章主要為大家介紹了PyTorch實(shí)現(xiàn)FedProx的聯(lián)邦學(xué)習(xí)算法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05numpy中的transpose函數(shù)中具體使用方法
本文主要介紹了numpy中的transpose函數(shù)中具體使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02python 監(jiān)控某個(gè)進(jìn)程內(nèi)存的情況問(wèn)題
這篇文章主要介紹了python 監(jiān)控某個(gè)進(jìn)程內(nèi)存的情況問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05一篇文章帶你了解python標(biāo)準(zhǔn)庫(kù)--sys模塊
這篇文章主要介紹了Python標(biāo)準(zhǔn)庫(kù)之Sys模塊使用詳解,本文講解了使用sys模塊獲得腳本的參數(shù)、處理模塊、使用sys模塊操作模塊搜索路徑、使用sys模塊查找內(nèi)建模塊、使用sys模塊查找已導(dǎo)入的模塊等使用案例,需要的朋友可以參考下2021-08-08Python中sort函數(shù)正則表達(dá)式的使用
在python中,sort是列表排序的一種方法,本文就來(lái)介紹一下sort函數(shù)正則表達(dá)式的使用以及與sorted的區(qū)別,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03Python字典的概念及常見(jiàn)應(yīng)用實(shí)例詳解
這篇文章主要介紹了Python字典的概念及常見(jiàn)應(yīng)用,結(jié)合實(shí)例形式詳細(xì)的分析了Python字典的概念、原理、創(chuàng)建、常見(jiàn)操作函數(shù)與使用注意事項(xiàng),需要的朋友可以參考下2019-10-10使用python將請(qǐng)求的requests headers參數(shù)格式化方法
今天小編就為大家分享一篇使用python將請(qǐng)求的requests headers參數(shù)格式化方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01