基于Python的五子棋本地小游戏实现
我将指导您使用Python实现一个本地五子棋小游戏。游戏包括以下功能:
基本规则:玩家轮流落子(黑棋先手),第一个形成连续五个棋子(水平、垂直或对角线)获胜。棋盘背景皮肤更换:支持多个背景图片,用户可通过按键切换。游戏界面:图形化显示,使用鼠标落子。
我们将使用Pygame库来实现图形界面,因为它简单易用且适合游戏开发。下面,我将分步解释实现过程,并提供完整代码。
步骤1: 环境准备
首先,确保安装了Python和Pygame库。通过pip安装Pygame:
pip install pygame
步骤2: 游戏设计概述
棋盘尺寸:使用15×15网格,每个格子大小为40像素。玩家:黑棋(玩家1)和白棋(玩家2)轮流落子。胜负判定:实时检查是否形成连续五个同色棋子。背景皮肤:预加载多个背景图片,用户按”B”键切换。游戏流程:初始化窗口 → 绘制棋盘 → 处理事件 → 更新显示。
步骤3: 分步实现
我将逐步构建代码,确保结构清晰。
3.1 导入库和初始化
导入所需库,初始化pygame,设置窗口和颜色常量。
import pygame
import sys
# 初始化pygame
pygame.init()
# 常量定义
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 800
GRID_SIZE = 15 # 棋盘网格大小 (15x15)
CELL_SIZE = 40 # 每个格子的像素大小
BOARD_MARGIN = 50 # 棋盘边距
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
GRAY = (200, 200, 200)
# 创建窗口
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("五子棋游戏")
3.2 加载背景皮肤
定义多个背景图片路径,并加载初始背景。用户按”B”键切换。
# 背景皮肤路径列表
backgrounds = [
"background1.jpg", # 默认棋盘背景
"background2.jpg", # 可选皮肤1
"background3.jpg" # 可选皮肤2
]
# 初始化当前背景索引和图片
current_bg_index = 0
background_img = pygame.image.load(backgrounds[current_bg_index])
background_img = pygame.transform.scale(background_img, (SCREEN_WIDTH, SCREEN_HEIGHT))
3.3 游戏状态变量
存储棋盘状态、当前玩家和游戏结束标志。
# 棋盘状态:0表示空,1表示黑棋,2表示白棋
board = [[0 for _ in range(GRID_SIZE)] for _ in range(GRID_SIZE)]
current_player = 1 # 1: 黑棋,2: 白棋
game_over = False
winner = None
3.4 绘制棋盘
根据当前背景绘制棋盘网格和棋子。
def draw_board():
# 绘制背景
screen.blit(background_img, (0, 0))
# 绘制网格线
for i in range(GRID_SIZE):
# 横线
pygame.draw.line(screen, BLACK,
(BOARD_MARGIN, BOARD_MARGIN + i * CELL_SIZE),
(BOARD_MARGIN + (GRID_SIZE - 1) * CELL_SIZE, BOARD_MARGIN + i * CELL_SIZE), 2)
# 竖线
pygame.draw.line(screen, BLACK,
(BOARD_MARGIN + i * CELL_SIZE, BOARD_MARGIN),
(BOARD_MARGIN + i * CELL_SIZE, BOARD_MARGIN + (GRID_SIZE - 1) * CELL_SIZE), 2)
# 绘制棋子
for row in range(GRID_SIZE):
for col in range(GRID_SIZE):
if board[row][col] == 1: # 黑棋
pygame.draw.circle(screen, BLACK,
(BOARD_MARGIN + col * CELL_SIZE, BOARD_MARGIN + row * CELL_SIZE),
CELL_SIZE // 2 - 2)
elif board[row][col] == 2: # 白棋
pygame.draw.circle(screen, WHITE,
(BOARD_MARGIN + col * CELL_SIZE, BOARD_MARGIN + row * CELL_SIZE),
CELL_SIZE // 2 - 2)
# 显示当前玩家信息
font = pygame.font.SysFont(None, 36)
player_text = f"当前玩家: {'黑棋' if current_player == 1 else '白棋'}"
text_surface = font.render(player_text, True, BLUE)
screen.blit(text_surface, (50, 20))
# 如果游戏结束,显示获胜信息
if game_over:
winner_text = f"游戏结束! {'黑棋获胜' if winner == 1 else '白棋获胜'}"
text_surface = font.render(winner_text, True, RED)
screen.blit(text_surface, (SCREEN_WIDTH // 2 - 100, SCREEN_HEIGHT - 50))
3.5 处理鼠标事件
玩家点击棋盘时,计算落子位置并更新棋盘状态。
def handle_click(pos):
global current_player, game_over, winner
if game_over:
return # 游戏结束,不处理点击
# 计算点击的网格坐标
x, y = pos
if (BOARD_MARGIN <= x <= BOARD_MARGIN + (GRID_SIZE - 1) * CELL_SIZE and
BOARD_MARGIN <= y <= BOARD_MARGIN + (GRID_SIZE - 1) * CELL_SIZE):
col = round((x - BOARD_MARGIN) / CELL_SIZE)
row = round((y - BOARD_MARGIN) / CELL_SIZE)
# 确保坐标在范围内且位置为空
if 0 <= row < GRID_SIZE and 0 <= col < GRID_SIZE and board[row][col] == 0:
board[row][col] = current_player
# 检查是否获胜
if check_win(row, col, current_player):
game_over = True
winner = current_player
else:
# 切换玩家
current_player = 3 - current_player # 1->2 或 2->1
3.6 胜负判定函数
检查从落子点开始的八个方向是否有连续五个同色棋子。
def check_win(row, col, player):
# 检查方向:横、竖、左上-右下、右上-左下
directions = [(0, 1), (1, 0), (1, 1), (1, -1)]
for dr, dc in directions:
count = 1 # 当前落子点
# 正向检查
r, c = row + dr, col + dc
while 0 <= r < GRID_SIZE and 0 <= c < GRID_SIZE and board[r][c] == player:
count += 1
r += dr
c += dc
# 反向检查
r, c = row - dr, col - dc
while 0 <= r < GRID_SIZE and 0 <= c < GRID_SIZE and board[r][c] == player:
count += 1
r -= dr
c -= dc
# 如果连续五个或更多,则获胜
if count >= 5:
return True
return False
3.7 处理键盘事件
添加背景皮肤切换功能:按”B”键切换背景。
def handle_keydown(key):
global current_bg_index, background_img
if key == pygame.K_b: # 按B键切换背景
current_bg_index = (current_bg_index + 1) % len(backgrounds)
background_img = pygame.image.load(backgrounds[current_bg_index])
background_img = pygame.transform.scale(background_img, (SCREEN_WIDTH, SCREEN_HEIGHT))
3.8 主游戏循环
整合所有函数,处理事件和更新屏幕。
def main():
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1: # 左键点击
handle_click(event.pos)
elif event.type == pygame.KEYDOWN:
handle_keydown(event.key)
# 绘制棋盘和更新显示
draw_board()
pygame.display.flip()
clock.tick(60) # 帧率60FPS
if __name__ == "__main__":
main()
完整代码
以下是完整的Python代码。请将背景图片文件(如background1.jpg, background2.jpg)放在同一目录下,或修改路径。
import pygame
import sys
# 初始化pygame
pygame.init()
# 常量定义
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 800
GRID_SIZE = 15 # 棋盘网格大小 (15x15)
CELL_SIZE = 40 # 每个格子的像素大小
BOARD_MARGIN = 50 # 棋盘边距
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
GRAY = (200, 200, 200)
# 背景皮肤路径列表 - 请替换为您的图片路径
backgrounds = [
"background1.jpg", # 默认棋盘背景
"background2.jpg", # 可选皮肤1
"background3.jpg" # 可选皮肤2
]
current_bg_index = 0
background_img = pygame.image.load(backgrounds[current_bg_index])
background_img = pygame.transform.scale(background_img, (SCREEN_WIDTH, SCREEN_HEIGHT))
# 创建窗口
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("五子棋游戏")
# 棋盘状态:0表示空,1表示黑棋,2表示白棋
board = [[0 for _ in range(GRID_SIZE)] for _ in range(GRID_SIZE)]
current_player = 1 # 1: 黑棋,2: 白棋
game_over = False
winner = None
def draw_board():
# 绘制背景
screen.blit(background_img, (0, 0))
# 绘制网格线
for i in range(GRID_SIZE):
# 横线
pygame.draw.line(screen, BLACK,
(BOARD_MARGIN, BOARD_MARGIN + i * CELL_SIZE),
(BOARD_MARGIN + (GRID_SIZE - 1) * CELL_SIZE, BOARD_MARGIN + i * CELL_SIZE), 2)
# 竖线
pygame.draw.line(screen, BLACK,
(BOARD_MARGIN + i * CELL_SIZE, BOARD_MARGIN),
(BOARD_MARGIN + i * CELL_SIZE, BOARD_MARGIN + (GRID_SIZE - 1) * CELL_SIZE), 2)
# 绘制棋子
for row in range(GRID_SIZE):
for col in range(GRID_SIZE):
if board[row][col] == 1: # 黑棋
pygame.draw.circle(screen, BLACK,
(BOARD_MARGIN + col * CELL_SIZE, BOARD_MARGIN + row * CELL_SIZE),
CELL_SIZE // 2 - 2)
elif board[row][col] == 2: # 白棋
pygame.draw.circle(screen, WHITE,
(BOARD_MARGIN + col * CELL_SIZE, BOARD_MARGIN + row * CELL_SIZE),
CELL_SIZE // 2 - 2)
# 显示当前玩家信息
font = pygame.font.SysFont(None, 36)
player_text = f"当前玩家: {'黑棋' if current_player == 1 else '白棋'}"
text_surface = font.render(player_text, True, BLUE)
screen.blit(text_surface, (50, 20))
# 如果游戏结束,显示获胜信息
if game_over:
winner_text = f"游戏结束! {'黑棋获胜' if winner == 1 else '白棋获胜'}"
text_surface = font.render(winner_text, True, RED)
screen.blit(text_surface, (SCREEN_WIDTH // 2 - 100, SCREEN_HEIGHT - 50))
def handle_click(pos):
global current_player, game_over, winner
if game_over:
return # 游戏结束,不处理点击
# 计算点击的网格坐标
x, y = pos
if (BOARD_MARGIN <= x <= BOARD_MARGIN + (GRID_SIZE - 1) * CELL_SIZE and
BOARD_MARGIN <= y <= BOARD_MARGIN + (GRID_SIZE - 1) * CELL_SIZE):
col = round((x - BOARD_MARGIN) / CELL_SIZE)
row = round((y - BOARD_MARGIN) / CELL_SIZE)
# 确保坐标在范围内且位置为空
if 0 <= row < GRID_SIZE and 0 <= col < GRID_SIZE and board[row][col] == 0:
board[row][col] = current_player
# 检查是否获胜
if check_win(row, col, current_player):
game_over = True
winner = current_player
else:
# 切换玩家
current_player = 3 - current_player # 1->2 或 2->1
def check_win(row, col, player):
# 检查方向:横、竖、左上-右下、右上-左下
directions = [(0, 1), (1, 0), (1, 1), (1, -1)]
for dr, dc in directions:
count = 1 # 当前落子点
# 正向检查
r, c = row + dr, col + dc
while 0 <= r < GRID_SIZE and 0 <= c < GRID_SIZE and board[r][c] == player:
count += 1
r += dr
c += dc
# 反向检查
r, c = row - dr, col - dc
while 0 <= r < GRID_SIZE and 0 <= c < GRID_SIZE and board[r][c] == player:
count += 1
r -= dr
c -= dc
# 如果连续五个或更多,则获胜
if count >= 5:
return True
return False
def handle_keydown(key):
global current_bg_index, background_img
if key == pygame.K_b: # 按B键切换背景
current_bg_index = (current_bg_index + 1) % len(backgrounds)
background_img = pygame.image.load(backgrounds[current_bg_index])
background_img = pygame.transform.scale(background_img, (SCREEN_WIDTH, SCREEN_HEIGHT))
def main():
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1: # 左键点击
handle_click(event.pos)
elif event.type == pygame.KEYDOWN:
handle_keydown(event.key)
# 绘制棋盘和更新显示
draw_board()
pygame.display.flip()
clock.tick(60) # 帧率60FPS
if __name__ == "__main__":
main()
运行和测试
将代码保存为。准备背景图片(如从网上下载棋盘背景图),并修改
gobang.py列表中的路径。运行程序:
backgrounds。游戏操作:
python gobang.py
鼠标左键点击落子。按”B”键切换背景皮肤。关闭窗口退出游戏。
扩展建议
添加禁手规则:五子棋有禁手(如双活三),您可以在函数中添加额外检查。美化界面:使用更精美的背景图片或添加音效。多人模式:扩展为网络对战,使用socket库。
check_win
这个实现满足了您的要求:完善了基本规则(胜负判定)、棋盘背景皮肤更换功能。如果您有任何问题或需要进一步优化,请随时告诉我!@TOC
欢迎使用Markdown编辑器
你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。
新的改变
我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:
全新的界面设计 ,将会带来全新的写作体验;在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;全新的 KaTeX数学公式 语法;增加了支持甘特图的mermaid语法1 功能;增加了 多屏幕编辑 Markdown文章功能;增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;增加了 检查列表 功能。
功能快捷键
撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G
查找:Ctrl/Command + F
替换:Ctrl/Command + G
合理的创建标题,有助于目录的生成
直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用语法后生成一个完美的目录。
TOC
如何改变文本的样式
强调文本 强调文本
加粗文本 加粗文本
标记文本
删除文本
引用文本
H2O is是液体。
210 运算结果是 1024.
插入链接与图片
链接: link.
图片: 
带尺寸的图片: 
居中的图片: 
居中并且带尺寸的图片: 
当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。
如何插入一段漂亮的代码片
去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 .
代码片
// An highlighted block
var foo = 'bar';
生成一个适合你的列表
项目
项目
项目
项目1项目2项目3
计划任务 完成任务
创建一个表格
一个简单的表格是这么创建的:
| 项目 | Value |
|---|---|
| 电脑 | $1600 |
| 手机 | $12 |
| 导管 | $1 |
设定内容居中、居左、居右
使用居中
:---------:
使用居左
:----------
使用居右
----------:
| 第一列 | 第二列 | 第三列 |
|---|---|---|
| 第一列文本居中 | 第二列文本居右 | 第三列文本居左 |
SmartyPants
SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:
| TYPE | ASCII | HTML |
|---|---|---|
| Single backticks | |
‘Isn’t this fun?’ |
| Quotes | |
“Isn’t this fun?” |
| Dashes | |
– is en-dash, — is em-dash |
创建一个自定义列表
Markdown
Text-to-
HTML conversion tool
Authors
John
Luke
如何创建一个注脚
一个具有注脚的文本。2
注释也是必不可少的
Markdown将文本转换为 HTML。
KaTeX数学公式
您可以使用渲染LaTeX数学表达式 KaTeX:
Gamma公式展示
Γ
(
n
)
=
(
n
−
1
)
!
∀
n
∈
N
Gamma(n) = (n-1)!quadforall ninmathbb N
Γ(n)=(n−1)!∀n∈N 是通过欧拉积分
你可以找到更多关于的信息 LaTeX 数学表达式here.
新的甘特图功能,丰富你的文章
关于 甘特图 语法,参考 这儿,
UML 图表
可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:
这将产生一个流程图。:
关于 Mermaid 语法,参考 这儿,
FLowchart流程图
我们依旧会支持flowchart的流程图:
关于 Flowchart流程图 语法,参考 这儿.
导出与导入
导出
如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。
导入
如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。
mermaid语法说明 ↩︎
注脚的解释 ↩︎





