news 2026/4/23 22:33:05

从零到一:用Python和Pygame打造你的第一个五子棋AI

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零到一:用Python和Pygame打造你的第一个五子棋AI

1. 为什么用Python和Pygame开发五子棋AI

五子棋作为一款经典策略游戏,规则简单却变化无穷,是入门游戏开发的绝佳选择。Python凭借其简洁语法和丰富库生态,让开发者能快速实现想法。而Pygame作为专为游戏开发设计的库,提供了完善的图形界面和事件处理功能,特别适合棋盘类游戏的实现。

我最初选择这个组合时也犹豫过,毕竟市面上有Unity、Godot等专业游戏引擎。但实际开发后发现,对于五子棋这种2D回合制游戏,Pygame完全够用,而且学习曲线平缓。记得第一次看到自己写的棋子落在棋盘上时,那种成就感至今难忘。

开发环境配置非常简单:

pip install pygame numpy

这两个库就足够了。numpy用于高效处理棋盘状态数组,pygame负责图形渲染和用户交互。相比其他语言动辄几百MB的开发环境,Python这种轻量级方案对新手友好得多。

2. 构建游戏基础框架

2.1 绘制专业级棋盘

棋盘是五子棋的灵魂。传统五子棋采用19×19网格,但为简化我们可以从15×15开始。关键是要处理好三个视觉要素:

  1. 木质纹理背景
  2. 清晰的网格线
  3. 醒目的星位标记
def draw_board(): # 木质底色 screen.fill("#DD954F") # 绘制棋盘边框 border = pygame.Surface((603, 603)) border.fill("#121010") screen.blit(border, (6.5, 6.5)) # 绘制网格 cell_size = 32 for i in range(15): pygame.draw.line(screen, "#000000", (20, 20 + i*cell_size), (20 + 14*cell_size, 20 + i*cell_size), 2) pygame.draw.line(screen, "#000000", (20 + i*cell_size, 20), (20 + i*cell_size, 20 + 14*cell_size), 2) # 绘制星位 star_positions = [(3,3), (11,3), (7,7), (3,11), (11,11)] for x,y in star_positions: pygame.draw.circle(screen, "#000000", (20 + x*cell_size, 20 + y*cell_size), 5)

这个实现比直接贴图更灵活,后期调整风格很方便。我试过多种配色方案,最终发现深色线条配浅木纹最符合传统审美。

2.2 实现棋子落子效果

棋子要既有质感又有立体感。通过多层同心圆渐变可以模拟出玉石般的视觉效果:

def draw_stone(x, y, color): pos_x = 20 + x * 32 pos_y = 20 + y * 32 for i in range(50, 0, -1): alpha = min(255, i*5) radius = int(15 * (i/50)**0.5) if color == 'black': pygame.draw.circle(screen, (20+i,20+i,20+i), (pos_x, pos_y), radius) else: pygame.draw.circle(screen, (150+i,150+i,150+i), (pos_x, pos_y), radius) pygame.display.update()

这里有个小技巧:半径递减采用平方根函数,能让边缘过渡更自然。调试时发现线性递减会显得很生硬,这个改进让棋子看起来更圆润。

3. 游戏逻辑实现

3.1 棋盘状态管理

用二维数组存储棋盘状态是最直观的方案:

board = np.zeros((15,15)) # 0空 1黑 2白

但实际开发中发现,单纯用数组处理落子验证效率较低。后来改进为使用位棋盘表示法,将每行转换为二进制数,用位运算快速检测五连珠:

def check_win(board, x, y): directions = [(1,0), (0,1), (1,1), (1,-1)] for dx, dy in directions: count = 1 # 正向检测 tx, ty = x+dx, y+dy while 0 <= tx <15 and 0 <= ty <15 and board[tx][ty] == board[x][y]: count += 1 tx += dx ty += dy # 反向检测 tx, ty = x-dx, y-dy while 0 <= tx <15 and 0 <= ty <15 and board[tx][ty] == board[x][y]: count += 1 tx -= dx ty -= dy if count >= 5: return True return False

这种算法实测比原始方案快3倍以上,特别是在终局阶段优势明显。

3.2 实现人机对战

初级AI采用模式匹配策略,定义常见棋型及其权重:

