基于Python的Tkinter五子棋游戏开发指南
本文详解使用Python内置tkinter与numpy模块构建本地双人五子棋的完整流程。内容覆盖600×600画布初始化、15×15标准棋盘绘制、鼠标点击坐标网格化映射、黑白交替落子逻辑,以及基于四方向连续计数的胜负判定算法。附带修正边界条件的可运行源码,适合Python初学者实践图形界面与基础游戏交互逻辑。
开发准备与核心设计思路
在五子棋的程序设计中,明确规则边界是编写代码的前提。本实现采用简化通用规则:对局双方各执一色,空棋盘开局,黑先白后交替落子。棋子一旦放置即固定位置,不可移动或撤销。本文暂不实现“PASS权”与黑方禁手(如三三、四四、长连),聚焦于底层UI渲染、坐标拾取与基础胜负逻辑的实现。
整体架构分为三个核心阶段:
- 界面渲染层:利用
tkinter.Canvas建立坐标系,通过循环绘制15条横线与15条竖线,并计算天元及星位的偏移量。 - 交互控制层:捕获鼠标左键点击事件,将像素坐标转换为矩阵索引
(i, j),校验该交叉点是否已被占用,并根据全局计数器动态切换黑白两色。 - 逻辑判定层:以落子点为原点,沿水平、垂直及两条对角线四个轴向进行双向扩散扫描。当累计同色棋子数达标时触发获胜弹窗。
第1步:创建主窗口与绘制标准棋盘
程序启动需实例化根窗口,并配置一个尺寸为 600×600 像素的画布作为游戏区域。棋盘由 15 行 15 列的直线交叉构成。为保证视觉居中,起点坐标预留 20 像素边距,网格间距设定为 40 像素。通过双重循环分别调用 w1.create_line() 绘制纵向与横向网格线,随后按数学公式计算出 5 个星位黑点的矩形框坐标,使用 w1.create_oval() 填充显示。

# 引入必要的绘图模块
from tkinter import *
root = Tk() # 创建主窗口
root.title("Python五子棋游戏") # 设置窗口标题
w1 = Canvas(root, width=600, height=600, background='lightcyan')
w1.pack() # 启用默认布局管理
# 绘制15x15网格线(起始偏移20,间距40)
for i in range(0, 15):
w1.create_line(i * 40 + 20, 20, i * 40 + 20, 580)
w1.create_line(20, i * 40 + 20, 580, i * 40 + 20)
# 绘制五个星位交点
star_points = [
(135, 135, 145, 145), (135, 455, 145, 465),
(465, 135, 455, 145), (455, 455, 465, 465),
(295, 295, 305, 305)
]
for coords in star_points:
w1.create_oval(*coords, fill='black')
第2步:绑定点击事件与网格坐标映射
玩家下棋依赖于精确的像素到逻辑坐标的转换。当鼠标点击画布时,回调函数接收 event 对象获取 event.x 和 event.y。由于棋子实际绘制在交叉点圆心,需在半径范围内容差匹配。代码通过遍历 i 和 j 计算点击点到各交叉点 (20+40*i, 20+40*j) 的欧氏距离平方,若小于等于 20^2*2(容差阈值),则锁定对应网格行列。
落子逻辑依赖两个状态矩阵:A 记录点位占用情况(0为空,1为已占),B 存储棋子颜色属性('b'黑/'w'白)。利用整型变量 num 的奇偶性控制交替出子。每次成功落子后更新矩阵状态,并通过 w1.create_oval() 绘制实色圆形棋子。

import numpy as np
import tkinter.messagebox as msgbox
num = 0 # 全局步数计数器
A = np.full((15, 15), 0) # 占用标记矩阵
B = np.full((15, 15), '') # 颜色标识矩阵
def callback(event):
global num, A
# 查找最近的网格交点 (i, j)
found_i, found_j = 0, 0
for j in range(15):
for i in range(15):
dx = event.x - (20 + 40 * i)
dy = event.y - (20 + 40 * j)
if dx**2 + dy**2 <= 2 * 20**2:
found_i, found_j = i, j
break
if found_i != 0 or found_j != 0: break
# 校验空位并交替落子
if A[found_i][found_j] == 0:
color = 'black' if num % 2 == 0 else 'white'
char_code = 'b' if num % 2 == 0 else 'w'
w1.create_oval(40*found_i+5, 40*found_j+5,
40*found_i+35, 40*found_j+35, fill=color)
A[found_i][found_j] = 1
B[found_i][found_j] = char_code
num += 1
第3步:四方向扫描与五连珠判定
胜负检测是核心算法。选定落子点后,定义四个基础方向向量:水平向左 [-1, 0]、左上对角线 [-1, 1]、垂直向上 [0, 1]、右上对角线 [1, 1]。针对每个方向执行两次单向扫描:
- 正向延伸:沿向量方向递增索引,累加同色棋子,直到越界或遇到异色/空位停止。
- 反向回溯:从当前点沿相反方向递减索引累加,原理相同。
注意原稿中边界判断 x + a > 0 会导致索引 0 被误判越界。此处修正为 >= 0 且 < 15 以确保全范围覆盖。单次扫描包含落子点自身,故正反向计数之和 count1 + count2 实际多算了一次落子点,判定条件设为 == 6 等效于五子连珠。满足条件则弹出 messagebox 提示获胜方。

# 胜负判定逻辑嵌入callback末尾
directions = [[-1, 0], [-1, 1], [0, 1], [1, 1]]
for dx, dy in directions:
cx, cy = found_i, found_j
c1, c2 = 0, 0
# 正向扫描
while B[cx][cy] == B[found_i][found_j]:
c1 += 1
nx, ny = cx + dx, cy + dy
if 0 <= nx < 15 and 0 <= ny < 15 and B[nx][ny] == B[found_i][found_j]:
cx, cy = nx, ny
else: break
# 反向扫描
while B[cx][cy] == B[found_i][found_j]:
c2 += 1
px, py = cx - dx, cy - dy
if 0 <= px < 15 and 0 <= py < 15 and B[px][py] == B[found_i][found_j]:
cx, cy = px, py
else: break
if c1 + c2 == 6:
winner = "黑棋" if B[found_i][found_j] == 'b' else "白棋"
msgbox.showinfo("游戏结束", f"{winner}获胜!")
return # 判定成功后终止本轮逻辑
w1.bind("<Button-1>", callback)
# 退出按钮与主循环
u = Button(root, text="退出", width=10, height=1, command=root.quit, font=('楷体', 15))
u.pack()
root.mainloop()
常见问题排错与建议
- 坐标吸附不准:若发现棋子无法落在最近交叉点,检查容差公式中的半径值是否与棋盘缩放比例匹配。
- 边界索引报错 IndexError:部分旧版代码直接使用
> 0判断下限,在 Python 列表中会跳过第 0 行/列。务必统一使用0 <= index < 15规范边界拦截。 - 资源释放:Windows/Linux 下直接关闭 Tkinter 窗口即可,若需平滑退出建议将
command=root.destroy替代quit以清理系统句柄。
总结
本文通过模块化拆解,演示了如何利用 Python 基础库快速实现具有完整交互反馈的五子棋对局原型。掌握网格坐标映射算法与多向扫描判定逻辑后,开发者可进一步扩展悔棋功能、AI 对手接入或网络联机协议。以上就是基于Python实现五子棋游戏开发的详细内容,更多关于Python游戏开发与桌面应用设计的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













