小小五子棋
前言
本次课程综合大作业由 3人小组协同完成,基于 Java 语言开发一款集人机智能对战、局域网双人联机对战于一体的多功能五子棋系统。项目综合运用Swing 图形界面、多线程并发、Socket 网络编程、文件 IO 数据持久化等课程核心知识点,严格采用分层模块化开发思想拆分代码,每位组员独立负责专属业务模块,降低代码耦合度,便于并行开发、调试与后期维护。 整篇博客完整覆盖项目背景、开发环境、整体架构、人员分工、核心功能实现、开发难题与解决方案、项目总结、后续拓展方案,结构完全贴合答辩汇报逻辑,朗读流畅、细节充足,能够完整向老师展示小组全部开发工作。
一、项目概述
1.1 项目开发背景
市面上基础单机五子棋程序功能单一,仅支持本地双人落子,缺少智能人机对手、远程联机互动功能,也不存在聊天交互、棋谱保存、限时落子、悔棋认输等配套辅助功能,游戏体验较差。 结合本学期 Java 课程所学知识,小组决定自主开发一套功能完整、交互完善的五子棋对战程序,弥补传统单机五子棋的功能缺陷。项目兼顾教学实践价值与游戏实用性,既完成课程技术要求,又具备完整的游戏交互逻辑。
1.2 项目开发核心目标
- 实现双对战模式:高难度加权 AI 人机对战、局域网 TCP 双人联机对战两大核心玩法;
- 完善对局交互功能:支持悔棋、主动认输、双向申请和棋、每回合 10 秒落子限时机制;
- 搭建联机社交模块:局域网实时文字聊天、玩家自定义昵称互通展示;
- 实现棋谱数据持久化:本地保存完整对局记录、支持历史棋谱加载与完整对局回放;
- 优化程序运行性能:使用多线程分离 UI 渲染、AI 计算、网络 IO 操作,解决界面卡顿、点击无响应问题;
- 保障程序稳定性:处理网络断连、跨线程 UI 报错、端口占用、数组越界等异常问题,增加容错弹窗提示;
- 规范化代码结构:分层架构拆分视图、数据模型、AI 算法、网络通信四层,职责单一,便于团队协作开发。
1.3 开发环境与完整技术栈
硬件环境
笔记本电脑,支持局域网 WiFi / 热点互联,满足双人联机测试需求。
软件环境
- 开发语言:Java SE 11
- 图形界面框架:Swing(JFrame、JPanel、JButton、JTextArea 等全套 Swing 组件)
- 网络通信技术:TCP Socket、Object 对象序列化传输
- 并发技术:Java 多线程 Thread、SwingUtilities UI 调度线程
- 文件 IO:BufferedReader、FileReader、File 读写本地 txt 文件
- 开发 IDE:IntelliJ IDEA
- 版本规范:统一驼峰命名、完整代码注释、统一通信指令常量
核心技术简要说明
- Swing:搭建可视化窗口,绘制棋盘、棋子、功能按钮、聊天输入框,监听鼠标点击落子事件;
- Socket TCP 通信:分为服务端(创建房间)、客户端(加入房间),基于端口 8888 建立长连接,通过 ObjectOutputStream/ObjectInputStream 序列化传输落子数据、控制指令、聊天文本;
- 多线程技术:独立子线程处理 AI 大量循环计算、网络消息持续监听,避免阻塞 Swing 主线程;
- 对象序列化:将 byte 数组、字符串、整型指令封装为 Object 对象跨设备传输,实现两端数据同步;
- 文件持久化:读取本地昵称库文件随机分配玩家昵称,本地存储每一步落子记录实现棋谱保存与回放;
- 分层架构设计:数据与视图完全分离,所有业务数据统一由 Model 层管理,视图层仅负责展示与用户交互。
1.4 系统全部功能详细总览
模块一:人机对战功能
- 智能 AI 自动落子算法,进攻 + 加权防守双维度打分,防守权重放大,AI 优先封堵玩家高威胁棋型;
- AI 独立子线程异步计算,搭配 800ms 模拟思考延迟,还原真人下棋逻辑;
- 人机对局完整操作:悔棋、重新开局、主动认输、超时自动判负;
- 落子后自动四向扫描五子连珠,AI 连成五子自动弹窗提示玩家失败。
模块二:局域网联机对战功能
- 两种联机模式:房主创建房间(启动 ServerSocket 服务端)、玩家输入 IP 加入房间(客户端 Socket);
- 全量数据实时同步:双方落子坐标、黑白棋回合状态、对局胜负状态两端同步更新;
- 双向互动交互:联机悔棋申请、同意 / 拒绝悔棋;双向发起和棋、同意 / 拒绝和棋;主动认输同步告知对手胜利;
- 玩家昵称互通:连接成功后自动向对方发送本机昵称,聊天框显示双方专属昵称;
- 实时联机聊天:任意一方发送文字消息,另一方聊天面板实时展示;
- 网络异常处理:断开连接自动弹窗提示,释放全部 Socket 与 IO 资源,避免端口占用。
模块三:对局辅助拓展功能
- 棋盘背景切换:一键切换多套棋盘背景图片,实时重绘界面;
- 10 秒落子倒计时:每回合重置计时,倒计时结束未落子直接判定本局失败;
- 棋谱管理系统:对局结束保存完整落子记录;加载本地历史棋谱;完整回放整盘对局落子步骤;
- 全局对局控制:一键清空棋盘重新开局、对局结束锁定棋盘禁止落子;
- 消息提示弹窗:所有操作反馈、对局结果、网络异常、线程异常均提供可视化弹窗提示。
模块四:底层数据支撑功能
- 15*15 标准二维数组存储棋盘全部棋子状态,区分空点位、黑棋、白棋;
- 落子队列集合存储每一步落子数据,支持撤销上一步落子(悔棋);
- 预设全套五子棋棋型模板库与梯度威胁分值,支撑 AI 打分与胜负判定;
- 棋盘副本复制机制,AI 推演打分使用临时棋盘,不污染实时对局数据;
- 通用五子连珠判定方法,任意坐标落子后自动检测横、竖、两条对角线四向连续棋子。
二、系统整体分层架构与模块文件划分
本项目严格采用四层分层架构,每层职责完全独立,模块间仅通过暴露公共方法交互,无硬耦合代码。
2.1 四层架构详细介绍
第一层:视图层 View(用户可视化交互入口)
负责窗口展示、画面绘制、鼠标监听、按钮点击事件,用户所有操作均在视图层触发,分为两个核心类:
- MainFrame.java:程序顶层主窗口,全局总控制器;组员 1 独立开发
- ChessPanel.java:棋盘专属绘图画布,鼠标落子监听;组员 2 独立开发
第二层:数据模型层 Model(全局数据中枢)
统一存储程序所有静态、动态数据,封装数据读写、逻辑计算方法,所有视图、AI、网络模块均调用 Model 获取数据,实现数据与界面解耦;核心类 GobangModel.java,组员 3 独立开发。
第三层:AI 算法层 AI(人机对战智能逻辑)
封装五子棋博弈打分算法,独立完成棋盘遍历、棋型识别、最优落子点位筛选;核心类 AI.java,组员 3 独立开发。
第四层:网络通信层 Net(局域网数据传输)
拆分发送、接收两大逻辑:
- 消息发送逻辑:封装在 MainFrame 视图层(组员 1),点击按钮后向对手发送各类指令;
- 消息接收逻辑:独立后台监听线程 ReceiveThread.java(组员 3),持续读取对手传输的数据并分发处理。
2.2 模块间数据依赖流向
- 视图层 MainFrame、ChessPanel 依赖 Model 层、AI 层、网络接收线程;
- AI 层仅依赖 Model 层获取棋盘数据;
- 网络接收线程 ReceiveThread 依赖视图层、Model 层完成界面刷新与数据更新;
- Model 层不依赖任何上层模块,完全独立,所有数据自主管理。
| 分层名称 | 文件路径 | 开发成员 | 模块核心职责 | 对外提供公共接口 |
| 视图层 View | com.gobang.view.MainFrame.java | 闫溪玥 | 1. 程序入口、主窗口布局、所有功能按钮事件分发2. 联机客户端 / 服务端创建、网络输出流管理、各类对战指令发送3. 读取昵称文件、随机分配本机昵称、昵称同步协议封装4. 全局 10 秒落子计时器启停重置管理5. 聊天面板管理、聊天消息收发展示6. 网络 Socket/IO 资源统一释放 | 1.setEnemyNick () 更新对手昵称 2.appendChatText () 追加聊天记录3.resetChessTimer () 重置倒计时 4.startChessTimer () 开启倒计时 5.stopChessTimer () 停止倒计时 6.closeOnlineSocket () 释放网络资源 |
| 视图层 View | com.gobang.view.ChessPanel.java | 陆梅婷 | 1. 重写绘图方法,绘制棋盘网格、棋子、切换背景图2. 鼠标监听,像素坐标转棋盘逻辑点位、落子合法性校验3. 人机模式自动调用 AI 落子、联机发送落子数据4. 管理对局状态(对局结束标记、黑白落子回合)5. 棋谱保存、加载、完整对局回放功能6. 持有网络输出流,处理和棋、悔棋回复发送 | 1.reInit () 重置清空棋盘 2.getModel () 获取底层数据模型 3.playBack () 回放棋谱 4.loadGameRecord () 加载历史棋谱 5.repaint () 刷新棋盘画面 |
| 数据模型层 Model | com.gobang.model.GobangModel.java | 孙孟婷 | 1. 定义棋盘尺寸、空棋、黑棋、白棋、胜负全局常量2.15*15 二维数组存储所有棋盘点位状态3. 落子队列保存全部落子记录,支撑悔棋功能4. 内置棋型库、棋型对应威胁分值数组5. 悔棋撤销、四向五子连珠胜负判定算法6. 复制棋盘副本,供 AI 推演打分使用 | 1.setChessmanArray () 设置棋子2.getChessmanArray () 获取棋盘数组3.getChessmanArrayCopy () 获取棋盘副本4.repeatOperation () 执行悔棋5.automatic () 胜负判定6.getModelLibrary () 获取棋型模板7.modelScore 棋型分值数组 |
| AI 算法层 AI | com.gobang.ai.AI.java | 孙孟婷 | 1. 独立子线程异步计算 AI 最优落子,800ms 模拟思考延迟2. 全棋盘空位遍历,进攻 + 3.2 倍加权防守打分3. 四方向 5 格窗口匹配棋型,计算点位威胁分值4. 筛选综合最高分坐标作为 AI 落子点5. 落子后更新棋盘、自动判定 AI 胜利弹窗提示 | 1.chessForMachine () 触发 AI 自动落子 |
| 网络通信层 Net | com.gobang.net.ReceiveThread.java | 孙孟婷 | 1. 后台独立线程持续阻塞监听对手网络消息2. 区分 byte [] 落子、字符串指令、整型状态三类消息解析3. 处理昵称同步、联机悔棋、双向和棋、聊天、胜负同步逻辑4.Swing 多线程安全处理弹窗、界面更新5. 捕获网络断连异常,终止监听线程 | 无对外主动调用接口,后台自动运行,内部调用 Model、MainFrame、ChessPanel 接口 |
三、小组人员分工详细说明
3.1 分工设计核心原则
- 分层拆分任务,每人负责完整独立业务模块,不存在多人共用同一类代码,答辩可清晰区分每个人工作量;
- 底层数据模型、AI 算法、网络接收逻辑交由同一组员开发,统一数据格式、通信指令,避免模块对接格式不匹配;
- 顶层主窗口、棋盘画布拆分两名组员开发,分离全局控制与画面渲染工作;
- 开发前期小组统一规范:方法命名、代码注释、网络传输指令字符串、全局常量,提前对齐对接标准;
- 开发流程:并行编码→单模块自测→模块联调→全局功能测试→BUG 协同修复→功能迭代补充。
3.2 各组员完整工作内容
闫溪玥:顶层主窗口 MainFrame.java(视图层全局控制器)
- 程序程序入口 main 方法开发,采用 SwingUtilities 安全 UI 线程启动窗口,规避 Swing 启动异常;
- 主窗口基础属性初始化:窗体标题、窗口尺寸、关闭策略、屏幕居中、BorderLayout 边界布局;
- 页面整体布局搭建:划分中央棋盘显示区域、右侧功能按钮面板、底部聊天交互面板,设置组件间距、尺寸、边框;
- 10 个功能按钮创建、布局、绑定点击监听器,统一分发全部按钮点击事件:回放对局、加载历史棋谱、切换背景、悔棋、人机对战、联机对战、重新开局、申请和棋、认输、发送聊天;
- 联机对战发送端全套逻辑开发:
- 区分创建房间(启动 ServerSocket,监听 8888 端口等待客户端接入)、加入房间(输入局域网 IP 创建 Socket 连接服务端);
- 创建 ObjectOutputStream 序列化输出流,封装全部发送指令:NICK 昵称同步、REPEAT 悔棋、DRAW_APPLY 和棋申请、GIVE_UP 认输、普通聊天文本;
- 玩家昵称系统完整实现:
- 文件 IO 读取 res/nickname.txt 昵称库,文件不存在 / 读取失败弹出提示框;
- 随机从昵称库选取本机昵称,联机连接成功后自动发送本机昵称给对手;
- 对外提供 setEnemyNick () 接口,供网络接收线程同步更新对手昵称;
- 全局 10 秒倒计时 Timer 计时器封装,编写 start、stop、reset 三套接口,供棋盘面板、网络接收线程调用;
- 聊天系统顶层管理:聊天输入框、聊天展示文本域初始化;封装 appendChatText () 方法统一追加聊天记录,区分本地消息、联机消息;
- 网络资源统一释放工具方法 closeOnlineSocket ():依次关闭输出流、客户端 Socket、服务端 ServerSocket,清空全局网络对象,解决切换模式端口占用问题;
- 模块对接工作:初始化棋盘面板 ChessPanel、绑定 AI 实例、启动网络接收线程,为其他模块提供全局公共调用接口。
陆梅婷:棋盘画布 ChessPanel.java(视图层绘图与鼠标交互)
- 画布基础初始化:注入全局数据模型 GobangModel、AI 智能实例、主窗口引用;
- 重写 paintComponent 绘图核心方法,完整绘制:棋盘边框、15*15 网格线、黑色 / 白色棋子、自定义背景图片;
- 鼠标监听事件开发:捕捉鼠标点击坐标,将屏幕像素坐标换算为棋盘逻辑点位,校验点位是否为空、是否为本回合落子方、对局是否结束;
- 落子逻辑处理:校验通过后调用 Model 层存储棋子,保存落子记录,自动调用 AI 落子(人机模式)、发送落子数据给对手(联机模式);
- 多套棋盘背景切换功能:缓存多张背景资源,切换后调用 repaint () 实时重绘画布;
- 对局状态全局变量管理:towardsWin 标记对局是否结束、blackTurn 标记当前落子方(黑棋 / 白棋),锁定结束棋盘禁止鼠标落子;
- 棋谱全套业务逻辑开发:
- 缓存对局全部落子步骤,对局结束写入本地文件保存棋谱;
- 读取本地棋谱文件,解析落子数据加载至棋盘;
- 回放功能:清空棋盘,按顺序复现每一步落子,还原完整对局;
- 联机网络输出流持有:存储 ObjectOutputStream,接收和棋、悔棋指令时向对手发送回复消息;
- 对外工具接口封装:reInit () 清空棋盘重置对局、getModel () 获取数据模型、playBack () 回放棋谱、loadGameRecord () 加载历史棋谱;
- 联调对接:接收主窗口按钮指令、接收网络线程同步的对手落子数据,调用 repaint 刷新棋盘画面。
孙孟婷:数据模型 GobangModel + AI 算法 AI.java + 网络接收线程 ReceiveThread.java
子模块 1:底层数据模型 GobangModel
- 定义全局静态常量:棋盘尺寸 15、空棋子标识、黑棋标识、白棋标识、对局胜利 / 运行状态常量;
- 15*15 二维 byte 数组 chessmanArray 创建,封装 set、get 方法读写棋盘点位数据;
- 落子队列 ArrayList<byte []> chessQueue:存储每一步落子坐标与颜色,实现悔棋数据支撑;
- 预设棋型库 String [] modelLibrary、对应威胁分值 int [] modelScore:包含活四、冲四、活三、眠三、活二全部棋型模板,用于 AI 打分;
- 悔棋核心方法 repeatOperation ():移除队列最后一步落子,清空棋盘对应坐标棋子;
- 五子连珠自动判定方法 automatic ():以落子点位为中心,横向、纵向、主对角线、副对角线四向统计连续同色棋子,连续达到 5 颗返回对应棋子胜利标识;
- 棋盘副本复制 getChessmanArrayCopy ():拷贝完整棋盘二维数组,供 AI 推演打分使用,不修改真实对局数据。
子模块 2:人机智能 AI AI.java
- 构造方法注入数据模型与棋盘画布,持有全局棋盘数据与界面刷新引用;
- 四方向扫描数组 dirArr 定义,覆盖横、竖、两条对角线全部判断方向;
- 对外入口方法 chessForMachine ():供棋盘面板、主窗口调用启动 AI 落子计算;
- 异步 AI 思考子线程开发:所有棋盘遍历、打分循环放入独立 Thread,添加 800ms 休眠模拟 AI 思考;捕获线程中断异常并弹窗提示;
- 全棋盘空位遍历方法 traverseAllChessPoint ():双层循环遍历 15*15 所有坐标,跳过已有棋子点位;分别计算进攻分数、加权防守分数,综合对比筛选最高分最优落子点;防守权重设置 3.2,优先拦截玩家高威胁棋型;
- 单点威胁分值计算 getPointThreatScore ():复制临时棋盘模拟落子,以目标点位截取前后两格组成 5 格判断窗口,拼接字符串匹配预设棋型库,累加对应威胁分值;
- AI 落子后业务流程:更新 Model 棋盘数据、调用画布重绘、执行五子连珠判定,AI 胜利时修改对局结束状态并弹出提示弹窗。
子模块 3:网络消息接收线程 ReceiveThread.java
- 继承 Thread 创建独立后台监听线程,构造方法注入 Socket、棋盘面板、主窗口、数据模型,初始化 ObjectInputStream 输入流;
- 重写 run () 核心线程方法,死循环阻塞读取对手序列化消息,无消息时线程休眠不占用 CPU 资源;
- 多类型消息分流解析逻辑:(1) byte [] 字节数组:解析对手落子 x、y 坐标与棋子颜色,写入本地棋盘、存入落子队列、重置倒计时、自动判胜负;(2)String 字符串指令:区分 NICK 昵称同步、TURN_CHANGE 回合切换、OPPONENT_WIN 对手胜利、REPEAT 悔棋申请、DRAW_APPLY 和棋申请、DRAW_AGREE 同意和棋、DRAW_REFUSE 拒绝和棋、普通聊天文本;(3)Integer 整型指令:区分 WIN 对局胜利、RUNNING 重新开局全局状态指令;
- 全套联机交互逻辑处理:同步对手昵称并更新聊天面板、弹窗确认悔棋 / 和棋申请、两端同步对局胜负状态;
- Swing 多线程安全处理:所有弹窗、修改界面控件代码全部包裹 SwingUtilities.invokeLater (),提交至 UI 主线程执行,杜绝跨线程操作 Swing 组件报错;
- 全局异常捕获机制:捕获 IO 读取、对象反序列化全部异常,弹窗提示断开连接,跳出循环终止监听线程,防止程序卡死;
- 辅助工具方法 handleGameCommand ():统一处理整型对局全局状态指令,重置棋盘、停止计时器、弹窗提示对局结果;
- 模块对接:调用 Model 层更新棋盘数据、调用主窗口操作聊天面板与倒计时、调用 ChessPanel 刷新棋盘画面。
| 成员 | 负责全部文件 | 核心开发功能清单 | 对接其他组员模块 | 输出公共接口 |
| 闫溪玥(组员一) | com.gobang.view.MainFrame.java | 1. 程序入口开发,Swing 安全线程启动主窗口,完成窗口基础属性与整体布局搭建2. 10 个功能按钮创建、布局与统一点击事件分发,覆盖全部对局操作3. 局域网联机发送端全逻辑:服务端创建房间、客户端加入房间、Socket 通信流管理4. 自定义通信协议,封装昵称同步、悔棋、和棋、认输、聊天全量发送指令5. 玩家昵称系统:读取本地昵称库、随机分配本机昵称、联机昵称同步协议6. 全局 10 秒落子倒计时封装,提供启停重置全接口7. 聊天系统顶层管理,聊天面板初始化、消息追加与展示8. 网络资源统一释放方法,解决端口占用、连接泄漏问题 | 1. 组员 2:ChessPanel.java 棋盘面板,初始化注入、接收按钮操作指令2. 组员 3:ReceiveThread.java 网络接收线程,启动线程、同步昵称与聊天消息3. 组员 3:GobangModel.java 数据模型,读取全局常量、对局状态4. 组员 3:AI.java 人机 AI 实例,初始化注入、触发 AI 落子 | 1. setEnemyNick () 更新对手昵称2. appendChatText () 追加聊天记录3. resetChessTimer () 重置倒计时4. startChessTimer () 开启倒计时5. stopChessTimer () 停止倒计时6. closeOnlineSocket () 释放网络资源 |
| 陆梅婷(组员二) | com.gobang.view.ChessPanel.java | 1. 棋盘画布初始化,注入数据模型、AI 实例、主窗口引用2. 重写 paintComponent 绘图方法,完整绘制棋盘网格、棋子、自定义背景3. 鼠标监听开发,像素坐标转棋盘逻辑点位、落子合法性校验4. 落子全流程处理:写入模型、保存落子记录、触发 AI 落子 / 联机发送落子数据5. 棋盘背景切换功能,缓存背景资源、实时重绘画面6. 对局状态管理:对局结束标记、黑白落子回合锁定7. 棋谱全功能开发:对局记录缓存、本地保存、历史加载、完整回放8. 联机网络输出流持有,处理和棋、悔棋回复指令发送 | 1. 组员 1:MainFrame.java 主窗口,接收按钮操作指令、调用全局计时器2. 组员 3:GobangModel.java 数据模型,读写棋盘数据、执行悔棋、胜负判定3. 组员 3:AI.java 人机 AI,触发 AI 自动落子4. 组员 3:ReceiveThread.java 网络接收线程,接收对手落子数据、刷新棋盘 | 1. reInit () 重置清空棋盘2. getModel () 获取底层数据模型3. playBack () 回放棋谱4. loadGameRecord () 加载历史棋谱5. repaint () 刷新棋盘画面 |
| 孙孟婷(组员三) | 1. com.gobang.model.GobangModel.java2. com.gobang.ai.AI.java3. com.gobang.net.ReceiveThread.java | 【GobangModel】1. 定义棋盘尺寸、空棋、黑棋、白棋、胜负全局常量2. 15*15 二维数组存储棋盘状态,封装读写方法3. 落子队列实现,支撑悔棋功能4. 内置棋型库与对应威胁分值数组5. 悔棋撤销、四向五子连珠胜负判定算法6. 棋盘副本复制方法,供 AI 推演使用【AI.java】1. 独立子线程异步计算 AI 落子,800ms 模拟思考延迟2. 全棋盘空位遍历,进攻 + 3.2 倍加权防守打分3. 四方向 5 格窗口匹配棋型,计算点位威胁分值4. 筛选最优落子点,落子后更新棋盘、自动判胜弹窗【ReceiveThread.java】1. 后台独立线程持续监听对手网络消息2. 三类消息分流解析:落子 byte 数组、控制指令字符串、对局状态整型3. 昵称同步、联机悔棋、双向和棋、聊天、胜负同步全逻辑处理4. Swing 多线程安全处理,所有界面更新使用 UI 调度线程5. 网络异常捕获,断连自动弹窗、终止监听线程 | 1. 组员 1:MainFrame.java 主窗口,调用聊天、计时器、昵称接口2. 组员 2:ChessPanel.java 棋盘面板,刷新棋盘画面、更新对局状态 | 【GobangModel】1. setChessmanArray () 设置棋子2. getChessmanArray () 获取棋盘数组3. getChessmanArrayCopy () 获取棋盘副本4. repeatOperation () 执行悔棋5. automatic () 胜负判定6. getModelLibrary () 获取棋型模板7. modelScore 棋型分值数组【AI.java】1. chessForMachine () 触发 AI 自动落子【ReceiveThread.java】无对外主动调用接口,后台自动运行 |
3.3 小组完整协同开发流程
- 需求分析阶段:全体组员共同梳理项目功能清单,确定人机、联机两大核心玩法,划分四层架构;
- 规范统一阶段:小组协商统一网络通信指令、全局常量、代码注释格式、方法命名规则,避免后期对接格式冲突;
- 并行开发阶段:组员 1 开发主窗口与联机发送逻辑、组员 2 开发棋盘绘图与鼠标交互、组员 3 同步开发底层 Model、AI 算法、网络接收线程,三人同步编码,互不干扰;
- 单模块自测阶段:每位组员完成自身模块后,独立测试全部功能,排查自身代码 BUG;
- 模块联调阶段:整合视图、模型、AI、网络四大模块,测试人机对战、联机对战完整流程,统一解决模块对接报错;
- 功能迭代补充:小组讨论新增认输、昵称同步、10 秒倒计时拓展功能,分配对应组员完成开发;
- 全局综合测试:全员循环测试全部功能场景,覆盖人机对局、联机双人对局、棋谱保存回放、聊天交互、断连异常等全部情况;
- 最终优化整理:统一完善全部代码注释,优化弹窗提示文案,修复剩余细微逻辑缺陷。
四、核心功能模块详细实现原理
4.1 底层数据模型 GobangModel 实现原理
Model 层作为项目数据核心,做到数据与界面完全分离,视图仅做展示,所有修改棋盘、存储落子、胜负判断逻辑全部封装在此类中。
- 棋盘存储:使用 byte [15][15] 二维数组,0 代表空位置、1 代表黑棋(玩家)、2 代表白棋(AI / 对手),读写棋盘统一调用 setChessmanArray 方法,禁止视图层直接操作数组;
- 落子记录:ArrayList 集合存储每一步 byte [] 数组,数组内依次存放 x 坐标、y 坐标、棋子颜色,悔棋时直接移除集合最后一个元素,同步清空棋盘对应点位;
- 棋型打分体系:将五子棋常见威胁棋型转为数字字符串模板,例如活三、冲四对应不同高分,AI 遍历点位时匹配字符串即可快速获取威胁分值,简化算法复杂度;
- 胜负判定逻辑:落子后向四个方向循环延伸,统计同色连续棋子数量,任意方向连续棋子等于 5,直接返回胜利棋子标识,上层视图接收后结束对局。
4.2 人机 AI 加权博弈算法实现原理
本项目 AI 区别于简单随机落子,采用进攻防守双重加权评分算法,难度更高,具备主动拦截玩家威胁棋型的能力。
- 临时棋盘推演机制:每次计算点位分数前复制完整棋盘数组,在临时数组模拟落子打分,不会修改当前正在进行的对局数据;
- 双重分值计算:(1)进攻分:模拟 AI 白棋落在该点位,计算该点位能形成的全部威胁分值;(2)防守分:模拟玩家黑棋落在该点位,计算玩家威胁分值,乘以 3.2 权重放大防守优先级;
- 综合得分 = 进攻分数 + 加权防守分数,遍历全部空位后选取总分最高坐标作为 AI 落子点;
- 多线程优化:AI 遍历 15*15 棋盘包含大量双层循环、四方向字符串匹配,计算耗时较长,放入独立子线程异步执行,不会阻塞界面按钮、鼠标操作。
4.3 局域网 Socket 联机通信实现原理
项目 TCP 通信分为发送、接收两端解耦开发,基于对象序列化实现跨设备复杂数据传输。
发送端(组员 1 MainFrame)
- 端口固定 8888,分为服务端、客户端两种角色:(1)服务端(创建房间):启动 ServerSocket 阻塞等待客户端连接,接入成功后创建双向 IO 流;(2)客户端(加入房间):输入房主局域网 IP,主动创建 Socket 连接对应端口;
- ObjectOutputStream 负责序列化对象发送,支持发送三类数据:byte [] 落子数组、String 控制指令、Integer 全局状态;
- 每一个交互按钮绑定对应发送逻辑,点击后自动封装指令并调用 flush () 强制推送消息,保证对手实时接收。
接收端(组员 3 ReceiveThread)
- 独立后台线程持续循环读取输入流消息,程序运行全程监听对手数据;
- 使用 instanceof 判断传输对象类型,分流至落子处理、指令处理、全局对局状态处理三大分支;
- 所有界面修改操作全部使用 SwingUtilities.invokeLater,将 UI 操作交给 Swing 专属绘制线程执行,规避多线程并发修改组件抛出的运行时异常;
- 完整交互链路: 1)连接成功双方互发昵称; 2)任意一方落子,发送 byte 数组同步坐标; 3)发起悔棋 / 和棋,发送对应字符串指令,接收方弹窗确认后发送回复指令; 4)一方认输、五子连珠胜利,发送对局结束指令,两端同步锁定棋盘。
4.4 图形视图两层协同实现原理
视图层拆分为 MainFrame 全局窗口与 ChessPanel 棋盘画布,分工明确,互不冗余:
- MainFrame:只管理窗口布局、按钮事件、网络发送、聊天、计时器等全局控制逻辑,不参与棋盘绘制;
- ChessPanel:只负责棋盘、棋子、背景绘制、鼠标点击落子,不管理全局按钮与网络连接;
- 两层通过对象引用互相调用公共接口,落子、悔棋、切换背景、回放棋谱等操作统一调用 repaint () 方法触发画布重绘,实时更新画面;
- 联机模式下 ChessPanel 持有网络输出流,处理和棋、悔棋回复时向对手发送反馈指令,完成双向交互闭环。
4.5 拓展辅助功能实现细节
(1)10 秒落子倒计时
通过 Swing Timer 定时器每 1 秒递减计时数值,数值存储在 MainFrame 全局变量,棋盘绘制时实时渲染剩余时间;倒计时归零时停止计时器,弹窗提示超时失败,锁定对局结束。
(2)认输双向同步
人机对局:点击认输直接弹窗提示 AI 获胜; 联机对局:点击认输后本地判定对局结束,同时向对手发送 GIVE_UP 指令,对手接收后弹窗提示我方认输胜利。
(3)和棋双向交互流程
- 我方点击申请和棋,向对手发送 DRAW_APPLY;
- 对手接收指令弹出确认框,选择同意 / 拒绝;
- 对手选择同意,发送 DRAW_AGREE,两端同步判定平局;
- 对手选择拒绝,发送 DRAW_REFUSE,我方弹窗提示申请被拒,对局继续。
(4)棋谱保存与回放编辑CSDN同步助手
对局结束时循环读取落子队列,将每一步坐标写入本地 txt 文件;回放时读取文件解析全部落子数据,清空棋盘后按顺序复现所有落子步骤,完整还原对局全过程。
五、项目核心亮点
结合小组完成的全部代码实现功能,本项目相比简易单机五子棋存在多处设计与功能亮点,也是本次课程大作业核心加分点:
- 分层低耦合模块化架构设计项目划分为视图层、数据模型层、AI 算法层、网络通信层四层,数据与界面完全解耦。Model 统一管理所有棋盘数据,视图仅负责页面渲染,AI、网络模块仅依赖基础数据接口,模块独立开发、单独调试,多人并行开发无代码冲突,后期维护、新增功能成本极低。
- 多线程异步解耦,解决 Swing 界面卡顿痛点将 AI 大量循环计算、网络消息监听全部放置独立子线程执行,UI 主线程只负责画面刷新。同时严格遵循 Swing 线程安全规范,所有界面更新操作使用
SwingUtilities.invokeLater(),彻底规避后台线程操作组件导致的程序崩溃、报错问题,程序运行流畅无卡顿。 - 高智能加权防守 AI 博弈算法AI 采用进攻 + 加权防守双维度打分机制,防守权重设置 3.2,AI 会主动优先封堵玩家四、三等高威胁棋型,AI 难度更高,游戏可玩性更强;计算时使用棋盘副本推演,不会污染真实对局数据,逻辑稳定无 BUG。
- 完整闭环局域网双人联机交互体系基于 TCP Socket + 对象序列化实现局域网联机,区分服务端创建房间、客户端加入房间双模式;自定义完整通信指令协议,实现昵称互通、实时聊天、联机悔棋、双向和棋、认输同步、落子实时同步全套交互逻辑,两端对局状态完全一致。
- 完善的对局辅助与容错机制内置 10 秒落子倒计时超时判负、棋盘背景切换、棋谱保存 / 加载 / 回放、对局重新开局功能;同时覆盖文件读取失败、网络断开、端口占用、线程中断等各类异常,全部搭配弹窗友好提示,程序容错性强,不易崩溃。
- 规范团队协同开发规范开发前期统一全局常量、网络传输指令、代码注释、命名规范;按模块精准拆分分工,每人负责独立完整类文件,无交叉冗余代码,开发流程标准化,便于版本管理与 Git 提交迭代。
六、开发过程难点、问题与完整解决方案
难点 1:AI 棋盘大量循环计算阻塞 Swing 界面
问题描述
15*15 棋盘双层循环遍历 + 四方向 5 格窗口字符串匹配,单次 AI 计算存在上千次循环操作,若直接在 Swing 主线程执行,会导致窗口卡死、按钮点击无响应、鼠标落子失效,严重影响程序使用体验。
解决方案(组员 3 独立完成)
创建独立子线程承载全部 AI 打分、遍历逻辑,主线程仅负责触发 AI 计算、等待线程完成后刷新棋盘画面;线程内添加 800ms 休眠模拟 AI 思考效果,既解决卡顿问题,又提升游戏真实感;同时捕获线程中断异常,异常时弹窗提示用户。
难点 2:多线程并发修改 Swing 组件,抛出线程安全异常
问题描述
网络接收线程、AI 子线程属于自定义后台线程,直接调用 JOptionPane 弹窗、修改聊天文本域、修改画布状态时,Swing 底层会抛出 IllegalThreadStateException 跨线程异常,程序直接崩溃。
解决方案(组员 3 独立完成)
严格遵循 Swing 单线程绘制规范,所有弹窗、修改界面控件、修改文本内容的代码全部封装在 SwingUtilities.invokeLater () 中,将 UI 操作任务提交至 Swing 专属 UI 调度线程执行,彻底消除跨线程报错。
难点 3:联机对战双方玩家昵称无法同步展示
问题描述
最初版本仅本地随机生成昵称,连接后对手无法获取我方昵称,聊天框只显示空白标识,双人联机交互辨识度低。
解决方案(组员 1、组员 3 协同完成)
- 组员 1 在客户端、服务端连接成功后,自动发送 NICK: 自定义前缀 + 本机昵称字符串指令;
- 组员 3 在 ReceiveThread 中判断字符串以 NICK: 开头,截取真实昵称,调用 MainFrame 提供的 setEnemyNick 接口更新全局对手昵称;
- 接收聊天消息时,读取全局对手昵称拼接聊天内容展示,实现两端昵称互通。
难点 4:网络异常断开后 Socket、IO 资源未释放,端口持续占用
问题描述
联机过程强制关闭窗口、断开 WiFi、退出房间时,Socket 套接字、ObjectOutputStream 未正常关闭,再次创建房间会提示 8888 端口被占用,无法开启服务端。
解决方案(组员 1 独立完成)
封装统一资源释放方法 closeOnlineSocket (),切换人机模式、断开连接、关闭窗口时自动执行;依次关闭输出流、客户端 Socket、服务端 ServerSocket,清空全局网络对象变量,彻底释放端口与 IO 资源,杜绝端口占用问题。
难点 5:联机悔棋、和棋双向交互逻辑复杂,两端对局状态不一致
问题描述
仅单方发送申请指令,缺少对方回复反馈逻辑,会出现一方同意悔棋另一方棋盘未撤销、一方同意和棋另一方未判定平局,两端对局状态不同步 BUG。
解决方案(组员 3 独立完成)
设计完整闭环指令交互链路:
- 发起方发送申请指令;
- 接收方弹窗选择操作,向对方发送同意 / 拒绝回复指令;
- 两端同时执行对应逻辑,同步修改棋盘、对局结束状态、刷新界面,保证双人画面完全一致。
七、项目整体总结与小组开发收获
7.1 项目完成情况总结
本项目完整落地前期全部开发需求,成功实现高难度人机 AI 对战、局域网双人联机对战两大核心玩法,配套完成聊天交互、自定义昵称、悔棋、认输、双向和棋、10 秒限时落子、背景切换、棋谱保存回放全套辅助功能。 代码严格采用四层分层模块化架构,四人小组分工清晰,每位组员独立完成专属模块,模块间接口规范、低耦合,程序具备完善异常容错机制,无严重崩溃、卡顿、数据不同步等致命 BUG,功能完整性、程序稳定性均达到课程大作业考核标准。
7.2 个人技术能力提升总结
- 熟练掌握 Swing 完整图形界面开发流程,理解窗口、画布、组件布局、鼠标事件监听底层实现逻辑;
- 吃透 TCP Socket 网络编程原理,掌握服务端 / 客户端创建、长连接通信、Object 对象序列化传输、IO 流资源管理;
- 深刻理解 Java 多线程并发开发核心要点,掌握异步线程分离耗时操作、Swing 线程安全处理方案;
- 建立分层架构开发思维,学会拆分视图、数据、算法、通信模块,实现数据与界面解耦;
- 掌握简单博弈 AI 开发思路,理解棋型威胁权重、棋盘推演打分算法设计逻辑;
- 熟练使用文件 IO 完成本地数据持久化,实现文本文件读取、数据保存功能;
- 大幅提升团队协同开发能力,学会统一代码规范、模块对接、协同排查联调 BUG。
7.3 项目可优化拓展方向
- 网络功能升级:搭建多人联机大厅,支持多组玩家同时双人对局,不再限制单房间;支持公网端口映射,实现外网远程联机;
- AI 算法升级:引入蒙特卡洛博弈树、极大极小值算法,进一步提升 AI 智能程度;增加多难度 AI 切换(简单 / 普通 / 困难);
- 账号积分系统:新增本地账号登录、对局积分存储、胜负战绩统计功能;
- UI 界面美化:替换原生 Swing 简陋按钮,使用图片自定义组件、美化弹窗样式、增加对局背景音乐;
- 数据存储升级:将棋谱、玩家积分从 txt 文本迁移至轻量数据库,实现数据长期管理;
- 拓展对战规则:新增禁手规则,贴合专业五子棋竞赛标准。
小小五子棋视频演示