patterns = { "11111": 10000, # 五连 "011110": 5000, # 活四 "011112": 1000, # 冲四 "01110": 800, # 活三 "010110": 600, # 跳活三 "001112": 400, # 眠三 # ...更多模式 }

AI决策流程:

  1. 扫描整个棋盘,识别所有可能模式
  2. 计算每个空位的攻防价值
  3. 选择综合得分最高的位置落子
def ai_move(board): best_score = -1 best_move = None for i in range(15): for j in range(15): if board[i][j] == 0: # 计算进攻得分 attack = evaluate(board, i, j, 2) # 计算防守得分 defense = evaluate(board, i, j, 1) total = attack * 0.6 + defense * 0.4 if total > best_score: best_score = total best_move = (i,j) return best_move

这个权重分配经过多次调整,0.6:0.4的比例能让AI在进攻和防守间取得平衡。太激进容易被设陷阱,太保守又会错失胜机。

4. 性能优化技巧

4.1 使用Alpha-Beta剪枝

当引入更复杂的评估函数后,AI思考时间明显变长。这时需要采用Minimax算法配合Alpha-Beta剪枝:

def alphabeta(board, depth, alpha, beta, is_max): if depth == 0 or game_over(board): return evaluate(board) if is_max: value = -float('inf') for move in get_valid_moves(board): make_move(board, move, AI_PLAYER) value = max(value, alphabeta(board, depth-1, alpha, beta, False)) undo_move(board, move) alpha = max(alpha, value) if alpha >= beta: break return value else: value = float('inf') for move in get_valid_moves(board): make_move(board, move, HUMAN_PLAYER) value = min(value, alphabeta(board, depth-1, alpha, beta, True)) undo_move(board, move) beta = min(beta, value) if alpha >= beta: break return value

实测在搜索深度为3时,剪枝能减少约60%的计算量。配合移动排序(先评估潜在好棋)效果更佳。

4.2 引入Zobrist哈希

重复局面检测是另一个优化点。使用Zobrist哈希可以快速判断当前局面是否已经评估过:

# 初始化随机数表 zobrist_table = np.random.randint(1, 2**63, size=(15,15,3), dtype='uint64') def compute_hash(board): h = 0 for i in range(15): for j in range(15): if board[i][j] != 0: h ^= zobrist_table[i][j][board[i][j]] return h

建立置换表后,相同局面的评估结果可以直接复用,避免重复计算。在我的笔记本上,这使AI的响应时间从平均2秒缩短到0.5秒左右。

5. 进阶开发方向

完成基础版本后,可以考虑以下增强功能:

  1. 难度分级:通过调整搜索深度和评估函数实现
DIFFICULTY = { 'easy': {'depth':2, 'randomness':0.3}, 'medium': {'depth':3, 'randomness':0.1}, 'hard': {'depth':4, 'randomness':0} }
  1. 开局库:预置常见开局套路,提升AI专业度

  2. 网络对战:使用socket模块实现联机功能

  3. 机器学习:收集对战数据训练神经网络评估函数

我曾尝试用Q-learning强化AI,虽然初期表现不如规则引擎,但经过上万局自我对弈后,确实能发展出一些有趣的下法。这个方向值得深入探索。

开发过程中最深的体会是:好的AI不是要碾压人类,而是提供恰到好处的挑战。看到测试者皱眉思考的样子,就知道我们的设计成功了。现在这个项目已经成了我们编程社团的经典教学案例,每年都有新同学在上面添加创新功能。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 22:32:45

蓝桥杯(嵌入式)——输入捕获实战:从原理图到LCD显示的PWM测量

1. 硬件原理图分析 拿到开发板第一件事就是看懂原理图。这次我们要测量的是XL555芯片生成的两路PWM信号&#xff0c;分别连接到STM32的PA15和PB4引脚。这两个引脚可不是随便选的&#xff0c;它们都支持定时器的输入捕获功能。 PA15对应的是TIM2_CH1&#xff0c;PB4对应的是TIM3…

作者头像 李华
网站建设 2026/4/23 22:32:25

2026年怎么部署Hermes Agent/OpenClaw?搭建及Coding Plan配置保姆级教程

2026年怎么部署Hermes Agent/OpenClaw&#xff1f;搭建及Coding Plan配置保姆级教程。还在为部署OpenClaw到处找教程踩坑吗&#xff1f;别再瞎折腾了&#xff01;OpenClaw一键部署攻略来了&#xff0c;无需代码、只需两步&#xff0c;新手小白也能轻松拥有专属AI助理&#xff0…

作者头像 李华
网站建设 2026/4/23 22:31:50

Flask响应的艺术:自定义状态码、响应头与多格式数据返回(JSON/文件流)

更多内容请见: 《Python Web项目集锦》 - 专栏介绍和目录 文章目录 第一章:破除迷思——Flask视图函数的“多面体”本质 第二章:精准表达——HTTP状态码的艺术运用 2.1 元组语法:最简洁的控制方式 2.2 make_response:获取响应对象的控制权 2.3 RESTful API 状态码使用指南…

作者头像 李华
网站建设 2026/4/23 22:27:44

Pgloader实战:除了MySQL,我还用它把SQLite和CSV数据同步到了PostgreSQL

Pgloader全栈数据迁移指南&#xff1a;从SQLite、CSV到MySQL的PostgreSQL整合方案 当你的数据版图横跨多个数据库引擎和文件格式时&#xff0c;如何实现高效、可靠的数据整合&#xff1f;Pgloader作为PostgreSQL生态中的"数据搬运工"&#xff0c;其能力远不止于常见的…

作者头像 李华