1. 程式人生 > 程式設計 >pygame實現五子棋遊戲

pygame實現五子棋遊戲

本文例項為大家分享了pygame五子棋遊戲的具體程式碼,供大家參考,具體內容如下

1.設定棋盤

五子棋標準棋盤是15x15的,如果我們每個格子的大小是40x40的話,棋盤應該是40x(15-1)=560的寬度,我們在四面各保留60的邊距,那麼視窗的長寬各是40x(15-1)+60x2

# -*- coding=utf-8 -*-
import random
import pygame
pygame.init()

space = 60 # 四周留下的邊距
cell_size = 40 # 每個格子大小
cell_num = 15
grid_size = cell_size * (cell_num - 1) + space * 2 # 棋盤的大小
screencaption = pygame.display.set_caption('FIR')
screen = pygame.display.set_mode((grid_size,grid_size)) #設定視窗長寬

while True:
 for event in pygame.event.get():
  if event.type == pygame.QUIT:
  pygame.quit()
  exit()

 screen.fill((0,150)) # 將介面設定為藍色

 for x in range(0,cell_size*cell_num,cell_size):
 pygame.draw.line(screen,(200,200,200),(x+space,0+space),cell_size*(cell_num-1)+space),1)
 for y in range(0,(0+space,y+space),(cell_size*(cell_num-1)+space,1)
 
 pygame.display.update() # 必須呼叫update才能看到繪圖顯示

2.落子

首先我們定義一個chess_arr陣列用於儲存落到棋盤上的棋子

chess_arr = []

然後在遊戲主迴圈監聽下滑鼠彈起事件,然後在捕捉到滑鼠彈起事件時獲取滑鼠位置並把位置新增進chess_arr

for event in pygame.event.get():
 ……
 
  if event.type == pygame.MOUSEBUTTONUP: # 滑鼠彈起
  x,y = pygame.mouse.get_pos() # 獲取滑鼠位置
  chess_arr.append((x,y))

最後我們在pygame.display.update()前將棋子繪製出來看看效果

可以看到,現在已經能點出棋子了,但是棋子的位置不是縱橫線的交叉點,所以我們必須對滑鼠位置進行取整,不能把x,y這個位置加的這麼隨意,處理下x,y位置的程式碼如下

for event in pygame.event.get():
 ……
  if event.type == pygame.MOUSEBUTTONUP: # 滑鼠彈起
  x,y = pygame.mouse.get_pos() # 獲取滑鼠位置
  xi = int(round((x - space)*1.0/cell_size)) # 獲取到x方向上取整的序號
  yi = int(round((y - space)*1.0/cell_size)) # 獲取到y方向上取整的序號
  if xi>=0 and xi<cell_num and yi>=0 and yi<cell_num:
   chess_arr.append((xi*cell_size+space,yi*cell_size+space))

現在發現落子位置靠譜多了

為了程式碼的可讀性更好點,以後一些棋盤計算更方便,我們把放入chess_arr陣列的絕對座標改成放入的是格子的序號,也就是把

chess_arr.append((xi*cell_size+space,yi*cell_size+space))

改成

chess_arr.append((xi,yi))

然後在畫棋子的地方也稍作修改,把

pygame.draw.circle(screen,(205,205,205),[x,y],16,16)

改成

pygame.draw.circle(screen,[x*cell_size+space,y*cell_size+space],16)

接下來還有個問題,因為進到chess_arr陣列前並沒有判斷某一位置是否已經有棋子,存在重複落子的情況,所以這邊還要多加個判斷,因為python語言夠強大,可以直接判斷是否包含tuple或者陣列,所以只要多加一個(xi,yi) not in chess_arr的判斷就好了,開不開森~

for event in pygame.event.get():
  ……
  if event.type == pygame.MOUSEBUTTONUP: # 滑鼠彈起
  ……
  if xi>=0 and xi<cell_num and yi>=0 and yi<cell_num and (xi,yi) not in chess_arr:
   chess_arr.append((xi,yi))

為免程式碼偏差,先更新下目前的完整程式碼

# -*- coding=utf-8 -*-
import random
import pygame
from pygame.locals import MOUSEBUTTONUP
pygame.init()

space = 60 # 四周留下的邊距
cell_size = 40 # 每個格子大小
cell_num = 15
grid_size = cell_size * (cell_num - 1) + space * 2 # 棋盤的大小
screencaption = pygame.display.set_caption('FIR')
screen = pygame.display.set_mode((grid_size,grid_size)) #設定視窗長寬

chess_arr = []

while True:
 for event in pygame.event.get():
  if event.type == pygame.QUIT:
  pygame.quit()
  exit()
 
  if event.type == pygame.MOUSEBUTTONUP: # 滑鼠彈起
  x,y = pygame.mouse.get_pos() # 獲取滑鼠位置
  xi = int(round((x - space)*1.0/cell_size)) # 獲取到x方向上取整的序號
  yi = int(round((y - space)*1.0/cell_size)) # 獲取到y方向上取整的序號
  if xi>=0 and xi<cell_num and yi>=0 and yi<cell_num and (xi,yi))

 screen.fill((0,1)

 for x,y in chess_arr:
 pygame.draw.circle(screen,16)

 pygame.display.update() # 必須呼叫update才能看到繪圖顯示

3.區分黑白子

這裡常規的想法可能有這麼兩種:1.chess_arr理論應該是黑白相間的,一個隔一個不同顏色畫就好了(這種在不考慮正規比賽五手兩打或者讓子的情況下是沒問題的) 2.往chess_arr裡填(x,y)時多填一個黑白標記改成(x,y,flag) ,這裡我們選擇第二種方案
首先,我們全域性定義個flag變數

flag = 1 # 1黑 2白

我們把

if xi>=0 and xi<cell_num and yi>=0 and yi<cell_num and (xi,yi))

