Python Turtle交互编程实战——五子棋游戏
本文适配浙江高考信息技术选考Python模块,以趣味游戏方式深化知识点,考点覆盖:「面向对象编程」「turtle交互绘图」「四方向遍历算法」「事件绑定」「全局变量」等知识点,附完整可运行代码。
🎯 考点知识点速览
| 考点 |
考频 |
核心要点 |
| 二维列表生成式 |
⭐⭐⭐⭐ |
[[0 for _ in range(k)] for _ in range(k)] |
global 关键字 |
⭐⭐⭐⭐ |
修改全局变量前必须声明,否则创建局部变量 |
| turtle 事件绑定 |
⭐⭐⭐⭐⭐ |
onclick(函数名) 自动传入点击坐标 (x,y) |
类 & __init__ |
⭐⭐⭐⭐ |
self 指代实例本身,实例属性通过 self.属性名 定义 |
| 四方向遍历算法 |
⭐⭐⭐⭐⭐ |
连子/数组搜索类题目必考,双向计数技巧 |
turtle.mainloop() |
⭐⭐⭐⭐ |
事件循环,缺少会导致窗口一闪而过 |
🎮 实战项目:五子棋游戏
点击灰色圆圈下棋,黑白交替,三子连成线(横/竖/斜)即胜利。
🔧 代码逐段解析
1. 导入模块 + 初始化配置
import turtle
# 颜色模式设置为浮点模式 0.0~1.0
turtle.colormode(1)
# 背景色设为浅灰色
turtle.bgcolor((0.8, 0.8, 0.8))
# 全局状态
f = 0 # 回合标记:0 = 黑棋,1 = 白棋
k = 5 # 棋盘规模 5×5
game_over = False # 游戏结束标记
✅ 考点:全局变量声明,turtle基础配置
2. 二维棋盘数据结构
# data:存储棋子图形对象(turtle实例)
data = [[0 for _ in range(k)] for _ in range(k)]
# data2:存储游戏逻辑数据 0=空位 1=黑棋 2=白棋
data2 = [[0 for _ in range(k)] for _ in range(k)]
✅ 考点:二维列表生成式,两个数组分别存视图与逻辑的MVC设计思想
3. 四方向定义(胜负判断核心)
directions = [
[(0, -1), (0, 1)], # 左右(横向)
[(-1, 0), (1, 0)], # 上下(纵向)
[(-1, -1), (1, 1)], # 左斜(主对角线)
[(-1, 1), (1, -1)] # 右斜(副对角线)
]
📌 方向向量:
每组是一对相反方向的向量,落子后向两边同时计数
✅ 考点:方向向量设计,连子问题通用解法
4. 胜负判断函数
def win(x, y, tk):
global game_over
for d in directions:
cnt = 1 # ★ 初始值1,包含当前落子
# 正向遍历
tx, ty = x + d[0][0], y + d[0][1]
while 0 <= tx < k and 0 <= ty < k and data2[tx][ty] == tk:
cnt += 1
tx += d[0][0]
ty += d[0][1]
# 反向遍历
tx, ty = x + d[1][0], y + d[1][1]
while 0 <= tx < k and 0 <= ty < k and data2[tx][ty] == tk:
cnt += 1
tx += d[1][0]
ty += d[1][1]
if cnt >= 3:
print(f"{tk}颜色胜利")
game_over = True
return True
return False
✅ 考点:双向遍历算法,边界判断,全局变量修改
5. 棋子类(面向对象核心)
class Fang:
def __init__(self, x, y, i, j):
self.x = i # 记录当前格子在数组中的行索引
self.y = j # 记录当前格子在数组中的列索引
self.pen = turtle.Turtle()
self.pen.penup() # 抬笔,移动不画线
self.pen.speed(0) # 最快绘图速度
self.pen.goto(x, y) # 移动到指定坐标
self.pen.shape('circle') # 形状为圆形
self.pen.color((0.6, 0.6, 0.6))# 默认灰色(空位)
self.pen.onclick(self.on_click)# 绑定点击事件
✅ 考点:类的定义,__init__ 构造方法,self 的用法
6. 点击事件处理
def on_click(self, x, y):
global f
if game_over: return # 游戏结束后禁止点击
if data2[self.x][self.y] != 0: return # 已有棋子禁止点击
if f == 0: # 黑棋回合
self.pen.color((0, 0, 0))
data2[self.x][self.y] = 1
win(self.x, self.y, 1)
f = 1 # 切换到白棋
else: # 白棋回合
self.pen.color((1, 1, 1))
data2[self.x][self.y] = 2
win(self.x, self.y, 2)
f = 0 # 切换到黑棋
✅ 考点:事件绑定,全局变量修改,分支逻辑
7. 构建棋盘 + 启动主循环
# 创建5×5共25个棋子对象
for i in range(k):
for j in range(k):
data[i][j] = Fang(
-200 + i * 50, # x坐标:从-200开始,每格50px
200 - j * 50, # y坐标:从200开始,每格减少50px
i, j
)
# 进入事件循环,保持窗口不关闭
turtle.mainloop()
📐 棋盘坐标图示:
| (0,0) |
(1,0) |
(2,0) |
(3,0) |
(4,0) |
| (0,1) |
● |
|
|
(4,1) |
| (0,2) |
|
○ |
|
(4,2) |
| (0,3) |
|
|
|
(4,3) |
| (0,4) |
(1,4) |
(2,4) |
(3,4) |
(4,4) |
● 黑棋 | ○ 白棋 | 间距 50px
✅ 考点:坐标计算,嵌套循环,主循环写法
📝 完整可运行代码
import turtle
turtle.colormode(1)
turtle.bgcolor((0.8, 0.8, 0.8))
f = 0
k = 5
data = [[0 for _ in range(k)] for _ in range(k)]
data2 = [[0 for _ in range(k)] for _ in range(k)]
directions = [[(0, -1), (0, 1)], [(-1, 0), (1, 0)], [(-1, -1), (1, 1)], [(-1, 1), (1, -1)]]
game_over = False
def win(x, y, tk):
global game_over
for d in directions:
cnt = 1
tx, ty = x + d[0][0], y + d[0][1]
while 0 <= tx < k and 0 <= ty < k and data2[tx][ty] == tk:
cnt += 1; tx += d[0][0]; ty += d[0][1]
tx, ty = x + d[1][0], y + d[1][1]
while 0 <= tx < k and 0 <= ty < k and data2[tx][ty] == tk:
cnt += 1; tx += d[1][0]; ty += d[1][1]
if cnt >= 3: print(f"{tk}颜色胜利"); game_over = True; return True
return False
class Fang:
def __init__(self, x, y, i, j):
self.x = i; self.y = j
self.pen = turtle.Turtle()
self.pen.penup(); self.pen.speed(0); self.pen.goto(x, y)
self.pen.shape('circle'); self.pen.color((0.6, 0.6, 0.6))
self.pen.onclick(self.on_click)
def on_click(self, x, y):
global f
if game_over or data2[self.x][self.y] != 0: return
if f == 0: self.pen.color((0,0,0)); data2[self.x][self.y] = 1; win(self.x,self.y,1); f=1
else: self.pen.color((1,1,1)); data2[self.x][self.y] = 2; win(self.x,self.y,2); f=0
for i in range(k):
for j in range(k):
data[i][j] = Fang(-200 + i*50, 200 - j*50, i, j)
turtle.mainloop()
✍️ 高考模拟题(本题15分)
请修改上述代码,完成以下要求:
答案将在下期推送公布,欢迎在评论区提交你的解法~
本文由「信奥POCO」原创,专注浙江技术高考/C++算法竞赛内容,欢迎点赞/在看/转发,关注获取更多干货。