用Python和Pygame从零打造一个能‘思考’的五子棋AI(附完整代码)
·
用Python和Pygame从零打造一个能‘思考’的五子棋AI(附完整代码)
五子棋作为一款经典策略游戏,其规则简单却蕴含无限变化。许多开发者尝试用编程实现人机对战,但要让AI具备基本"思考"能力并非易事。本文将带你从零开始,使用Python和Pygame构建一个能分析局势、做出决策的五子棋AI,完整代码可直接运行测试。
1. 环境准备与基础框架搭建
在开始编码前,我们需要配置开发环境并建立游戏基础框架。这个阶段将完成棋盘绘制、棋子显示等视觉部分。
首先安装必要的库:
pip install pygame numpy
初始化Pygame窗口并绘制棋盘:
import pygame
import numpy as np
def init_game():
pygame.init()
screen = pygame.display.set_mode((615, 615))
pygame.display.set_caption('五子棋AI')
screen.fill("#DD954F") # 棋盘底色
# 绘制棋盘网格线
for i in range(19):
# 横线
pygame.draw.line(screen, '#000000', (30, 30 + i*32), (594, 30 + i*32), 1)
# 竖线
pygame.draw.line(screen, '#000000', (30 + i*32, 30), (30 + i*32, 594), 1)
# 绘制星位标记
star_positions = [(3,3), (9,3), (15,3), (3,9), (9,9),
(15,9), (3,15), (9,15), (15,15)]
for x, y in star_positions:
pygame.draw.circle(screen, '#000000', (30 + x*32, 30 + y*32), 5)
pygame.display.flip()
return screen
棋盘状态用19x19的二维数组表示:
board = np.zeros((19, 19)) # 0:空 1:黑棋 2:白棋
2. 游戏核心逻辑实现
2.1 棋子绘制与落子判定
设计棋子绘制函数需要考虑视觉效果和状态记录:
def draw_piece(screen, x, y, color):
"""绘制棋子
:param x: 棋盘横坐标(0-18)
:param y: 棋盘纵坐标(0-18)
:param color: 'black'或'white'
"""
center = (30 + x*32, 30 + y*32)
if color == 'black':
pygame.draw.circle(screen, (45, 45, 45), center, 15)
pygame.draw.circle(screen, (80, 80, 80), center, 12)
else:
pygame.draw.circle(screen, (230, 230, 230), center, 15)
pygame.draw.circle(screen, (200, 200, 200), center, 12)
pygame.display.update()
鼠标点击处理逻辑:
def handle_click(pos, board, current_player):
"""处理玩家点击事件
:return: (x, y) 落子位置,None表示无效点击
"""
x, y = (pos[0]-30)//32, (pos[1]-30)//32
if 0 <= x < 19 and 0 <= y < 19 and board[x][y] == 0:
board[x][y] = 1 if current_player == 'black' else 2
return x, y
return None
2.2 胜负判定算法
五子棋胜负判定需要检查四个方向(水平、垂直、对角线)是否有五连珠:
def check_win(board, x, y):
"""检查是否获胜
:return: True/False
"""
directions = [(1,0), (0,1), (1,1), (1,-1)] # 四个检查方向
player = board[x][y]
for dx, dy in directions:
count = 1 # 当前棋子已算1个
# 正向检查
nx, ny = x + dx, y + dy
while 0 <= nx < 19 and 0 <= ny < 19 and board[nx][ny] == player:
count += 1
nx += dx
ny += dy
# 反向检查
nx, ny = x - dx, y - dy
while 0 <= nx < 19 and 0 <= ny < 19 and board[nx][ny] == player:
count += 1
nx -= dx
ny -= dy
if count >= 5:
return True
return False
3. AI核心算法设计
3.1 模式匹配策略
我们采用模式匹配方法让AI识别棋局形势。定义常见棋型及其优先级:
PATTERNS = [
# 活四 (优先级最高)
{'pattern': [0, 1, 1, 1, 1, 0], 'score': 10000},
# 冲四
{'pattern': [0, 1, 1, 1, 1, 2], 'score': 1000},
{'pattern': [2, 1, 1, 1, 1, 0], 'score': 1000},
# 活三
{'pattern': [0, 1, 1, 1, 0, 0], 'score': 500},
# 眠三
{'pattern': [2, 1, 1, 1, 0, 0], 'score': 200},
# 活二
{'pattern': [0, 1, 1, 0, 0, 0], 'score': 100},
# 眠二
{'pattern': [2, 1, 1, 0, 0, 0], 'score': 50}
]
3.2 局势评估函数
AI需要评估棋盘每个位置的潜在价值:
def evaluate_position(board, x, y, player):
"""评估某个位置的潜在价值
:return: 该位置得分
"""
if board[x][y] != 0: # 已有棋子
return 0
directions = [(1,0), (0,1), (1,1), (1,-1)]
total_score = 0
for dx, dy in directions:
line = []
# 获取该方向上的6个位置
for i in range(-2, 4):
nx, ny = x + i*dx, y + i*dy
if 0 <= nx < 19 and 0 <= ny < 19:
line.append(board[nx][ny])
else:
line.append(2) # 边界视为对手棋子
# 匹配预定义模式
for pattern in PATTERNS:
if line == pattern['pattern']:
total_score += pattern['score']
break
return total_score
3.3 AI决策算法
AI通过评估整个棋盘选择最佳落子位置:
def ai_move(board):
"""AI选择最佳落子位置
:return: (x, y) 坐标
"""
best_score = -1
best_move = None
# 遍历整个棋盘
for x in range(19):
for y in range(19):
if board[x][y] == 0:
# 评估进攻价值(AI视角)
attack_score = evaluate_position(board, x, y, 2)
# 评估防守价值(玩家视角)
defend_score = evaluate_position(board, x, y, 1)
# 综合得分
total_score = attack_score + defend_score * 0.8
if total_score > best_score:
best_score = total_score
best_move = (x, y)
# 如果没有找到策略点,随机选择
if best_move is None:
empty_pos = [(x,y) for x in range(19) for y in range(19) if board[x][y]==0]
return random.choice(empty_pos) if empty_pos else None
return best_move
4. 游戏主循环与完整实现
将各部分组合成完整游戏:
def main():
screen = init_game()
board = np.zeros((19, 19))
current_player = 'black' # 黑棋先行
game_over = False
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
return
if not game_over and current_player == 'black' and event.type == pygame.MOUSEBUTTONDOWN:
pos = handle_click(event.pos, board, current_player)
if pos:
x, y = pos
draw_piece(screen, x, y, current_player)
if check_win(board, x, y):
print("玩家获胜!")
game_over = True
current_player = 'white'
# AI回合
if not game_over and current_player == 'white':
pygame.time.delay(500) # AI思考时间
pos = ai_move(board)
if pos:
x, y = pos
board[x][y] = 2
draw_piece(screen, x, y, current_player)
if check_win(board, x, y):
print("AI获胜!")
game_over = True
current_player = 'black'
if __name__ == "__main__":
main()
5. 进阶优化方向
基础版本完成后,可以考虑以下优化:
-
增加难度级别:
- 初级:随机落子
- 中级:当前模式匹配
- 高级:加入Minimax搜索算法
-
性能优化:
# 使用局部搜索代替全局搜索 def get_neighbor_positions(board, radius=2): """获取已有棋子周围的位置""" positions = set() for x in range(19): for y in range(19): if board[x][y] != 0: for i in range(-radius, radius+1): for j in range(-radius, radius+1): nx, ny = x+i, y+j if 0 <= nx < 19 and 0 <= ny < 19 and board[nx][ny] == 0: positions.add((nx, ny)) return positions if positions else None -
增加开局库:
- 预置常见开局模式
- 提高AI开局阶段的表现
-
可视化评估:
def draw_evaluation(screen, board): """绘制棋盘各点评估值(调试用)""" font = pygame.font.SysFont('arial', 10) for x in range(19): for y in range(19): if board[x][y] == 0: score = evaluate_position(board, x, y, 2) if score > 0: text = font.render(str(score), True, (255,0,0)) screen.blit(text, (30 + x*32 - 10, 30 + y*32 - 5)) pygame.display.update()
这个五子棋AI实现展示了如何将游戏规则转化为计算机可执行的逻辑。虽然不如专业棋类AI强大,但核心思路相同:评估局势、预测发展、选择最优策略。读者可以在此基础上继续扩展,比如加入深度学习等更先进的算法。
更多推荐


所有评论(0)