zoukankan      html  css  js  c++  java
  • java 五子棋之人机对战思路详解

        最近做了五子棋,记录下自己完成五子棋的人机对战的思路。


        首先,思路是这样的:每当人手动下一颗棋子(黑子)的时候,应当遍历它周围棋子的情况,并赋予周围棋子一定的权值,当在机器要下棋子(白子)守护之前,会遍历整个棋盘的权值情况(棋盘的权值存在一个二维数组中),从中找出权值最大的点坐标,并下子(白子)。


        这样的话,问题就集中在两个方面了,一个是:如何遍历黑子周围的棋子情况? 另一个是:如何设定权值?


        首先,是设定权值。这个没有固定的设定方案,可以先试着设定,然后,尝试效果后(主要是白子的攻防情况是否合理),再调整。

        以下是我的设定方案:


       


        接着,是相对困难的部分,就是如何遍历黑子周围的棋子情况。 从之前权值方案中可以看到,设置权值的一个很重要的目的是为了进行防守,所以应当在连续黑子的两端(下面图中的橙色区域)设置权值,这样就有利于白子填充在连续黑子的两端,从而达到防守的目的,下面这张图可以说明:

        

        中心的黑子:表示当前所下的黑子,周围的棋子表示是之前下的。

        红色箭头:表示需要遍历的八个方向,因为中心黑子的坐标(i, j)是已知的,所以很容易得到周围的棋子坐标(i+n, j+m)

        橙色方框:表示连续黑子的末端,可能是空白(表示还没有棋子填充),也可能是白子。


        接着是算法思想:

        首先,应当先判断敌方棋子(黑子)第一次下的时候(敌方棋子先下),此时,周围八个棋子都是空的,于是应当对周围八个点赋予相同的权值(活一),当遍历整个棋盘后,便在这八个点中随机选择一个(用随机数),填上黑子。


        接着,敌方继续下子,如果敌方当前所下棋子与之前的棋子连续,则会构成活二或者眠二(以此类推,会构成活三眠三~~,这时,根据权值表,会赋予周围棋子更大的权值(权值应当是累加的,也就是说,当前权值 += 之前权值),最后遍历后,下白子。




  • 相关阅读:
    PureBasic 打开一个一行有多个数据的文件并读取其中某个数据
    正则表达式的30分钟教程
    【编程珠玑】读书笔记 第一章 开篇
    while ((ch = getchar()) != EOF)中ch定义为char还是int型?cin、scanf等如何结束键盘输入
    itoa函数的实现(不同进制)
    atoi函数的实现(考虑不同进制、溢出)
    函数重载二义性:error C2668: 'pow' : ambiguous call to overloaded function
    strcat与strncat的C/C++实现
    strcpy函数的C/C++实现
    strlen的C/C+++实现
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3177668.html
Copyright © 2011-2022 走看看