用Python和Pygame构建具有初级决策能力的五子棋AI

五子棋作为一款历史悠久的策略游戏,其简单的规则背后隐藏着复杂的博弈思维。当我们需要为这款游戏开发一个AI对手时,面临的第一个挑战就是:如何让计算机理解棋盘局势并做出合理决策?本文将展示如何用Python和Pygame构建一个基于规则库的轻量级五子棋AI,这种实现方式既保留了算法的可解释性,又能提供不错的游戏体验。

1. 五子棋AI的核心设计思路

传统棋类AI通常采用博弈树搜索算法,但对于初学者而言,这些算法实现复杂度较高。我们采用一种更直观的方法——基于模式匹配的规则库系统,这种设计有三大优势:

  1. 执行效率高:不需要复杂的计算
  2. 可解释性强:每一步决策都有明确的规则依据
  3. 易于扩展:可以逐步添加更复杂的规则

关键数据结构:我们使用一个三维列表来存储各种棋型模式:

patterns = [
    # 进攻模式
    [[1,1,1,1,3], "四连进攻"],  
    [[1,1,3,1,1], "跳四进攻"],
    # 防守模式
    [[2,2,2,3,0], "三连防守"],
    [[0,3,2,2,2], "另一端防守"]
]

每个模式包含两部分:棋型定义和策略描述。数字代表棋子状态(1=黑棋,2=白棋,3=落子点,0=空位)。

2. 游戏基础框架搭建

2.1 棋盘与棋子渲染

使用Pygame创建游戏窗口和绘制棋盘:

import pygame
import numpy as np

def init_game():
    pygame.init()
    screen = pygame.display.set_mode((600, 650))
    pygame.display.set_caption('五子棋AI对战')
    
    # 棋盘背景
    board = pygame.Surface((570, 570))
    board.fill((220, 179, 92))
    
    # 绘制网格线
    for i in range(15):
        pygame.draw.line(board, (0,0,0), (30, 30+i*38), (570-30, 30+i*38), 2)
        pygame.draw.line(board, (0,0,0), (30+i*38, 30), (30+i*38, 570-30), 2)
    
    return screen, board

棋子渲染采用渐变效果增强视觉体验:

def draw_stone(surface, x, y, color):
    """绘制具有立体感的棋子"""
    if color == 'black':
        colors = [(50,50,50), (30,30,30), (10,10,10)]
    else:
        colors = [(220,220,220), (200,200,200), (180,180,180)]
    
    for i, col in enumerate(colors):
        pygame.draw.circle(
            surface, col,
            (x, y), 15 - i*3
        )

2.2 游戏状态管理

使用NumPy数组存储棋盘状态:

class GameState:
    def __init__(self):
        self.board = np.zeros((15, 15))  # 0=空, 1=黑, 2=白
        self.current_player = 1  # 黑方先行
        self.game_over = False
    
    def make_move(self, row, col):
        if self.board[row][col] == 0 and not self.game_over:
            self.board[row][col] = self.current_player
            if self.check_win(row, col):
                self.game_over = True
            else:
                self.current_player = 3 - self.current_player  # 切换玩家
            return True
        return False

3. 模式匹配引擎实现

3.1 多方向扫描算法

AI需要检查四个主要方向的棋型:

  1. 水平方向
  2. 垂直方向
  3. 主对角线
  4. 副对角线
def scan_board(board, patterns):
    """扫描棋盘寻找最佳落子点"""
    best_score = -1
    best_move = None
    
    for i in range(15):
        for j in range(15):
            if board[i][j] != 0:
                continue
                
            # 检查四个方向
            directions = [(0,1), (1,0), (1,1), (1,-1)]
            for dx, dy in directions:
                line = get_line(board, i, j, dx, dy)
                score = evaluate_line(line, patterns)
                
                if score > best_score:
                    best_score = score
                    best_move = (i, j)
    
    return best_move if best_move else random_move(board)

def get_line(board, x, y, dx, dy):
    """获取指定方向的连续9个位置状态"""
    line = []
    for i in range(-4, 5):
        nx, ny = x + i*dx, y + i*dy
        if 0 <= nx < 15 and 0 <= ny < 15:
            line.append(board[nx][ny])
        else:
            line.append(-1)  # 边界外
    return line

3.2 棋型评估系统

为不同棋型分配权重值:

棋型模式 权重 说明
五连 10000 直接获胜
活四 5000 下一步可成五连
冲四 1000 单端被堵的四连
活三 500 可发展为活四
活二 100 潜在的发展路线

评估函数实现:

def evaluate_line(line, patterns):
    """评估一行棋型的价值"""
    max_score = 0
    
    # 检查所有预定义模式
    for pattern, score in patterns:
        for i in range(len(line) - len(pattern) + 1):
            match = True
            for j in range(len(pattern)):
                if pattern[j] != 3 and line[i+j] != pattern[j]:
                    match = False
                    break
            if match:
                max_score = max(max_score, score)
    
    return max_score

4. AI策略优化技巧

4.1 多级优先级系统

为了提高AI的智能程度,我们实现一个三级决策系统:

  1. 获胜检查:优先完成五连
  2. 防守必要点:阻止对手即将获胜
  3. 模式匹配进攻:根据棋型库选择最佳进攻点
def ai_decision(game_state):
    # 第一优先级:检查AI是否能直接获胜
    winning_move = find_winning_move(game_state.board, 2)
    if winning_move:
        return winning_move
    
    # 第二优先级:阻止玩家获胜
    block_move = find_winning_move(game_state.board, 1)
    if block_move:
        return block_move
    
    # 第三优先级:模式匹配决策
    strategic_move = scan_board(game_state.board, PATTERNS)
    return strategic_move

4.2 开局库与特殊棋型

为AI添加常见开局模式:

OPENING_BOOK = {
    "花月开局": [
        (7,7), (7,8), (8,7), (6,8)
    ],
    "云雨开局": [
        (7,7), (6,6), (8,8), (5,5)
    ]
}

def check_opening(board):
    """检查是否符合已知开局"""
    move_count = np.count_nonzero(board)
    if move_count < 4:
        for name, moves in OPENING_BOOK.items():
            match = True
            for i in range(move_count):
                if board[moves[i][0]][moves[i][1]] != (1 if i%2==0 else 2):
                    match = False
                    break
            if match:
                return moves[move_count]
    return None

5. 完整游戏循环实现

整合所有组件创建完整游戏体验:

def main():
    screen, board = init_game()
    game_state = GameState()
    clock = pygame.time.Clock()
    
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                return
                
            if event.type == pygame.MOUSEBUTTONDOWN and game_state.current_player == 1:
                x, y = pygame.mouse.get_pos()
                col = round((x - 35) / 38)
                row = round((y - 35) / 38)
                if 0 <= row < 15 and 0 <= col < 15:
                    game_state.make_move(row, col)
        
        # AI回合
        if not game_state.game_over and game_state.current_player == 2:
            move = ai_decision(game_state)
            if move:
                game_state.make_move(*move)
            pygame.time.delay(500)  # 增加AI思考时间
        
        # 渲染
        screen.fill((240, 240, 240))
        screen.blit(board, (15, 15))
        
        # 绘制棋子
        for i in range(15):
            for j in range(15):
                if game_state.board[i][j] == 1:
                    draw_stone(screen, 35+j*38, 35+i*38, 'black')
                elif game_state.board[i][j] == 2:
                    draw_stone(screen, 35+j*38, 35+i*38, 'white')
        
        pygame.display.flip()
        clock.tick(30)

if __name__ == "__main__":
    main()

6. 性能优化与扩展思路

6.1 优化模式匹配效率

使用位运算加速模式匹配:

def pattern_to_bits(pattern):
    """将棋型模式转换为位掩码"""
    bits = 0
    for i, val in enumerate(pattern):
        bits |= val << (i*2)
    return bits

# 预计算所有模式的位表示
PATTERN_BITS = {pattern_to_bits(p): score for p, score in PATTERNS}

def evaluate_line_fast(line):
    """使用位运算的快速评估"""
    max_score = 0
    for i in range(len(line)-4):
        window = line[i:i+5]
        bits = pattern_to_bits(window)
        if bits in PATTERN_BITS:
            max_score = max(max_score, PATTERN_BITS[bits])
    return max_score

6.2 进阶AI发展方向

当基础规则库实现后,可以考虑以下扩展:

  1. 引入搜索算法:结合MiniMax算法与alpha-beta剪枝
  2. 评估函数优化:设计更精细的局面评估指标
  3. 机器学习整合:使用神经网络评估棋盘价值
  4. 开局库扩展:增加更多专业开局模式
class AdvancedAI:
    def __init__(self):
        self.opening_book = load_opening_book()
        self.patterns = load_patterns()
        
    def evaluate_position(self, board):
        """综合评估棋盘局面"""
        score = 0
        
        # 模式匹配得分
        score += self.pattern_match_score(board)
        
        # 空间控制得分
        score += self.space_control_score(board)
        
        # 灵活度得分
        score += self.mobility_score(board)
        
        return score

这个五子棋AI实现展示了如何将人类棋类知识转化为计算机可执行的规则系统。虽然不如深度学习模型强大,但这种基于规则的AI具有实现简单、运行高效的优势,特别适合作为游戏内置AI或更复杂算法的基础框架。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