本文作者:xiaoshi

Python 游戏 AI 学习的简单实现

Python 游戏 AI 学习的简单实现摘要: ...

Python游戏AI入门:从零打造你的第一个智能对手

为什么选择Python开发游戏AI?

Python凭借其简洁的语法和丰富的库支持,成为学习游戏AI开发的理想选择。对于初学者来说,不需要掌握复杂的底层编程知识,就能快速实现一个能思考、会决策的游戏AI。

Python 游戏 AI 学习的简单实现

市面上大多数游戏AI教程都专注于理论讲解,而本文将带你动手实践,用不到100行代码构建一个会玩井字棋的AI程序。这个项目不仅适合编程新手,也能给有经验的开发者提供AI算法实现的参考。

开发环境准备

开始前,请确保你的电脑安装了Python 3.6或更高版本。我们将使用以下几个关键库:

  • Pygame:用于创建游戏界面
  • Numpy:处理游戏状态数据
  • Random:为AI添加随机性

安装这些库只需在命令行中运行:

pip install pygame numpy

井字棋游戏基础框架

首先构建游戏的基本结构。创建一个tic_tac_toe.py文件,添加以下代码:

import pygame
import numpy as np
import sys

# 初始化游戏
pygame.init()
WIDTH, HEIGHT = 600, 600
LINE_WIDTH = 15
BOARD_ROWS, BOARD_COLS = 3, 3
SQUARE_SIZE = WIDTH // BOARD_COLS

# 颜色定义
BG_COLOR = (28, 170, 156)
LINE_COLOR = (23, 145, 135)
CIRCLE_COLOR = (239, 231, 200)
CROSS_COLOR = (66, 66, 66)

# 创建游戏窗口
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('井字棋AI')
screen.fill(BG_COLOR)

# 游戏板
board = np.zeros((BOARD_ROWS, BOARD_COLS))

# 绘制游戏网格
def draw_lines():
    # 水平线
    pygame.draw.line(screen, LINE_COLOR, (0, SQUARE_SIZE), (WIDTH, SQUARE_SIZE), LINE_WIDTH)
    pygame.draw.line(screen, LINE_COLOR, (0, 2 * SQUARE_SIZE), (WIDTH, 2 * SQUARE_SIZE), LINE_WIDTH)
    # 垂直线
    pygame.draw.line(screen, LINE_COLOR, (SQUARE_SIZE, 0), (SQUARE_SIZE, HEIGHT), LINE_WIDTH)
    pygame.draw.line(screen, LINE_COLOR, (2 * SQUARE_SIZE, 0), (2 * SQUARE_SIZE, HEIGHT), LINE_WIDTH)

# 主游戏循环
def main():
    draw_lines()

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

        pygame.display.update()

if __name__ == "__main__":
    main()

这段代码创建了一个600x600像素的窗口,绘制了井字棋的3x3网格。目前它只是一个静态界面,接下来我们要添加游戏逻辑。

实现游戏基本逻辑

在原有代码基础上,添加玩家操作和游戏状态判断功能:

# 在main()函数前添加以下函数

def mark_square(row, col, player):
    board[row][col] = player

def available_square(row, col):
    return board[row][col] == 0

def is_board_full():
    for row in range(BOARD_ROWS):
        for col in range(BOARD_COLS):
            if board[row][col] == 0:
                return False
    return True

def check_win(player):
    # 检查行
    for row in range(BOARD_ROWS):
        if board[row][0] == player and board[row][1] == player and board[row][2] == player:
            return True
    # 检查列
    for col in range(BOARD_COLS):
        if board[0][col] == player and board[1][col] == player and board[2][col] == player:
            return True
    # 检查对角线
    if board[0][0] == player and board[1][1] == player and board[2][2] == player:
        return True
    if board[0][2] == player and board[1][1] == player and board[2][0] == player:
        return True
    return False

