畅Chang的五子棋设计
一、功能介绍:
可以根据自己的需要选择游戏模式,是人人对战(没有实现网络版)还是人机对战,并且在需要的时候可以自行转换,可以撤销以前下过了棋。以及清空棋盘。
五子棋的效果图
黑棋获胜后效果图如下
二、主要技术分析
五子棋的设计时所用到的知识点其实与前面的画图板基本上是一样的,但是在算法上却要比画图板的要求高很多,以下我想就悔棋、重绘以及人机算法这一块做点分析。
(1)悔棋步骤主要采用的是int型队列来保存每个棋子所在位置的横纵坐标。
(2)在整个五子棋的设计当中,重绘在我的映像中十分的深刻,棋盘需要重绘,棋子需要重绘,背景图片需要重绘、每次悔棋之后整个界面需要重绘,连人机算法中都有重绘的问题(不知道是什么原因,但是当机器落子的时候必须重绘一次棋盘,否则会出现错误),因此,我们可以看出重绘的重要性了。
下面就是那段代码,请大家注意第三行,我为它哭泣了一个下午
graf.drawImage(WhiteChessImg.getImage(),x2-4,y2-6,null);
//白棋落子后,重绘一次窗体
cf.repaint();
//将标记数组的位置赋值
chessArr[pot[0]][pot[1]] = Config.CHESS_WHITE;
(3)人机对战的算法是另一个让我十分头疼的问题,主要找不到合适的突破口,不过最后我将判断输赢的算法做了一点修改,就用到人机对战上来了,程度虽然比较浅,但是还是能完成一些基本的堵棋功能。这个算法并不是采用全盘遍历的思想,而是以每个人下的棋子为原点来进行几个方向的搜索。其优点在于算法所花费的时间较少,但是正是因为如此,它比较难完成一些有深度的判断。
以横排检查为例来说明人机算法
/**
* 检查横排的情况
* @param num 当连得棋子数大于num时,机器人进行堵截
* @param x 传入当前人下的棋子的横坐标
* @param y 传入当前人下的棋子的纵坐标
* @return 返回机器人下子的位置值
*/
public int[] checkRow(int num , int x , int y){
//初始一个数组,值保存的是负数
int[] pot = {-1,-1};
//设置一个计数器
int count = 0;
int countLeft = 0;
int countRight = 0;
//往右边判断
for(int i = x+1 ; i <chessArr.length ; ++i){
if(chessArr[i][y] == chessArr[x][y])
countRight++;
else
break;
}
//往左边判断
for(int i = x ; i >= 0 ; i--){
if(chessArr[i][y] == chessArr[x][y])
countLeft++;
else
break;
}
//总的连子数等于左边与右边相加的和
count = countLeft+countRight;
//当总的连子数等于设定的数,那么找到要堵的位置
if(count == num){
if((x+countRight+1)<chessArr.length&&chessArr[x+countRight+1][y]==0){
//将一排黑棋右边的空位置返回
pot[0] = x+countRight+1;
pot[1] = y;
return pot;
}
else if((x-countLeft)>=0&&chessArr[x-countLeft][y]==0){
//将这牌黑棋左边的空位置返回
pot[0] = x-countLeft;
pot[1] = y;
return pot;
}
}else{
//如果这牌黑棋在横向被堵住了,那么返回初始值;
pot[0] = -1;
pot[1] = -1;
return pot;
}
return pot;
}
三、总结与希望
这个五子棋在很多地方还存在着问题:首先是人机对战上玩家只能选择黑子并且机器只具备堵棋的功能,其次,由于人机算法是自己设计的,很不成熟,在一些地方会存在小的漏洞。并且由于在网络方面没有修行,因此无法完成网络上的人人对弈。由于五子棋涉及到java中的许多基本知识点、简单的数据结构以及算法问题,那么我还会对这个小项目进行修改,以逐步完善它,并且希望在这个过程中巩固自己的基础知识,加强自己的算法设计能力以及用来学习以后的网络知识(当然,还有PS的能力,好多这上头的问题还是请同学帮解决的)。
五子棋的设计具有一定的挑战性,在设计中,遇到了很多需要解决的问题,比如说窗体的BorderLayout布局方式,组件字体的设置,背景颜色与前景颜色的区别,这些虽然没有讲到过,但是应该学会通过自己的能力去解决。还有就是必须加强算法的能力。总得来说我认识到,要学会将学过的东西作为工具去学习还不知道的知识,这样才能进步。同时也希望各位朋友能够多多指教,大家便可以共同学习,共同进步嘛,代码发在附件里面,有兴趣的朋友可以看一下,然后提些建议,方便以后改进。
上一篇: 五子棋