- Python AI游戲編程入門:基于Pygame和PyTorch
- 肖凱
- 1166字
- 2024-10-25 14:10:49
2.2 編寫第一個小游戲
本書以游戲為編程主題,下面就讓我們嘗試編寫一個井字棋游戲來熱身。編寫該游戲一方面是為了復習我們以前學過的Python知識,另一方面也可以讓我們更熟悉VS Code。
井字棋游戲很簡單,它的棋盤是一個3×3的網格,玩家率先實現3顆棋子在一條直線上即可勝利。本游戲程序包含的核心數據就是棋盤信息,另外還需要若干函數來承載游戲功能,例如顯示棋盤信息的函數、處理玩家輸入的函數,以及判斷棋局勝負的函數等。所有代碼都在一個代碼文件中。
首先定義幾個變量,包括棋盤大小變量boardSize和棋盤信息變量board。我們會使用兩種符號分別表示兩個玩家的落子,其中一個玩家的落子使用字母符號“X”來表示,而另一個玩家的落子使用字母符號“O”來表示,當棋盤上還沒有玩家落子時,所有位置都以符號“.”來表示。先手玩家使用字母符號“X”來落子,將落子信息保存在變量currentPlayer中。隨后輸出一些游戲提示信息。
boardSize = 3
board = ['.'] * boardSize * boardSize
currentPlayer = 'X'
print("井字棋游戲開始")
print("規則:三子連成直線即勝利")
print("X先手,O后手")
隨后我們定義print_board函數,它負責在終端上顯示棋盤信息。
def print_board(board):
print("\n")
print("%s|%s|%s"%(board[0],board[1],board[2]))
print("-+-+-")
print("%s|%s|%s"%(board[3],board[4],board[5]))
print("-+-+-")
print("%s|%s|%s"%(board[6],board[7],board[8]))
我們還需要一個函數來負責判斷勝負。函數hasWon看起來很復雜,但其內在邏輯很簡單,就是列舉各種可能獲勝的棋局狀態,只要滿足這種狀態就返回True。如果覺得某個地方不容易理解,可以通過VS Code設置斷點,并按鍵盤上的F5鍵進入調試模式,在調試模式下可以一步步地運行代碼,以觀察每個變量的值并理解代碼的運行邏輯。
def hasWon(currentBoard,player):
winningSet=[player in range(boardSize)]
row1=currentBoard[:3]
row2=currentBoard[3:6]
row3=currentBoard[6:]
if winningSet in [row1,row2,row3]:
return True
col1=[currentBoard[0],currentBoard[3],currentBoard[6]]
col2=[currentBoard[1],currentBoard[4],currentBoard[7]]
col3=[currentBoard[2],currentBoard[5],currentBoard[8]]
if winningSet in[col1,col2,col3]:
return True
diag1=[currentBoard[0],currentBoard[4],currentBoard[8]]
diag2=[currentBoard[6],currentBoard[4],currentBoard[2]]
if winningSet in [diag1,diag2]:
return True
return False
因為兩個玩家交替落子,所以需要定義getNextPlayer函數以交換當前玩家。
def getNextPlayer(currentPlayer):
if currentPlayer == 'X':
return 'O'
return 'X'
getPlayerMove函數用來處理玩家的輸入。玩家輸入的是坐標的形式,每次需要輸入兩個數字,數字之間以英文逗號間隔,數字取值為0~2。“X,Y”表示落子位置在棋盤上的第X行、第Y列。需要注意的是,該函數獲取玩家輸入后,會將這些輸入信息通過字符串操作拆分成兩部分,再轉換成整數類型保存為坐標,最后將二維的坐標信息轉換成一維的索引。判斷當前棋盤的落子位置為空白位置時,就用當前玩家的表示落子的字母符號進行賦值。
def getPlayerMove(board,currentPlayer):
isMoveValid = False
while isMoveValid == False:
print('')
userMove = input(f'玩家{currentPlayer}輸入棋盤坐標(坐標取值0,1,2): X,Y? ')
userX, userY = [int(char) for char in userMove.split(',')]
userIndex = userX * boardSize + userY
if board[userIndex] == '.':
isMoveValid = True
board[userIndex] = currentPlayer
return board
當棋盤上擺滿棋子時,需要結束游戲,因此要定義一個hasMovesLeft函數來判斷還有沒有空白位置供玩家落子。
def hasMovesLeft(board):
return '.' in board
最后將這些函數組裝在一起。
if __name__ == '__main__':
print_board(board)
while hasMovesLeft(board):
board = getPlayerMove(board,currentPlayer)
print_board(board)
if hasWon(board, currentPlayer):
print('Player'+currentPlayer+'haswon!')
break
currentPlayer = getNextPlayer(currentPlayer)
首先顯示棋盤,只要棋盤上還有空白位置可以下棋,就保持運行游戲主循環中的代碼。代碼先處理玩家輸入,顯示新的棋盤;如果出現勝負結果,就顯示相關信息。否則輪換玩家。游戲畫面如圖2-3所示。

圖2-3
這個游戲是不是很簡單。讀者可以先試著玩一下。如果不能很好地理解這些代碼,可以進入調試模式慢慢理解每行代碼完成的任務。如果你對某些語法不熟悉,可以先復習、鞏固對應的知識。
- 玩轉Scratch少兒趣味編程
- JavaScript 網頁編程從入門到精通 (清華社"視頻大講堂"大系·網絡開發視頻大講堂)
- GameMaker Programming By Example
- Access 2016數據庫管
- 概率成形編碼調制技術理論及應用
- 打開Go語言之門:入門、實戰與進階
- Learning Material Design
- 工業機器人離線編程
- 零基礎學HTML+CSS
- Drupal Search Engine Optimization
- VMware vSphere Design Essentials
- Spring Boot 2+Thymeleaf企業應用實戰
- jBPM6 Developer Guide
- Real-time Web Application Development using Vert.x 2.0
- HTML5+CSS3網頁布局項目化教程