Ⅰ 五子棋的算法用哪种比较简单
可以采用这样的笨算法,运行起来慢点,但是很简单易懂,而且效果很好。如果能够加以优化,则其实是很好的算法:
1、首先遍历整个棋盘,找到一个可以落子的点,然后假设自己在该点落子,再然后判断如果棋子落到这个点上后会对自己有什么利益,比如会不会形成冲4活三、双活三等等,(事先将冲四活三、双活三等效果定义上利益值,当然,如果是五个子连起来了的话,利益值要被定义成最高,最好是无穷大的),将各种效果的利益值相加,得到己方的利益值。
2、将角色互换一下,重复第一步,得到对方的利益值(其实是递桂算法)。
3、将己方的利益值减去对方的利益值,得到该点的总利益值。
4、整个棋盘所有能落子的点都计算出利益值之后,找出利益值最大的那个点,将棋子落到该点。
当然,这个算法可以有很大程度的优化,比如,如果没有相邻的棋子,可以放弃该点。还有一旦找出可以胜利的点,就不再继续往下计算。。。。
模拟算法:
int liyi(角色, 层次)
{
if(层次=0)
return 0;
for(第一个可以落子的点 到 最后一个可以落子的点)
{
int 利益,最大利益;
//递桂...
利益 = 获取本角色利益值() - liyi(角色=相反角色,层次-1);
if(利益>最大利益)
{
最大利益 = 利益;
保存该点。
}
落子到所保存的点。
}
Ⅱ 求问五子棋AI算法思路
五子棋的核心算法
五子棋是一种受大众广泛喜爱的游戏,其规则简单,变化多端,非常富有趣味性和消遣性。这里设计和实现了一个人机对下的五子棋程序,采用了博弈树的方法,应用了剪枝和最大最小树原理进行搜索发现最好的下子位置。介绍五子棋程序的数据结构、评分规则、胜负判断方法和搜索算法过程。
一、相关的数据结构
关于盘面情况的表示,以链表形式表示当前盘面的情况,目的是可以允许用户进行悔棋、回退等操作。
CList StepList;
其中Step结构的表示为:
struct Step
{
int m; //m,n表示两个坐标值
int n;
char side; //side表示下子方
};
以数组形式保存当前盘面的情况,
目的是为了在显示当前盘面情况时使用:
char FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE];
其中FIVE_MAX_LINE表示盘面最大的行数。
同时由于需要在递归搜索的过程中考虑时间和空间有效性,只找出就当前情况来说相对比较好的几个盘面,而不是对所有的可下子的位置都进行搜索,这里用变量CountList来表示当前搜索中可以选择的所有新的盘面情况对象的集合:
CList CountList;
其中类CBoardSituiton为:
class CBoardSituation
{
CList StepList; //每一步的列表
char FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE];
struct Step machineStep; //机器所下的那一步
double value; //该种盘面状态所得到的分数
}
二、评分规则
对于下子的重要性评分,需要从六个位置来考虑当前棋局的情况,分别为:-,¦,/,\,//,\\
实际上需要考虑在这六个位置上某一方所形成的子的布局的情况,对于在还没有子的地方落子以后的当前局面的评分,主要是为了说明在这个地方下子的重要性程度,设定了一个简单的规则来表示当前棋面对机器方的分数。
基本的规则如下:
判断是否能成5, 如果是机器方的话给予100000分,如果是人方的话给予-100000 分;
判断是否能成活4或者是双死4或者是死4活3,如果是机器方的话给予10000分,如果是人方的话给予-10000分;
判断是否已成双活3,如果是机器方的话给予5000分,如果是人方的话给予-5000 分;
判断是否成死3活3,如果是机器方的话给予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; //对初始根节点的value赋值
CalSeveralGoodPlace(currentBoardSituation,CountList);
//该函数是根据当前的盘面情况来比较得到比较好的可以考虑的几个盘面的情况,可以根据实际的得分情况选取分数比较高的几个盘面,也就是说在第一层节点选择的时候采用贪婪算法,直接找出相对分数比较高的几个形成第一层节点,目的是为了提高搜索速度和防止堆栈溢出。
pos=CountList.GetHeadPosition();
CBoardSituation* pBoard;
for(i=0;ivalue=Search(pBoard,min,value,0);
Value=Select(value,pBoard->value,max);
//取value和pBoard->value中大的赋给根节点
}
for(i=0;ivalue)
//找出那一个得到最高分的盘面
{
currentBoardSituation=pBoard;
PlayerMode=min; //当前下子方改为人
Break;
}
}
其中对于Search函数的表示如下:实际上核心的算法是一个剪枝过程,其中在这个搜索过程中相关的四个参数为:(1)当前棋局情况;(2)当前的下子方,可以是机器(max)或者是人(min);(3)父节点的值oldValue;(4)当前的搜索深度depth。
double Search(CBoardSituation&
board,int mode,double oldvalue,int depth)
{
CList m_DeepList;
if(deptholdvalue))== TRUE)
{
if(mode==max)
value=select(value,search(successor
Board,min,value,depth+1),max);
else
value=select(value,search(successor
Board,max,value,depth+1),min);
}
return value;
}
else
{
if ( goal(board)<>0)
//这里goal(board)<>0表示已经可以分出胜负
return goal(board);
else
return evlation(board);
}
}
注意这里的goal(board)函数是用来判断当前盘面是否可以分出胜负,而evlation(board)是对当前的盘面从机器的角度进行打分。
下面是Select函数的介绍,这个函数的主要目的是根据 PlayerMode情况,即是机器还是用户来返回节点的应有的值。
double Select(double a,double b,int mode)
{
if(a>b && mode==max)¦¦ (a< b && mode==min)
return a;
else
return b;
}
五、小结
在Windows操作系统下,用VC++实现了这个人机对战的五子棋程序。和国内许多只是采用规则或者只是采用简单递归而没有剪枝的那些程序相比,在智力上和时间有效性上都要好于这些程序。同时所讨论的方法和设计过程为用户设计其他的游戏(如象棋和围棋等)提供了一个参考。
Ⅲ 五子棋游戏计算机采用哪些算法来确定胜负
明星局为斜指开局的第11局,其结论为:RIF规则下黑必胜。
明星开局属于分离型开局,故白4不易防黑的优势区,最好采用“牵制”的办法。即:H9,控制黑的一个活2,自己做一个活2,如下面图1。如果“跟随”防守,黑将会继续在下方扩大优势,如下面图2。
白4选择H9后,黑只好G9控制,如下面图1,这样黑既可以往下发展,也可以往左发展。
根据开局抢2原则,白6显然走I7,挡对面的活2,自己成活2。
由于白6形成了新的活2,黑又没有进攻可言,所以黑只能继续控制,I6,把局势继续往下拉。
黑7选择了I6,黑的连接点主要有G6和G8、F8。F8或G8是一个三通点,G6是活3点,所以G8要强于G6。本次我们讨论G6。由于G8和白棋靠的较近,所以F8更强一些。
此时白10可选择G8,断黑的一个活2,自己成一个活2。
但此时黑的活2比较多,攻势已经非常大,经过下面图1的进攻线路可以取胜。
望采纳,谢谢
Ⅳ C语言五子棋算法
五子棋胜负的判定,一般有一下两种算法:
1.扫描整个棋盘,分别扫描四个方向是否有5个连子。网上找了很多五子棋源码都是用此算法,这意味着每下一个棋子都要扫描一遍19×19的棋盘,复杂而且低效,代码略。
2.每下一字,从该子开始扫描其四个方向(例如:从该子的(x-4,y)坐标开始扫描横向)是否存在5个连子。此算法较为常用,而且不涉及更为复杂的数据结构。
另外,为解决扫描越界的问题,在声明棋盘棋子位置时,可声明一个(4+19+4)×(4+19+4)的棋盘,而让棋子偏移(4,4)个坐标。
算法2源代码如下:
? void IfWin(int x,int y,int color){ TCHAR win[20]; int a,b; if(stone[x][y]==1) wcscpy_s(win,_T("黑棋胜利!")); else wcscpy_s(win,_T("白棋胜利!")); for(a=x-4;a<=x+4;a++)//判断横 if(stone[a][y]==color&&stone[a+1][y]==color&&stone[a+2][y]==color&&stone[a+3][y]==color&&stone[a+4][y]==color) {MessageBoxW(Xqwl.hWnd,win,TEXT(""),MB_OK);return;} for(b=y-4;b<=y+4;b++)//判断竖 if(stone[x][b]==color&&stone[x][b+1]==color&&stone[x][b+2]==color&&stone[x][b+3]==color&&stone[x][b+4]==color) {MessageBoxW(Xqwl.hWnd,win,TEXT(""),MB_OK);return;} for(a=x-4,b=y-4;a<=x+4;a++,b++)//判断右斜 if(stone[a][b]==color&&stone[a+1][b+1]==color&&stone[a+2][b+2]==color&&stone[a+3][b+3]==color&&stone[a+4][b+4]==color) {MessageBoxW(Xqwl.hWnd,win,TEXT(""),MB_OK);return;} for(a=x-4,b=y+4;a<=x+4;a++,b--)//判断左斜 if(stone[a][b]==color&&stone[a+1][b-1]==color&&stone[a+2][b-2]==color&&stone[a+3][b-3]==color&&stone[a+4][b-4]==color) {MessageBoxW(Xqwl.hWnd,win,TEXT(""),MB_OK);return;}}
Ⅳ 求五子棋获胜的算法
在确认下子的同时,获取当前位置的坐标,然后分别从8个方向上计算属于同一个玩家的棋子,即左、右、上、下、左上、右下、右上、左下,只要有在同一直线上的两个方向上的棋子之和为5,就判断该玩家取得胜利。
/*输赢判断语句*/
winFail()
{
/*往左数*/
int k,l,count1=0,count2=0,count3=0,count4=0,count5=0,count6=0,count7=0,count8=0;
/*printf("%d",intX);*/
for(k=intX;k>0;k--)
if(point[k][intY]!=point[intX][intY]) break;
else
count1++;
/*往右数*/
for(k=intX;k<=N;k++)
if(point[k][intY]!=point[intX][intY]) break;
else
count2++;
/*左右相加*/
if(count1+count2-1==5) initial(point[intX][intY]);
/*printf("%d",count1+count2-1);*/
/*往上数*/
for(l=intY;l>0;l--)
if(point[intX][l]!=point[intX][intY]) break;
else
count3++;
/*往下数*/
for(l=intY;l<=N;l++)
if(point[intX][l]!=point[intX][intY]) break;
else
count4++;
/*上下相加*/
if(count3+count4-1==5) initial(point[intX][intY]);
/*往左上数*/
for(k=intX,l=intY;k>0,l>0;k--,l--)
if(point[k][l]!=point[intX][intY]) break;
else
count5++;
/*往右下数*/
for(k=intX,l=intY;k<=N,l<=N;k++,l++)
if(point[k][l]!=point[intX][intY]) break;
else
count6++;
/*右上左下相加*/
if(count5+count6-1==5) initial(point[intX][intY]);
/*往右上数*/
for(k=intX,l=intY;k<=N,l>0;k++,l--)
if(point[k][l]!=point[intX][intY]) break;
else
count7++;
/*往左下数*/
for(k=intX,l=intY;k>0,l<=N;k--,l++)
if(point[k][l]!=point[intX][intY]) break;
else
count8++;
/*右上左下相加*/
if(count7+count8-1==5) initial(point[intX][intY]);
}
Ⅵ 围棋(5子棋)是怎么下的 有几中算法
五子棋:只要你的棋子有五个是相连的(横、竖、斜着都行)就算赢了。
围棋:并不是光算棋子的数量,最终是要看你占的地盘的大小。算法有好几种(各个国家的算法都不太相同),具体你还是看书吧,讲的比较清楚。
Ⅶ 五子棋高级算法
基本算法:
采用博弈比较常用的策略。
计算机下子前,分别对玩家和电脑棋型进行评估,然后根据棋型对每一位置打分(玩家和电脑在同一点的分数不同),比如活三100分,冲四1000分等,然后根据每个落子点分数进行选择。采用极大极小值策略,进行多步计算。
-_-.........代码在文件夹chess里啊..........
一些可能有用的链接
http://topic.csdn.net/t/20001021/09/35626.html
http://..com/question/46388110.html?si=6