五子棋设计思路文档
一、程序设计原理、目的以及算法
运用java swing和awt框架实现五子棋的绘图,按钮的事件响应等功能。主要分为三个类:主要UI类、棋子类、以及棋盘类。在原有的五子棋的基础上增加了四子棋和六子棋的扩展玩法,对于六子棋来说,玩家需要每人一次下两颗棋子,四子棋和五子棋的判定依据相同,增加娱乐性。
在算法方面主要有两个难点,第一,需要将棋谱的绘制坐标转化为基本的数据结构,例如棋子和网格交点的坐标均采用邻接矩阵的表示方式来存储。第二,五子棋的判定输赢的算法,即,横向扫描,竖向扫描,斜向扫描,其中,斜向扫描最为困难,需要将棋盘分为两个部分依次进行。具体的伪码描述如下:
输赢判断伪码描述:
for everychesses{
chessesare not null && chesses have played;
count++;
ifcount is 5, winner
}
棋子坐标转化为邻接矩阵的伪码描述:
forevery chesses{
chess[][].X ← X
chess[][].y ← Y
}
二、 程序的流程框图,以及UML图
主要UI的逻辑框图
后端算法实现的主要框图
这个设计采用了单一职责原则,将前端与后端的业务逻辑进行了分离,降低整个程序的耦合度,我们可以在以上的UML图中看到这个彼此的依赖关系。
三、算法的重难点
整个五子棋游戏在开发过程中遇到最为困难的是搭建基本数据结构的算法,判定输赢的算法,用户点击非网格处时,棋子自动修正至正确的位置上,涉及到对矩阵坐标的转换,以及对矩阵的遍历,尤其是矩阵的斜向遍历,以下就会通过源码分析的方式来进行解读。
1、 关于坐标转换矩阵的算法
我们知道,五子棋的棋盘是由若干的直线通过交错来进行绘制的,那么,每条直线的交点坐标之间应该具有一定的规律,这个交点的坐标可以用矩阵来保存,那么我们就能定义一个五子棋棋谱的行数、列数和行列之间的间隔差。
publicstaticfinalintMARGIN = 30; // 边距
publicstaticfinalintGRID_SPAN = 35; // 网络距离
publicstaticfinalintROW = 15; // 行数
publicstaticfinalintCOW = 15; // 列数
这我们能看到,我们定义了行数和列数,并且网络(格)距离我们也定义了,网络距离的数值是相对于容器的坐标,边距就是我们所谓的容器边缘的距离。
画出棋谱
//画出棋盘的横向线条
for(inti = 0 ;i <= ROW ;i++) {
g.drawLine(MARGIN,MARGIN +i * GRID_SPAN,MARGIN +COW *GRID_SPAN,MARGIN +i * GRID_SPAN);
}
//画出棋盘的纵向线条
for(inti = 0;i <= COW ;i++) {
g.drawLine(MARGIN +i * GRID_SPAN,MARGIN,MARGIN +i * GRID_SPAN,MARGIN +ROW