# 更新主游戏循环
def main():
    draw_lines()
    player = 1  # 1表示玩家,2表示AI
    game_over = False

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

            if event.type == pygame.MOUSEBUTTONDOWN and not game_over and player == 1:
                mouseX = event.pos[0]  # x坐标
                mouseY = event.pos[1]  # y坐标

                clicked_row = int(mouseY // SQUARE_SIZE)
                clicked_col = int(mouseX // SQUARE_SIZE)

                if available_square(clicked_row, clicked_col):
                    mark_square(clicked_row, clicked_col, player)
                    if check_win(player):
                        game_over = True
                    player = 2  # 轮到AI

        pygame.display.update()

现在游戏已经可以响应玩家的点击,在格子中放置标记,并判断胜负。接下来是最有趣的部分——实现AI逻辑。

实现简易游戏AI

我们将使用"极小化极大算法"(Minimax)来实现AI。这是一种在零和游戏中寻找最优策略的算法,特别适合井字棋这种完全信息博弈。

# 添加AI相关函数
import random

def minimax(board, depth, is_maximizing):
    if check_win(2):  # AI获胜
        return 1
    elif check_win(1):  # 玩家获胜
        return -1
    elif is_board_full():  # 平局
        return 0

    if is_maximizing:
        best_score = -float('inf')
        for row in range(BOARD_ROWS):
            for col in range(BOARD_COLS):
                if board[row][col] == 0:
                    board[row][col] = 2
                    score = minimax(board, depth + 1, False)
                    board[row][col] = 0
                    best_score = max(score, best_score)
        return best_score
    else:
        best_score = float('inf')
        for row in range(BOARD_ROWS):
            for col in range(BOARD_COLS):
                if board[row][col] == 0:
                    board[row][col] = 1
                    score = minimax(board, depth + 1, True)
                    board[row][col] = 0
                    best_score = min(score, best_score)
        return best_score

def best_move():
    best_score = -float('inf')
    move = None
    for row in range(BOARD_ROWS):
        for col in range(BOARD_COLS):
            if board[row][col] == 0:
                board[row][col] = 2
                score = minimax(board, 0, False)
                board[row][col] = 0
                if score > best_score:
                    best_score = score
                    move = (row, col)
    return move

# 更新主游戏循环,添加AI回合
def main():
    draw_lines()
    player = 1
    game_over = False

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

            if event.type == pygame.MOUSEBUTTONDOWN and not game_over and player == 1:
                mouseX = event.pos[0]
                mouseY = event.pos[1]

                clicked_row = int(mouseY // SQUARE_SIZE)
                clicked_col = int(mouseX // SQUARE_SIZE)

                if available_square(clicked_row, clicked_col):
                    mark_square(clicked_row, clicked_col, player)
                    if check_win(player):
                        game_over = True
                    player = 2

        # AI回合
        if player == 2 and not game_over:
            row, col = best_move()
            mark_square(row, col, 2)
            if check_win(2):
                game_over = True
            player = 1

        pygame.display.update()

完善游戏视觉效果

为了让游戏体验更好,我们添加绘制X和O的功能,以及游戏结束提示:

# 添加绘制函数
def draw_figures():
    for row in range(BOARD_ROWS):
        for col in range(BOARD_COLS):
            if board[row][col] == 1:  # 玩家
                pygame.draw.circle(screen, CIRCLE_COLOR, 
                                  (int(col * SQUARE_SIZE + SQUARE_SIZE // 2), 
                                   int(row * SQUARE_SIZE + SQUARE_SIZE // 2)), 
                                  SQUARE_SIZE // 3, 15)
            elif board[row][col] == 2:  # AI
                pygame.draw.line(screen, CROSS_COLOR, 
                                (col * SQUARE_SIZE + SQUARE_SIZE // 4, row * SQUARE_SIZE + SQUARE_SIZE // 4),
                                (col * SQUARE_SIZE + 3 * SQUARE_SIZE // 4, row * SQUARE_SIZE + 3 * SQUARE_SIZE // 4),
                                25)
                pygame.draw.line(screen, CROSS_COLOR, 
                                (col * SQUARE_SIZE + SQUARE_SIZE // 4, row * SQUARE_SIZE + 3 * SQUARE_SIZE // 4),
                                (col * SQUARE_SIZE + 3 * SQUARE_SIZE // 4, row * SQUARE_SIZE + SQUARE_SIZE // 4),
                                25)

# 添加游戏结束显示
def draw_game_over(winner):
    font = pygame.font.SysFont('Arial', 40)
    if winner == 1:
        text = "你赢了!"
    elif winner == 2:
        text = "AI赢了!"
    else:
        text = "平局!"

    text_surface = font.render(text, True, (255, 255, 255))
    screen.blit(text_surface, (WIDTH // 2 - text_surface.get_width() // 2, 
                              HEIGHT // 2 - text_surface.get_height() // 2))

# 更新主游戏循环
def main():
    draw_lines()
    player = 1
    game_over = False

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

            if event.type == pygame.MOUSEBUTTONDOWN and not game_over and player == 1:
                mouseX = event.pos[0]
                mouseY = event.pos[1]

                clicked_row = int(mouseY // SQUARE_SIZE)
                clicked_col = int(mouseX // SQUARE_SIZE)

                if available_square(clicked_row, clicked_col):
                    mark_square(clicked_row, clicked_col, player)
                    if check_win(player):
                        game_over = True
                        winner = player
                    elif is_board_full():
                        game_over = True
                        winner = 0
                    player = 2

        # AI回合
        if player == 2 and not game_over:
            row, col = best_move()
            mark_square(row, col, 2)
            if check_win(2):
                game_over = True
                winner = 2
            elif is_board_full():
                game_over = True
                winner = 0
            player = 1

        draw_figures()
        if game_over:
            draw_game_over(winner)

        pygame.display.update()

优化AI性能

当前的Minimax算法会遍历所有可能的游戏状态,对于井字棋这种简单游戏没问题,但对于更复杂的游戏效率太低。我们可以通过"Alpha-Beta剪枝"来优化:

def minimax(board, depth, is_maximizing, alpha=-float('inf'), beta=float('inf')):
    if check_win(2):
        return 1
    elif check_win(1):
        return -1
    elif is_board_full():
        return 0

    if is_maximizing:
        best_score = -float('inf')
        for row in range(BOARD_ROWS):
            for col in range(BOARD_COLS):
                if board[row][col] == 0:
                    board[row][col] = 2
                    score = minimax(board, depth + 1, False, alpha, beta)
                    board[row][col] = 0
                    best_score = max(score, best_score)
                    alpha = max(alpha, best_score)
                    if beta <= alpha:
                        break
        return best_score
    else:
        best_score = float('inf')
        for row in range(BOARD_ROWS):
            for col in range(BOARD_COLS):
                if board[row][col] == 0:
                    board[row][col] = 1
                    score = minimax(board, depth + 1, True, alpha, beta)
                    board[row][col] = 0
                    best_score = min(score, best_score)
                    beta = min(beta, best_score)
                    if beta <= alpha:
                        break
        return best_score

下一步学习方向

完成这个基础项目后,你可以尝试以下进阶内容:

  1. 为AI添加难度级别(通过限制搜索深度)
  2. 实现其他游戏如五子棋、象棋的AI
  3. 尝试使用机器学习方法(如Q-learning)训练AI
  4. 优化游戏界面,添加音效和动画

Python游戏AI开发是一个充满乐趣的领域,通过这个简单的井字棋项目,你已经掌握了基本概念。继续探索,你将能够创建更复杂、更智能的游戏对手!

文章版权及转载声明

作者:xiaoshi本文地址:http://blog.luashi.cn/post/2196.html发布于 05-30
文章转载或复制请以超链接形式并注明出处小小石博客

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

阅读
分享

发表评论

快捷回复:

评论列表 (暂无评论,14人围观)参与讨论

还没有评论,来说两句吧...