4.3 胜负判断条件 要判断四个方向,横向、竖向、以及2个斜向。思想还是比较简单,相同颜色连成五子即胜利,网上有些网友评论说完整的判断胜负条件包括连五和活四,我觉得完全没必要,活四还要检查两边的棋子,虽然运算量不大,但五子棋的标准就是连五即胜,一步之差,我们既要遵守规则,也要简化代码实现尽完整的功能。 http://www.paper51.com 我们要事先建立一个盘面数组board[ ][ ],即棋型表,数组的每一个元素对应棋盘上的一个交叉点,用‘0’表示空位,‘1’表示黑棋,‘2’表示白棋。由于代码太多,下面给出了一般状况的判断胜负函数,及以坐标(x,y)为中心的9X9矩形,只能在棋盘的内部,如果超过棋盘,就要另外考虑。下面的代码就是一般情况,整个矩形在棋盘内部的时候的判断胜负条件,如图14。 copyright paper51.com copyright paper51.com 图14 获胜 内容来自论文无忧网 www.paper51.com 胜负判断条件以下给出了X方向的代码: paper51.com protectedboolean judge(int x,int y,int clr){ http://www.paper51.com inti=0,j=0,count=0; copyright paper51.com // x方向 paper51.com for(i=0,count=0;x-i>=0&&i<5;i++){ paper51.com if (clr==board[x-i][y]){ 内容来自论文无忧网 www.paper51.com count++; 内容来自www.paper51.com } 内容来自论文无忧网 www.paper51.com
else{ 内容来自论文无忧网 www.paper51.com break; http://www.paper51.com } copyright paper51.com // System.out.println("("+x+" , "+y+" )"+"count = "+count); 内容来自论文无忧网 www.paper51.com if(count==5) copyright paper51.com return true; 内容来自www.paper51.com } 内容来自www.paper51.com for(i=1;x+i<15&&i<5;i++){ copyright paper51.com
if(clr==board[x+i][y]){ paper51.com count++; paper51.com }else{ 内容来自www.paper51.com break; http://www.paper51.com } 内容来自论文无忧网 www.paper51.com
if(count==5) paper51.com return true; http://www.paper51.com } 内容来自www.paper51.com return false; 内容来自论文无忧网 www.paper51.com
} paper51.com
为保证公平,先下子的就有禁手。但是我们一般没有这个规则限制,都是轮流先下子。理论上是这样的。但很多专家表明,先下子有很大的几率获胜,即使有禁手,先下子的一方还是有很大的优势,我觉得对于我们一般玩家而言,这些规定可以不考虑。 内容来自www.paper51.com
判断胜负的不管是单机还是玩家相互游戏,都必须开服务端,因为判断胜负是放在里面的。如果有一方获胜,弹出提示框,如果确认则清空棋盘继续新游戏。 paper51.com public void getVictory(Message msg){ http://www.paper51.com
JOptionPane.showMessageDialog(null, http://www.paper51.com "You Win The Game", 内容来自www.paper51.com
"Congratulations", copyright paper51.com JOptionPane.INFORMATION_MESSAGE); http://www.paper51.com //继续新游戏 内容来自www.paper51.com label3.setText("Player2"); http://www.paper51.com newGame(); 内容来自论文无忧网 www.paper51.com
} http://www.paper51.com
需要注意的一点是落下的棋子如果离任何一方的边界小于4,则以边界为限制判断是否有一方获胜,这样的话也要考虑多种方向,但原理还是和基本情况是一样的。 paper51.com 4.4 网络对战 copyright paper51.com 这部分也属于网络套接字编程的经典应用,根据服务器地址连接特定端口。 内容来自论文无忧网 www.paper51.com 网络部分很简单,但是我也做出了自己的特色,就是事件处理,做工可根据具体情况修改,虽然没有多少实用价值,但是也尽量使程序留有扩展性。下面给出了Message的代码。 copyright paper51.com /** copyright paper51.com * 消息列表 copyright paper51.com * type = 1 // 请求连接, msg = 连接者名字 内容来自www.paper51.com * type = 2 // 放棋子 http://www.paper51.com * type = 3 // 请求和其他人游戏 内容来自www.paper51.com * type = 4 // 拒绝游戏请求 copyright paper51.com
* type = 5 // 同意请求 内容来自论文无忧网 www.paper51.com * type = 6 // 发送胜利消息 http://www.paper51.com * type = 7 // 断开连接请求 内容来自www.paper51.com * type = 8 // 保存游戏,但是不放在磁盘上,在下一局开始时将会丢失 内容来自www.paper51.com * type = 9 // 添加新的玩家到所有客户端的玩家列表 paper51.com * type = 10// 响应信息 type ==1 paper51.com * type = 11// 和玩家游戏,msg 保存玩家的名字 ,创建游戏的玩家设置游戏 http://www.paper51.com * type = 12//信息设置 copyright paper51.com * type = 13// 设置玩家颜色 paper51.com * type = 14// msg= 接受请求的一方设置 http://www.paper51.com
* type = 15// 服务端更新信息 内容来自www.paper51.com * type = 16// 发送控制或错误信息 内容来自www.paper51.com * type = 17// 游戏失败 内容来自论文无忧网 www.paper51.com * type = 18// 服务端套接字关闭 copyright paper51.com * type = 19// 玩家结束游戏及更新 http://www.paper51.com
* tyep = 20// 电脑获胜/ 玩家获胜 内容来自论文无忧网 www.paper51.com
*/ http://www.paper51.com SOCKET监听端口,如果有玩家则更新玩家列表,如果双击除自己以外的玩家,则可以开始游戏,发送游戏请求,如果同意则返回棋子颜色并开始游戏,同时清空玩家列表。每一下子,把坐标传给服务端,并在2端显示出来,并且判断胜负。如果,有一方获胜,则提示消息通知双方,确定则继续开始新游戏。 paper51.com
服务端开启服务监听线程和客户端,如图15,如果有玩家知道服务器IP地址,即可选择在线玩家进行联网游戏,如图16。 内容来自www.paper51.com
内容来自论文无忧网 www.paper51.com
http://www.paper51.com
内容来自论文无忧网 www.paper51.com
双击除自己以外的一个玩家,发出游戏请求,同时要确定自己棋子的颜色,用MSG发回服务端。如果被拒绝,则返回原来的状态。 paper51.com
if(msg.color==1){ http://www.paper51.com ss = new String("white"); 内容来自www.paper51.com bpanel.setColor(2); 内容来自www.paper51.com } http://www.paper51.com
else{ paper51.com
ss = new String("black"); 内容来自论文无忧网 www.paper51.com
bpanel.setColor(1); 内容来自www.paper51.com
} 内容来自论文无忧网 www.paper51.com
http://www.paper51.com
内容来自www.paper51.com
图16 邀请游戏 内容来自论文无忧网 www.paper51.com
4.5 电脑AI 内容来自论文无忧网 www.paper51.com 广义上来讲,博弈是指在一定的环境条件和一定的规则约束下,依靠自己所能够掌握的信息,从各自选择的行为或是策略进行选择并加以实施,并从各自取得相应结果或收益的过程。冯·诺伊曼(John von Neumann,1903-1957)和摩根斯坦恩(Oskar Margenstern,1902-1977)在1944年出版了《博弈论与经济行为》(Theory of Games and Economic Behavior)一书中,最早地提出了关于博弈论的概念。但是,对于非合作、纯竞争型博弈,诺伊曼所解决的只有二人零和博弈。在这里所抽象化后的博弈问题是,已知参与者集合(两方),策略集合(所有棋着),和盈利集合(赢子输子),最终是想去找到一个理论上的解或平衡,也就是对参与双方来说都最合理、最优的具体策略。 paper51.com 而在这里狭义的讲,博弈论主要是研究棋手们落子中理性化、逻辑化的部分,并将其系统化为一门科学。换言之,博弈就是研究个体如何在错综复杂的相互影响中得出最合理的策略,博弈论正是衍生于古老的游戏或曰博弈如象棋、扑克等。数学家们将具体的问题抽象化,通过建立自完备的逻辑框架、体系研究其规律及变化。 copyright paper51.com 参考了很多五子棋算法,大部分思想差不多,就是搜索估值确定重要性,然后选取最大的一个点下子。具体做法如下:为电脑和玩家各建立一张表,用来存放棋型数据,比如“20”代表“冲四”的点,用“15”代表“活三”的点,那么在计算重要性时,就可以根据20>15得出前者比后者重要,下子时电脑便会自动选择“冲四”的点,这里还要说明一点的事,还要考虑四个方向。因为有可能有复合棋型,比如“四三”..从第一步起,不管是哪一方下子,电脑都有以这点为中心搜索9X9的矩阵内的所有空白点上棋子的重要性,一颗棋子对棋型影响的大小有9X9。重要看来虽然说进攻和防守的重要性一样的,但是我认为防守更重要。 内容来自www.paper51.com 在估值的时候,必须要考虑棋子的合法落子情况。不同的棋类博弈,其估值必定有极大的差别,各种因为规则而造成的不同因素影响估值的设计。不同的棋类游戏各有所谓的规则,规则中就有博弈双方都可以走哪些着法。某些博弈游戏很容易就找到合理着法,我所实现的五子棋,它就具有很简单的落子规则,即棋盘上所有的空位都可以落子,它们都是合理的着法。但是有些棋类游戏,比如在中国象棋和国际象棋中,情况就有些复杂了,每个棋子都有它特定的着法, copyright paper51.com |