只要週末有空閒時間,我就喜歡寫一些小而愚蠢的東西。其中一個想法變成了一款命令列國際象棋遊戲,您可以在其中與 OpenAI 對抗。我將其命名為“SkakiBot”,靈感來自“Skaki”,希臘語中的國際象棋單字。
優秀的 python-chess 函式庫負責所有的西洋棋機制。我們的目標不是從頭開始建立一個國際象棋引擎,而是展示 OpenAI 如何輕鬆地整合到這樣的專案中。
讓我們深入研究程式碼,看看它們是如何組合在一起的!
我們將首先設定一個基本的遊戲循環,該循環接受使用者輸入並為國際象棋邏輯奠定基礎。
def main(): while True: user_input = input("Enter your next move: ").strip() if user_input.lower() == 'exit': print("Thanks for playing SkakiBot. Goodbye!") break if not user_input: print("Move cannot be empty. Please try again.") continue print(f"You entered: {user_input}")
此時,程式碼沒有做太多事情。它只是提示用戶輸入、驗證並列印它:
Enter your next move: e2e4 You entered: e2e4 Enter your next move: exit Thanks for playing SkakiBot. Goodbye!
接下來,我們引入 python-chess,它將處理棋盤管理、移動驗證和遊戲結束場景。
pip install chess
安裝庫後,我們可以初始化棋盤並在提示使用者輸入之前列印它:
import chess def main(): board = chess.Board() while not board.is_game_over(): print(board) user_input = input("Enter your next move (e.g., e2e4): ").strip() if user_input.lower() == 'exit': print("Thanks for playing SkakiBot. Goodbye!") break
為了使遊戲正常運行,我們需要驗證使用者輸入並向棋盤應用合法的移動。 UCI(通用國際象棋介面)格式用於移動,您可以在其中指定起始和結束方格(例如,e2e4)。
def main(): board = chess.Board() while not board.is_game_over(): # ... try: move = chess.Move.from_uci(user_input) if move in board.legal_moves: board.push(move) print(f"Move '{user_input}' played.") else: print("Invalid move. Please enter a valid move.") except ValueError: print("Invalid move format. Use UCI format like 'e2e4'.")
我們現在可以處理遊戲結束的場景,例如將死或僵局:
def main(): board = chess.Board() while not board.is_game_over(): # ... if board.is_checkmate(): print("Checkmate! The game is over.") elif board.is_stalemate(): print("Stalemate! The game is a draw.") elif board.is_insufficient_material(): print("Draw due to insufficient material.") elif board.is_seventyfive_moves(): print("Draw due to the seventy-five-move rule.") else: print("Game ended.")
在這個階段,你為雙方效力。您可以透過嘗試 Fool's Mate 來測試它,並按照 UCI 格式執行以下動作:
這會導致快速將死。
現在是時候讓人工智慧接管一邊了。 OpenAI 將評估董事會的狀態並提出最佳措施。
我們先從環境中取得 OpenAI API 金鑰:
# config.py import os def get_openai_key() -> str: key = os.getenv("OPENAI_API_KEY") if not key: raise EnvironmentError("OpenAI API key is not set. Please set 'OPENAI_API_KEY' in the environment.") return key
接下來,我們寫一個函數來將棋盤狀態(以 Forsyth-Edwards Notation (FEN) 格式)發送到 OpenAI 並檢索建議的走法:
def get_openai_move(board): import openai openai.api_key = get_openai_key() board_fen = board.fen() response = openai.ChatCompletion.create( model="gpt-3.5-turbo", messages=[ {"role": "system", "content": ( "You are an expert chess player and assistant. Your task is to " "analyse chess positions and suggest the best move in UCI format." )}, {"role": "user", "content": ( "The current chess board is given in FEN notation:\n" f"{board_fen}\n\n" "Analyse the position and suggest the best possible move. Respond " "with a single UCI move, such as 'e2e4'. Do not provide any explanations." )} ]) suggested_move = response.choices[0].message.content.strip() return suggested_move
提示很簡單,但它可以很好地產生有效的動作。它為 OpenAI 提供了足夠的上下文來了解董事會狀態並以 UCI 格式的合法舉措進行回應。
棋盤狀態以 FEN 格式發送,它提供了遊戲的完整快照,包括棋子位置、輪到誰、易位權和其他詳細資訊。這是理想的,因為 OpenAI 的 API 是無狀態的,並且不會保留請求之間的信息,因此每個請求必須包含所有必要的上下文。
目前,為了簡單起見,該模型被硬編碼為 gpt-3.5-turbo,但最好從環境中取得它,就像我們對 API 金鑰所做的那樣。這將使以後更容易更新或使用不同的模型進行測試。
最後,我們可以將人工智慧整合到主遊戲循環中。 AI 在每個用戶移動後評估棋盤並播放其回應。
def main(): while True: user_input = input("Enter your next move: ").strip() if user_input.lower() == 'exit': print("Thanks for playing SkakiBot. Goodbye!") break if not user_input: print("Move cannot be empty. Please try again.") continue print(f"You entered: {user_input}")
就是這樣!現在您已經有了一個功能齊全的國際象棋遊戲,您可以在其中與 OpenAI 對抗。程式碼還有很大的改進空間,但它已經可以玩了。有趣的下一步是讓兩個人工智慧相互對抗,讓他們一決勝負。
程式碼可在 GitHub 上取得。祝實驗愉快!
以上是使用 Python 和 OpenAI 建立國際象棋遊戲的詳細內容。更多資訊請關注PHP中文網其他相關文章!