跳到主要内容
Python 使用 Pygame 实现五子棋游戏完整教程 | 极客日志
Python 算法
Python 使用 Pygame 实现五子棋游戏完整教程 综述由AI生成 如何使用 Python 和 Pygame 库从零开发一个双人对战五子棋游戏。项目包含棋盘绘制、落子逻辑、胜负判定及界面交互等核心模块。通过分文件管理配置、渲染、面板和逻辑函数,实现了清晰的项目结构。文章详细解析了坐标转换算法与四方向连珠检测逻辑,并提供了完整的代码示例及运行环境配置指南,适合希望学习游戏开发基础及 Pygame 框架的开发者参考。
GitMaster 发布于 2025/2/6 更新于 2026/6/2 28 浏览Python 使用 Pygame 实现五子棋游戏完整教程
前言
本文详细介绍如何使用 Python 语言和 Pygame 图形库从零开发一个双人对战五子棋游戏。项目采用模块化设计,包含配置管理、棋盘绘制、信息面板、核心逻辑及主程序入口。通过本教程,读者可以掌握 Pygame 的基本窗口创建、事件监听、图像渲染以及简单的游戏状态管理逻辑。
环境准备
在开始编写代码之前,请确保您的开发环境满足以下要求:
操作系统 :Windows、macOS 或 Linux 均可(本文以 Windows 为例)。
Python 版本 :推荐使用 Python 3.8 及以上版本。
依赖库 :需要安装 pygame 库。
在终端或命令行中执行以下命令进行安装:
pip install pygame
图片素材 :为了获得更好的视觉效果,需要准备三张图片文件并放在项目目录的 images 文件夹下:
checkerboard_bg.png:棋盘背景图
black_chess.png:黑棋子图片(透明背景)
white_chess.png:白棋子图片(透明背景)
注:若暂无图片,代码中可暂时注释掉图片加载部分,改用圆形绘制代替。
项目结构
建议将项目文件组织如下:
gobang_project/
├── images/
│ ├── checkerboard_bg.png
│ ├── black_chess.png
│ └── white_chess.png
├── settings.py
├── checkerboard.py
├── infopanel.py
├── game_functions.py
└── gobang.py
核心代码实现
1. 配置文件 (settings.py)
此文件用于集中管理游戏的各项参数,如屏幕尺寸、字体设置、棋盘规格等。修改此处即可快速调整游戏外观。
class Settings ():
def __init__ (self ):
"""初始化的游戏配置"""
self .width = 700
self .height = 554
self .fontsize = 14
self .fonttype =
.number =
.bd_left =
.bd_top =
.bd_space =
.game_active =
.chess_player =
.prompt_info =
.win_number =
.checkerboard_bg =
.black_chess =
.white_chess =
.move_chess = []
'simsun'
self
15
self
30
self
30
self
36
self
True
self
1
self
'当前棋手:黑棋'
self
0
self
'images/checkerboard_bg.png'
self
'images/black_chess.png'
self
'images/white_chess.png'
self
2. 棋盘绘制模块 (checkerboard.py) 负责加载资源并在屏幕上绘制棋盘网格、坐标轴及棋子图像。使用了 pygame.image.load 加载图片,并使用 convert_alpha() 处理透明通道。
import sys
import pygame
class Checkerboard ():
def __init__ (self, ck_settings, screen, position ):
self .ck_settings = ck_settings
self .screen = screen
self .position = position
self .text_color = (0 , 0 , 0 )
self .font = pygame.font.SysFont(ck_settings.fonttype, ck_settings.fontsize)
self .checkerboard = []
try :
self .bg_image = pygame.image.load(ck_settings.checkerboard_bg)
self .black_image = pygame.image.load(ck_settings.black_chess).convert_alpha()
self .white_image = pygame.image.load(ck_settings.white_chess).convert_alpha()
self .chess_rect = self .black_image.get_rect()
except Exception as e:
print ('error:' , e)
sys.exit()
def draw_board (self ):
for i in range (self .ck_settings.number):
self .checkerboard.append([])
for j in range (self .ck_settings.number):
self .checkerboard[i].append(self .position(
self .ck_settings.bd_left + i * self .ck_settings.bd_space,
self .ck_settings.bd_top + j * self .ck_settings.bd_space
))
for i in range (0 , self .ck_settings.number):
x_text = self .font.render(chr (ord ('A' ) + i), True , self .text_color)
y_text = self .font.render(str (i + 1 ), True , self .text_color)
self .bg_image.blit(x_text, (
self .checkerboard[i][0 ].x - x_text.get_width() / 2 ,
self .checkerboard[i][0 ].y - 20
))
self .bg_image.blit(y_text, (
self .checkerboard[0 ][i].x - 20 ,
self .checkerboard[0 ][i].y - y_text.get_height() / 2
))
pygame.draw.line(self .bg_image, self .text_color,
self .checkerboard[0 ][i],
self .checkerboard[self .ck_settings.number-1 ][i])
pygame.draw.line(self .bg_image, self .text_color,
self .checkerboard[i][0 ],
self .checkerboard[i][self .ck_settings.number-1 ])
self .screen.blit(self .bg_image, (0 , 0 ))
3. 信息面板模块 (infopanel.py) 位于屏幕右侧,用于显示当前执棋方、提示信息或获胜宣言。使用 render 方法将文本转换为图像表面。
import pygame.font
class Infopanel ():
def __init__ (self, ck_settings, screen ):
"""初始化属性"""
self .settings = ck_settings
self .screen = screen
self .screen_rect = screen.get_rect()
self .info_color = (217 , 8 , 10 )
self .font = pygame.font.SysFont(ck_settings.fonttype, 16 )
def draw_info (self, info ):
"""将文字渲染为图像,并定位到右边水平居中"""
self .info_image = self .font.render(info, True , self .info_color)
self .info_image_rect = self .info_image.get_rect()
self .info_image_rect.right = self .screen_rect.right - (self .screen_rect.width - 536 - self .info_image_rect.width) / 2
self .info_image_rect.top = 50
self .screen.blit(self .info_image, self .info_image_rect)
4. 游戏逻辑模块 (game_functions.py) 这是游戏的核心,包含了落子更新、位置检查、胜负判定及事件监听。
落子与更新 update_board 函数负责切换棋手颜色、记录落子坐标并触发胜负检测。
import sys
import pygame
def update_board (ck_settings, cb, index_coordinates, position ):
"""更新棋盘信息"""
if ck_settings.chess_player == 1 :
ck_settings.prompt_info = '当前棋手:白棋'
img = cb.black_image
chess_type = 'black'
else :
ck_settings.prompt_info = '当前棋手:黑棋'
img = cb.white_image
chess_type = 'white'
"""落棋"""
dropState = check_at(ck_settings, index_coordinates)
if dropState:
i, j = index_coordinates
chess_x = cb.checkerboard[j][i].x - cb.chess_rect.width / 2
chess_y = cb.checkerboard[j][i].y - cb.chess_rect.height / 2
ck_settings.win_number += 1
ck_settings.move_chess.append({'type' : chess_type, 'coord' : position(i, j)})
cb.bg_image.blit(img, (chess_x, chess_y))
ck_settings.chess_player *= -1
if ck_settings.win_number >= 9 :
check_stats(ck_settings, (i, j))
else :
ck_settings.prompt_info = '已经有其他棋子'
位置检查 check_at 函数遍历已落子列表,防止重复落子。
def check_at (ck_settings, index_coordinates ):
for item in ck_settings.move_chess:
if index_coordinates == item['coord' ]:
return False
return True
胜负判定 check_stats 函数是算法核心。它以后一手棋为中心,向四个方向(横、竖、斜、反斜)延伸,统计连续同色棋子数量。如果达到 5 个则判定获胜。
def check_stats (ck_settings, pos ):
"""校验四个方向,是否有了输赢"""
pos_i, pos_j = pos
directs = [(1 , 0 ), (0 , 1 ), (1 , 1 ), (1 , -1 )]
for direct in directs:
line_checkerboard = []
d_x, d_y = direct
last = ck_settings.move_chess[-1 ]
line_ball = []
for ball in ck_settings.move_chess:
if ball['type' ] == last['type' ]:
x = ball['coord' ].x - last['coord' ].x
y = ball['coord' ].y - last['coord' ].y
if d_x == 0 :
if x == 0 :
line_ball.append(ball['coord' ])
if d_y == 0 :
if y == 0 :
line_ball.append(ball['coord' ])
if x * d_y == y * d_x:
line_ball.append(ball['coord' ])
if len (line_ball) >= 5 :
sorted_line = sorted (line_ball)
for i, item in enumerate (sorted_line):
index = i + 4
if index < len (sorted_line):
if d_x == 0 :
y1 = item.y
y2 = sorted_line[index].y
if abs (y1 - y2) == 4 :
ck_settings.prompt_info = '黑棋获胜' if last['type' ] == 'black' else '白棋获胜'
else :
x1 = item.x
x2 = sorted_line[index].x
if abs (x1 - x2) == 4 :
ck_settings.prompt_info = '黑棋获胜' if last['type' ] == 'black' else '白棋获胜'
else :
break
事件处理 check_events 监听鼠标点击和窗口关闭事件。to_index 将屏幕像素坐标转换为棋盘网格索引。
def check_events (ck_settings, cb, position ):
"""监听事件"""
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1 :
pos = pygame.mouse.get_pos()
x_first = cb.checkerboard[0 ][0 ].x
x_last = cb.checkerboard[ck_settings.number - 1 ][ck_settings.number - 1 ].x
y_first = cb.checkerboard[0 ][0 ].y
y_last = cb.checkerboard[ck_settings.number - 1 ][ck_settings.number - 1 ].y
if pos[0 ] < x_first or pos[0 ] > x_last or pos[1 ] < y_first or pos[1 ] > y_last:
ck_settings.prompt_info = '落子位置不正确!'
else :
index_coordinates = to_index(ck_settings, pos)
update_board(ck_settings, cb, index_coordinates, position)
def to_index (ck_settings, pos ):
"""实际坐标转换为棋盘下标"""
i = round ((pos[1 ] - ck_settings.bd_top) / ck_settings.bd_space)
j = round ((pos[0 ] - ck_settings.bd_left) / ck_settings.bd_space)
return (i, j)
5. 主程序入口 (gobang.py) import pygame
from settings import Settings
from checkerboard import Checkerboard
from collections import namedtuple
import game_functions as gf
from infopanel import Infopanel
def run_game ():
"""运行游戏"""
pygame.init()
clock = pygame.time.Clock()
ck_settings = Settings()
screen = pygame.display.set_mode((ck_settings.width, ck_settings.height))
pygame.display.set_caption('五子棋游戏' )
position = namedtuple('Position' , ['x' , 'y' ])
cb = Checkerboard(ck_settings, screen, position)
infopanel = Infopanel(ck_settings, screen)
while ck_settings.game_active:
cb.draw_board()
infopanel.draw_info(ck_settings.prompt_info)
gf.check_events(ck_settings, cb, position)
pygame.display.flip()
clock.tick(60 )
if __name__ == '__main__' :
run_game()
运行说明
确保所有代码文件在同一目录下,且 images 文件夹存在。
在终端中进入项目目录。
执行命令:
python gobang.py
弹出窗口后,点击棋盘交叉点进行落子。
常见问题与优化建议
常见问题
图片无法加载 :请检查 images 文件夹路径是否正确,以及文件名是否完全匹配(包括后缀)。
字体乱码 :尝试修改 settings.py 中的 fonttype 为系统通用的字体名称,如 'Arial' 或 'SimHei'。
落子无反应 :检查 check_events 中的坐标转换逻辑,确保鼠标坐标与棋盘边界匹配。
功能扩展 当前版本实现了基础的双人对战功能,后续可根据兴趣添加以下特性:
悔棋功能 :记录历史步数栈,支持撤销操作。
音效支持 :落子时播放清脆的敲击声。
AI 对手 :引入极小极大算法(Minimax)或蒙特卡洛树搜索(MCTS),实现人机对战。
计时器 :增加每步限时功能,提升竞技性。
界面美化 :使用更现代的 UI 框架替换原生 Pygame 绘制,提升视觉体验。
结语 本教程通过分模块的方式,清晰地展示了使用 Python 和 Pygame 开发桌面小游戏的全过程。从配置管理到核心算法,每个环节都经过详细拆解。希望读者能通过此案例,进一步探索游戏开发的更多可能性,如物理引擎集成、网络联机等功能。
相关免费在线工具 加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
Gemini 图片去水印 基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online