這裡改成

if xi>=0 and xi<cell_num and yi>=0 and yi<cell_num and (xi,yi,1) not in chess_arr and (xi,2) not in chess_arr:
   chess_arr.append((xi,flag))
   flag = 2 if flag == 1 else 2

再把畫棋的

for x,16)

改成

for x,c in chess_arr:
 chess_color = (30,30,30) if c == 1 else (225,225,225)
 pygame.draw.circle(screen,chess_color,16)

現在看起來有點像那麼回事了

4.判斷輸贏

判斷輸贏的關鍵當然還是使用chess_arr這個陣列,這個陣列用來判斷勝利並不太方便,我們把它轉一個15*15的二維陣列來計算,轉換程式碼如下

m = [[0]*15 for i in range(15)] # 先定義一個15*15的全0陣列
for x,c in chess_arr:
 m[y][x] = 1 # 上面有棋則標1

我們把這程式碼一起放到一個check_win(chess_arr,flag)函式裡,用於判斷某一方是否勝利,基本流程是分別判斷最後一顆落下的子的橫線、豎線、斜線上是不是有5個以上子,有則返回True,函式程式碼如下:

def get_one_dire_num(lx,ly,dx,dy,m):
 tx = lx
 ty = ly
 s = 0
 while True:
 tx += dx
 ty += dy
 if tx < 0 or tx >= cell_num or ty < 0 or ty >= cell_num or m[ty][tx] == 0: return s
 s+=1

def check_win(chess_arr,flag):
 m = [[0]*cell_num for i in range(cell_num)] # 先定義一個15*15的全0的陣列,不能用[[0]*cell_num]*cell_num的方式去定義因為一位陣列會被重複引用
 for x,c in chess_arr:
 if c == flag:
  m[y][x] = 1 # 上面有棋則標1
 lx = chess_arr[-1][0] # 最後一個子的x
 ly = chess_arr[-1][1] # 最後一個子的y
 dire_arr = [[(-1,0),(1,0)],[(0,-1),(0,1)],[(-1,1),-1)]] # 4個方向陣列,往左+往右、往上+往下、往左上+往右下、往左下+往右上,4組判斷方向
 
 for dire1,dire2 in dire_arr:
 dx,dy = dire1
 num1 = get_one_dire_num(lx,m)
 dx,dy = dire2
 num2 = get_one_dire_num(lx,m)
 if num1 + num2 + 1 >= 5: return True

 return False

判斷函式完成了,我們再定一個全域性變數用於儲存遊戲狀態

game_state = 1 # 遊戲狀態1.表示正常進行 2.表示黑勝 3.表示白勝

我們在滑鼠新增棋子的程式碼後面做下修改,呼叫判斷勝利的函式

if check_win(chess_arr,flag):
  game_state = 2 if flag == 1 else 3
  else:
  flag = 2 if flag == 1 else 1

最後在pygame.display.update()前加個遊戲狀態判斷,用於顯示獲勝文字

if game_state != 1:
 myfont = pygame.font.Font(None,60)
 white = 210,210,0
 win_text = "%s win"%('black' if game_state == 2 else 'white')
 textImage = myfont.render(win_text,True,white)
 screen.blit(textImage,(260,320))

另外,滑鼠事件判斷處也要做下修改,判斷下游戲狀態是不是遊戲中

if game_state == 1 and event.type == pygame.MOUSEBUTTONUP: # 滑鼠彈起

至此主要的程式碼都完整了,下面是效果圖

最後貼下完整程式,這邊沒有做禁手的判斷和判輸,後面有時間再處理

# -*- coding=utf-8 -*-
import random
import pygame
from pygame.locals import MOUSEBUTTONUP
pygame.init()

space = 60 # 四周留下的邊距
cell_size = 40 # 每個格子大小
cell_num = 15
grid_size = cell_size * (cell_num - 1) + space * 2 # 棋盤的大小
screencaption = pygame.display.set_caption('FIR')
screen = pygame.display.set_mode((grid_size,grid_size)) #設定視窗長寬

chess_arr = []
flag = 1 # 1黑 2白
game_state = 1 # 遊戲狀態1.表示正常進行 2.表示黑勝 3.表示白勝

def get_one_dire_num(lx,m)
 if num1 + num2 + 1 >= 5: return True

 return False

while True:
 for event in pygame.event.get():
  if event.type == pygame.QUIT:
  pygame.quit()
  exit()
 
  if game_state == 1 and event.type == pygame.MOUSEBUTTONUP: # 滑鼠彈起
  x,flag))
   if check_win(chess_arr,flag):
   game_state = 2 if flag == 1 else 3
   else:
   flag = 2 if flag == 1 else 1

 screen.fill((0,16)

 if game_state != 1:
 myfont = pygame.font.Font(None,320))
 
 pygame.display.update() # 必須呼叫update才能看到繪圖顯示

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。