pygame實現井字棋之第二步邏輯實現
一、前言
我們在上一篇博客中實現瞭九宮格的繪制,為我們打下瞭基礎。
這次我們來實現基本的邏輯,比如判斷輸贏、玩傢和電腦分別下棋的邏輯。
二、下棋
2.1 玩傢
我們之前在Lattice
類中,有一個stats變量來表示格子的狀態,
# 0表示初始,1表示個人-1表示電腦 self.stats = 0
所以下棋本質上就是修改這個變量。
首先,我們是用鼠標點擊的方式來實現下棋的,所以應當修改事件響應部分:
for event in pygame.event.get(): # 退出 if event.type == pygame.QUIT: sys.exit() # 點擊鼠標 elif event.type == pygame.MOUSEBUTTONDOWN: # 獲得鼠標點擊的位置 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模塊主要是負責遊戲中的事件。
第一個事件表示點擊界面的右上角關閉鍵,退出程序;
第二個事件是鼠標點擊,可以使用pygame.mouse.get_pos得到點擊位置。
因為之前的格子(Lattice類)中有一個rect類的實例,我們可以使用collidepoint函數,傳入坐標判斷是在哪個格子中。
隨後我們需要判斷格子有沒有被占用,沒被占用,那麼我們就可以修改stats。
2.2 電腦
對於電腦來說,實際情況差不多,不過我們選擇瞭隨機生成的方式:
def computer(): """電腦的回合,隨機生成一個位置""" global judge random_num = [i for i in range(len(rect)) if not rect[i].stats] # 沒位子下瞭,平局 if not random_num: judge = 1 print("draw") exit() rect[random.choice(random_num)].stats = 1 return #result = Button("your choice")
我們先給出瞭所有沒有被占用的格子,使用列表解析形成列表。
如果列表為空,沒位子下瞭,就說明平局(在每一次落子之後,都會有輸贏的判斷,後面再說);
反之,我們就用random.choice函數,在列表中選擇一個元素(這個元素為Lattice類的實例),將其stats修改為1。
judge這個,是判斷是否結束遊戲的標志,初始為0。
三、輸贏判斷
這個可能會麻煩一點。
這裡,我的想法是每一個格子都有一個下標,將所有可能贏的格子組合的下標都寫出來。
win_list = [ # 行 [0, 1, 2], [3, 4, 5], [6, 7, 8], # 列 [0, 3, 6], [1, 4, 7], [2, 5, 8], # 對角 [0, 4, 8], [2, 4, 6] ]
隨後,我們同樣使用列表解析,將所有stats為1和-1的組成兩個列表:
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]
那麼問題來瞭,stats1、2中,可能隻有部分元素在win_list中,瞬間找到瞭被leecode支配的恐懼。
for i in win_list: # 取出每一個可能獲勝的條件 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()
我們的邏輯是對每一個獲勝可能組合,分別取出每一個元素,並在stats列表中查找,如果都能找到,列表解析式的結果就一定和原先的獲勝組合相同,此時我們就可以判斷一方獲勝。
四、一人一子
井字棋和五子棋的玩法差不多,所以必須做到在玩傢下子後,電腦能下子。
(正常電腦的反應,可是比玩傢快多瞭。
當然可以設置一個變量,0、1分別表示誰該下子瞭,但是我有更好的選擇——在玩傢下子後進行輸出。
if not i.stats and i.rect.collidepoint(mouse_x,mouse_y): # 玩傢下棋 i.stats = -1 win_or_lose() # 電腦下棋 computer() win_or_lose()
還有一個問題,就是不管哪方下子瞭,我們都需要對輸贏進行判斷。
五、顯示問題
當你完成瞭上述操作,會發現,其實屏幕上什麼都看不到。
因為我們還沒有顯示格子的圖標。
這裡我選擇使用經典的’x’、‘o’,用渲染文字的方式實現。(這部分也可以自己找圖貼上去)
渲染文字的步驟:
- self.font = pygame.font.SysFont設置字體
- self.font.render函數,生成一個含有文本信息的圖像
- 將圖像使用get_rect方法處理成矩形,進行對齊
- 使用blit方法渲染
lattice.py文件:
import pygame class Lattice(): def __init__(self,rect,screen): self.rect = rect self.screen = screen # 0表示初始,1表示個人-1表示電腦 self.stats = 0 # 文本顏色 self.text_color = (30, 30, 30) # 背景顏色,也就是我們screen渲染的顏色 self.bg_color = (255, 255, 255) # 設置字體 self.font = pygame.font.SysFont(None,48) def draw(self): # 按照狀態賦值文本信息 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函數:
傳入參數:文本信息,Boolean(控制曲線是否光滑,沒試過),文本顏色,背景顏色(也就是我們screen渲染的顏色)
返回一個圖片類型。
get_rect()方法:
將圖片處理成矩形,pygame有一點很好,就是不管什麼樣的圖形都能當成矩形處理
rect對象,有centerx、centery、x、y等一系列屬性,方便我們進行對齊操作,在這裡不展開說瞭。
blit方法:
輸入圖片和矩形(這裡的矩形實質上是給方法指明顯示的坐標),
在screen上顯示。
在主模塊中:
def update(): for i in rect: i.draw() # 將界面顯示 pygame.display.flip()
如果隻是在while循環的開始寫一個update,會發現實際上我們是不能及時看到結果的,這樣很明顯有影響,所以在每一次落子之後,我們都會進行一次刷新,然後再判斷輸贏。
if not i.stats and i.rect.collidepoint(mouse_x,mouse_y): # 玩傢下棋 i.stats = -1 update() win_or_lose() # 電腦下棋 computer() update() win_or_lose()
六、結語
這樣,我們這個井字棋基本上就可以玩瞭,但是我們還是需要進行一些修改。
下一篇博客,我將對細節進行整改。
下一篇:pygame實現井字棋——3.邏輯優化
上一篇:pygame實現井字棋——1.繪制九宮格
到此這篇關於pygame實現井字棋之第二步邏輯實現的文章就介紹到這瞭,更多相關pygame井字棋遊戲內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- pygame實現井字棋之第三步邏輯優化
- pygame實現井字棋之第一步繪制九宮格
- python實戰之利用pygame實現貪吃蛇遊戲(二)
- Python實現敲擊木魚積累功德小項目
- python實現跨年表白神器–你值得擁有