大作业实验报告¶
一 · 小组简介¶
小组成员¶
鲁嘉宁 2021201518 冯宵瑶 2021201516 冯锦程 2021201644
小组分工¶
本小组三位同学线上线下一起共同完成大作业三个阶段的实现
仓库链接¶
https://github.com/Fxy2021201516/Chinese_checkers.git
二 . 各阶段任务完成情况¶
第一阶段¶
- 实现多界面的呈现与切换
- 实现棋盘的呈现
- 实现棋子的呈现与移动
- 实现行棋的合法性的判断
第二阶段¶
- 服务端的窗口和相应的处理判断能力。包括:客户端进入房间的合法性、玩家姓名的合法性、行棋的合法性、终局的判断、排名的计算、轮空清空棋子。
- 客户端的窗口呈现和相应的移动能力。包括:显示时间、显示己方姓名、移动棋子并传输相应通信协议等。
- 服务端和客户端之间的通信建立
第三阶段¶
- 实现AI与单机模式之间随意切换,支持2、3人AI模式
附加功能¶
- 实现连跳展示路径
- 可查看任一方棋子上一步行棋路径
- 可实现人与AI对战
效果图展示¶




三 . 整体思路¶
第一阶段¶
- 定义QPushButton类为棋子

- 定义可点击区域vector

- 定义棋盘数组

- 通过鼠标点击事件来记录坐标与棋盘上的位置,从而使棋子可以移动

- 通过递归判断连跳是否合法

第二阶段¶
分别在客户端与服务端设置 receive 函数,判断接收到的信息并作出相应处理。
服务端¶
- 对各个协议的接受、发送、处理。
服务端判断移动是否合法,如不合法向客户端发送错误信息,使客户端撤销本次移动。
在服务端设置计时器,实现轮空判负功能,棋子中途轮空将直接被在棋盘上移除。

客户端¶
- 显示图形界面
- 对各个协议的接受、发送、处理。其中,客户端记录所有鼠标点击事件,记录坐标位置,并直接做出移动。若收到服务端的信息显示自己为非法移动,再进行撤销。

第三阶段¶
- 通过权值计算的方法,判断权值最大的移动即为AI应该作出的移动。
- 为棋盘设定初始的权值表,然后根据棋子在棋盘上的位置,调整每个棋子权值的占比。

- 遍历AI一方所有可能的移动方案,再以上述逻辑遍历AI所有对手可能的移动方案,之后再次对AI后一步的走法进行尝试。

- 综合考虑以上几步,按进攻、防守、搭桥分别计算得出权值。
- 总权值最大的即为AI所做的移动 。

四· 遇到的问题和解决方案¶
第一阶段¶
- 空指针: 以下问题:程序进入多人游戏时无窗口出现直接报错为“crash”
- 在遍历容器为每一个棋子设置槽函数时注意每方棋子在vector中和begin与end的位置关系
- 在生成棋盘时数学关系出错,导致在后面程序的运行中出现错误的对应关系,从而出现未被正确赋值的指针
- 数学关系逻辑问题: 棋盘上棋子不在正确位置
- 连跳不能正常进行,递归前记得初始化
第二阶段¶
- 棋子移动时未考虑棋子逻辑坐标与Qt的图形界面的交互. 移动棋子,有正确的玩家控制权轮换,对棋子移动的合法性判断也体现棋子已经完成移动,但是不显示棋子移动且被移动棋子原位置仍可点击(并且在点击后crash). 解决方法:在走棋时更改棋子作为一个按钮在界面上的位置信息(棋子继承
QPushButton类) - 与第一阶段程序的整合: 为了更好地联系第二阶段,我们对第一阶段的程序做了一定程度的修改,例如坐标系的建立方法、棋子坐标的改动、不同游戏人数的实现思路,在改动的同时,机械的复制粘贴就导致了很多的bug。比如,程序运行到
changeinfo时,总会报空指针的错误,原因是我们在复制粘贴时,搞错了两行代码的位置,把this->select指成了空指针。 - switch的case里不放break;while循环里没有放终止条件。所以我们调试的时候经常遇到意想不到效果……
第三阶段¶
- 不会记录路径:考虑每次都会覆盖上一次的路径。
- AI移动的方向不符合正常思维:权值设置不合理。
- AI棋子反复横跳:在设计AI判断和寻找路径的函数中,有一些范围和逻辑上的小错误,导致用到此部分是出现错误。
- 选择了正确的棋子并且算出了想去的位置,但是跳不过去:深度搜索时,flag设置成了局部变量,则每一次调用递归函数时都被赋予了新值。解决方法:设置为全局变量,并处理每次变化的逻辑关系。