溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python單機五子棋的代碼怎么寫

發布時間:2021-10-22 13:46:50 來源:億速云 閱讀:427 作者:柒染 欄目:開發技術
# Python單機五子棋的代碼怎么寫

本文將詳細介紹如何使用Python開發一個單機版五子棋游戲,包含完整代碼實現和分步解析。這個項目適合Python初學者學習基礎語法和游戲開發邏輯。

## 一、項目概述

五子棋是一種經典的策略型棋類游戲,玩家通過在棋盤上交替落子,先形成五子連線的一方獲勝。我們將使用Python的Pygame庫來實現圖形界面,并采用簡單的算法實現人機對戰。

### 主要功能模塊
1. 圖形界面繪制
2. 玩家落子處理
3. 簡單實現
4. 勝負判斷
5. 游戲狀態管理

## 二、開發環境準備

首先需要安裝必要的庫:

```bash
pip install pygame numpy
  • Pygame:用于圖形界面和事件處理
  • Numpy:簡化二維數組操作(可選)

三、完整代碼實現

以下是完整的五子棋游戲代碼(約200行):

import pygame
import sys
import numpy as np
from pygame.locals import *

# 初始化常量
BOARD_SIZE = 15  # 15x15的棋盤
GRID_SIZE = 40   # 每個格子的像素大小
MARGIN = 40      # 棋盤邊距
PIECE_RADIUS = 18  # 棋子半徑
WINDOW_SIZE = BOARD_SIZE * GRID_SIZE + 2 * MARGIN
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BOARD_COLOR = (220, 179, 92)
RED = (255, 0, 0)
BLUE = (0, 0, 255)

# 初始化游戲
def init_game():
    pygame.init()
    screen = pygame.display.set_mode((WINDOW_SIZE, WINDOW_SIZE))
    pygame.display.set_caption('五子棋')
    return screen

# 繪制棋盤
def draw_board(screen):
    screen.fill(BOARD_COLOR)
    # 繪制網格線
    for i in range(BOARD_SIZE):
        # 橫線
        pygame.draw.line(screen, BLACK, 
                        (MARGIN, MARGIN + i * GRID_SIZE), 
                        (WINDOW_SIZE - MARGIN, MARGIN + i * GRID_SIZE), 2)
        # 豎線
        pygame.draw.line(screen, BLACK, 
                        (MARGIN + i * GRID_SIZE, MARGIN), 
                        (MARGIN + i * GRID_SIZE, WINDOW_SIZE - MARGIN), 2)
    # 繪制五個小黑點(天元等)
    dots = [(3, 3), (11, 3), (3, 11), (11, 11), (7, 7)]
    for dot in dots:
        pygame.draw.circle(screen, BLACK, 
                          (MARGIN + dot[0] * GRID_SIZE, MARGIN + dot[1] * GRID_SIZE), 5)

# 游戲主類
class GomokuGame:
    def __init__(self):
        self.board = np.zeros((BOARD_SIZE, BOARD_SIZE), dtype=int)  # 0空 1黑 2白
        self.current_player = 1  # 黑棋先行
        self.game_over = False
        self.winner = None
    
    # 落子
    def place_piece(self, row, col):
        if self.game_over or self.board[row][col] != 0:
            return False
        
        self.board[row][col] = self.current_player
        if self.check_win(row, col):
            self.game_over = True
            self.winner = self.current_player
        else:
            self.current_player = 3 - self.current_player  # 切換玩家
        return True
    
    # 檢查是否獲勝
    def check_win(self, row, col):
        directions = [(1, 0), (0, 1), (1, 1), (1, -1)]  # 橫豎斜四個方向
        for dr, dc in directions:
            count = 1  # 當前落子
            # 正向檢查
            r, c = row + dr, col + dc
            while 0 <= r < BOARD_SIZE and 0 <= c < BOARD_SIZE and self.board[r][c] == self.current_player:
                count += 1
                r += dr
                c += dc
            # 反向檢查
            r, c = row - dr, col - dc
            while 0 <= r < BOARD_SIZE and 0 <= c < BOARD_SIZE and self.board[r][c] == self.current_player:
                count += 1
                r -= dr
                c -= dc
            if count >= 5:
                return True
        return False
    
    # 簡單落子
    def ai_move(self):
        if self.game_over:
            return
        
        # 優先防守:檢查玩家是否有四連
        for i in range(BOARD_SIZE):
            for j in range(BOARD_SIZE):
                if self.board[i][j] == 0:
                    self.board[i][j] = 1  # 假設玩家落子
                    if self.check_win(i, j):
                        self.board[i][j] = 2  # 攔截
                        if self.check_win(i, j):
                            self.game_over = True
                            self.winner = 2
                        self.current_player = 1
                        return (i, j)
                    self.board[i][j] = 0
        
        # 隨機落子
        empty_positions = [(i, j) for i in range(BOARD_SIZE) for j in range(BOARD_SIZE) if self.board[i][j] == 0]
        if empty_positions:
            return empty_positions[np.random.randint(len(empty_positions))]
        return None

# 繪制棋子
def draw_pieces(screen, game):
    for i in range(BOARD_SIZE):
        for j in range(BOARD_SIZE):
            if game.board[i][j] == 1:  # 黑棋
                pygame.draw.circle(screen, BLACK, 
                                 (MARGIN + j * GRID_SIZE, MARGIN + i * GRID_SIZE), 
                                 PIECE_RADIUS)
            elif game.board[i][j] == 2:  # 白棋
                pygame.draw.circle(screen, WHITE, 
                                 (MARGIN + j * GRID_SIZE, MARGIN + i * GRID_SIZE), 
                                 PIECE_RADIUS)
                pygame.draw.circle(screen, BLACK, 
                                 (MARGIN + j * GRID_SIZE, MARGIN + i * GRID_SIZE), 
                                 PIECE_RADIUS, 1)

# 顯示游戲結果
def show_result(screen, winner):
    font = pygame.font.Font(None, 72)
    if winner == 1:
        text = font.render("黑棋獲勝!", True, RED)
    else:
        text = font.render("白棋獲勝!", True, BLUE)
    text_rect = text.get_rect(center=(WINDOW_SIZE//2, WINDOW_SIZE//2))
    screen.blit(text, text_rect)

# 主函數
def main():
    screen = init_game()
    game = GomokuGame()
    
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            
            if event.type == MOUSEBUTTONDOWN and not game.game_over:
                if game.current_player == 1:  # 玩家回合
                    x, y = pygame.mouse.get_pos()
                    col = round((x - MARGIN) / GRID_SIZE)
                    row = round((y - MARGIN) / GRID_SIZE)
                    if 0 <= row < BOARD_SIZE and 0 <= col < BOARD_SIZE:
                        if game.place_piece(row, col):
                            # 回合
                            ai_pos = game.ai_move()
                            if ai_pos:
                                game.place_piece(*ai_pos)
        
        draw_board(screen)
        draw_pieces(screen, game)
        if game.game_over:
            show_result(screen, game.winner)
        pygame.display.update()

if __name__ == "__main__":
    main()

四、代碼分步解析

1. 初始化設置

BOARD_SIZE = 15  # 標準五子棋棋盤大小
GRID_SIZE = 40   # 每個格子的像素尺寸
MARGIN = 40      # 棋盤邊緣留白

這些常量定義了棋盤的基本參數,可以根據需要調整。標準五子棋使用15×15的棋盤,我們設置每個格子40像素寬,邊緣留白40像素。

2. 游戲狀態管理

GomokuGame類負責維護游戲狀態:

  • board: 15×15的二維數組,記錄每個位置的棋子狀態
  • current_player: 當前回合玩家(1為黑棋,2為白棋)
  • game_over: 游戲是否結束標志
  • winner: 獲勝方

3. 勝負判斷算法

check_win方法實現了五子棋的核心勝負判斷邏輯:

def check_win(self, row, col):
    directions = [(1, 0), (0, 1), (1, 1), (1, -1)]  # 橫豎斜四個方向
    for dr, dc in directions:
        count = 1  # 當前落子
        # 正向檢查
        r, c = row + dr, col + dc
        while 0 <= r < BOARD_SIZE and 0 <= c < BOARD_SIZE and self.board[r][c] == self.current_player:
            count += 1
            r += dr
            c += dc
        # 反向檢查
        r, c = row - dr, col - dc
        while 0 <= r < BOARD_SIZE and 0 <= c < BOARD_SIZE and self.board[r][c] == self.current_player:
            count += 1
            r -= dr
            c -= dc
        if count >= 5:
            return True
    return False

該方法從當前落子位置向四個方向(水平、垂直、兩個對角線)檢查是否有五個或更多同色棋子連續排列。

4. 簡單實現

我們的實現了基本防守邏輯:

def ai_move(self):
    # 優先攔截玩家即將獲勝的位置
    for i in range(BOARD_SIZE):
        for j in range(BOARD_SIZE):
            if self.board[i][j] == 0:
                self.board[i][j] = 1  # 假設玩家落子
                if self.check_win(i, j):
                    self.board[i][j] = 2  # 攔截
                    return (i, j)
                self.board[i][j] = 0
    
    # 沒有危險則隨機落子
    empty_positions = [(i, j) for i in range(BOARD_SIZE) for j in range(BOARD_SIZE) if self.board[i][j] == 0]
    if empty_positions:
        return empty_positions[np.random.randint(len(empty_positions))]

這個會: 1. 首先檢查玩家是否有四連需要攔截 2. 如果沒有威脅,則隨機選擇空位落子

5. 圖形界面渲染

使用Pygame繪制棋盤和棋子:

def draw_board(screen):
    # 繪制棋盤網格
    for i in range(BOARD_SIZE):
        pygame.draw.line(screen, BLACK, 
                       (MARGIN, MARGIN + i * GRID_SIZE), 
                       (WINDOW_SIZE - MARGIN, MARGIN + i * GRID_SIZE), 2)
        pygame.draw.line(screen, BLACK, 
                       (MARGIN + i * GRID_SIZE, MARGIN), 
                       (MARGIN + i * GRID_SIZE, WINDOW_SIZE - MARGIN), 2)

def draw_pieces(screen, game):
    for i in range(BOARD_SIZE):
        for j in range(BOARD_SIZE):
            if game.board[i][j] == 1:  # 黑棋
                pygame.draw.circle(screen, BLACK, 
                                 (MARGIN + j * GRID_SIZE, MARGIN + i * GRID_SIZE), 
                                 PIECE_RADIUS)

五、功能擴展建議

這個基礎版本可以進一步擴展:

  1. 增強:實現評分函數、Minimax算法或Alpha-Beta剪枝
  2. 游戲設置:添加選擇先手、調整棋盤大小等功能
  3. 悔棋功能:記錄落子歷史,支持回退
  4. 網絡對戰:使用socket實現聯機對戰
  5. 音效和動畫:添加落子音效和動畫效果

六、總結

通過這個約200行的Python項目,我們實現了一個完整的單機五子棋游戲,包含: - 圖形界面顯示 - 玩家交互 - 簡單對手 - 勝負判斷

這個項目涵蓋了Python基礎語法、面向對象編程、二維數組處理和基本游戲開發邏輯,是學習Python編程的絕佳實踐項目。讀者可以基于這個基礎版本繼續擴展更復雜的功能。

希望本文對你學習Python游戲開發有所幫助!完整代碼已在上文提供,可以直接運行體驗。 “`

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女