JAVA五子棋实现问题(辛苦)
具体算法网上也有:
五子棋是一种广受大众喜爱的游戏。它的规则简单多样,很有趣味性和娱乐性。本文设计并实现了一个人机配对下的五子棋程序,采用博弈树方法,应用剪枝和最大最小树原理进行搜索,寻找下一个棋手的最佳位置。介绍了五子棋程序的数据结构、评分规则、胜负判定方法和搜索算法过程。
一.相关数据结构
关于磁盘情况的表示,当前磁盘情况以链表的形式表示,目的是让用户进行后悔、撤退等操作。
CList步骤列表;
阶梯结构表示为:
结构步骤
{
int m;//m,n表示两个坐标值。
int n;
char侧;//side表示下一个子节点。
};
以数组的形式保存当前磁盘,
目的是使用:
char FIVE area[FIVE _ MAX _ LINE][FIVE _ MAX _ LINE];
其中FIVE_MAX_LINE表示磁盘表面上的最大行数。
同时,由于递归搜索过程中需要考虑时间和空间的有效性,只找到当前情况下相对较好的几个磁盘,而不是搜索所有可以下载的位置。这里,变量CountList用于表示可以在当前搜索中选择的所有新磁盘状况对象的集合:
CList CountList
CBoardSituiton类是:
CBoardSituation类
{
CList步骤列表;//每个步骤的列表
char FIVE area[FIVE _ MAX _ LINE][FIVE _ MAX _ LINE];
结构步骤machineStep//机器的下一步
双值;//由此磁盘状态获得的分数
}
二、评分规则
对于夏紫的重要性分数,我们需要从六个位置来考虑当前的棋局,分别是:-,?,/,\,//,\\
其实要考虑一方在这六个位置上形成的棋子布局。对于棋子未放置后当前局势的得分,主要是为了说明该处棋子的重要性,设置了一个简单的规则向机器方表示当前棋面的得分。
基本规则如下:
判断是否可以5,如果是机器,给100000分,如果是人类,给-100000分;
判断自己能活4还是死4还是死4活3,如果是机器方给10000分,如果是人类方给-10000分;
判断是否变成了双职3,如果是机方给5000分,如果是人方给-5000分;
判断是死是活,如果是机器方给1000分,如果是人类方给-1000分;
判断能不能成功。4.如果是机器给500分,如果是人给-500分。
判断能否单人作业3,如果是机器给200分,如果是人类给-200分;
判断是否变成双职2,如果是机方给100分,如果是人方给-100分;
判断能不能成功。3.如果是机器给50分,如果是人给-50分。
判断是否可以结对工作2、如果是机器,给10分,如果是人类,给-10分;
判断能否存活2,如果是机器方给5分,如果是人类方给-5分;
判断能不能成功。2.如果是机方给3分,如果是人方给-3分。
实际上,目前的情况是按照上述规则的顺序来比较的。如果满足某个规则,则对该情况进行评分并保存,然后退出规则匹配。注意,这里的规则是对下棋一般规则的总结。在实际操作中,用户可以添加规则,修改评分机制。
第三,胜败判断
其实是根据最后一个玩家的现状来判断胜负的。其实需要从四个位置来判断,横线、竖线和分别为45度角和135度角的两条线,才能看出这四个方向的最后一个玩家是否构成了连续五个棋子,如果是,就说明这个游戏已经赢了。详情见下图:
第四,描述搜索算法的实现
注意下面核心算法中的变量currentBoardSituation,它代表当前机器的最新磁盘情况,CountList代表一级子节点可以选择的比较好的磁盘的集合。核心算法如下:
void MainDealFunction()
{
value =-MAXINT;//将值赋给初始根节点
CalSeveralGoodPlace(currentBoardSituation,count list);
//这个函数是根据当前的磁盘情况比较可以考虑的几个磁盘,根据实际的得分情况选择得分较高的几个磁盘,也就是说在选择一级节点的时候,利用贪婪算法直接找出相对得分较高的组成一级节点,以提高搜索速度,防止堆栈溢出。
pos=CountList。getheadsposition();
CBoardSituation * pBoard
for(I = 0;ivalue=Search(pBoard,min,value,0);
Value=Select(value,pBoard->;值,max);
//取值并将pboard->最大值赋给根节点。
}
for(I = 0;ivalue)
//找出哪个磁盘得分最高。
{
currentBoardSituation = pBoard
PlayerMode = min//当前子当事人变更为个人。
打破;
}
}
搜索函数的表示如下:其实核心算法是一个剪枝过程,其中四个相关参数分别是:(1)当前棋局;(2)当前孩子可以是机器(max)也可以是人(Min);(3)父节点oldValue的值;;(4)当前搜索深度。
双重搜索(CBoardSituation&
板,int模式,双旧值,int深度)
{
CList m _ DeepList
if(deptholdvalue))== TRUE)
{
if(模式= =最大值)
值=选择(值,搜索(后续
Board,min,value,depth+1),max);
其他
值=选择(值,搜索(后续
Board,max,value,depth+1),min);
}
返回值;
}
其他
{
if(goal(board)& lt;& gt0)
//这里的目标(棋盘)< & gt0表示可以决出胜负。
返回目标(板);
其他
返回翻译(板);
}
}
注意,这里的goal(board)函数是用来判断当前盘面的输赢的,而evlation(board)是从机器的角度来给当前盘面打分的。
下面是Select函数的介绍。这个函数的主要目的是根据PlayerMode返回节点的正确值,即机器或用户。
双重选择(双重a、双重b、int模式)
{
如果(a & gtb & & mode = = max)(a & lt;b && mode==min)
返回a;
其他
返回b;
}
动词 (verb的缩写)摘要
在Windows操作系统下,这个人机对战的五子棋程序是用VC++实现的。与国内很多只采用规则或简单递归而不剪枝的程序相比,在智能性和时间有效性上要优于这些程序。同时,所讨论的方法和设计过程为用户设计其他游戏(如象棋和围棋)提供了参考。
我发给你了。