zoukankan      html  css  js  c++  java
  • 【设计】五子棋设计数据结构

    五子棋数据结构的分析与设计

    对于棋盘内每一个格子,可能的结果有三种 黑子 白子 无子

    而对于每一个棋子的信息可以分为 棋子的颜色 棋子的位置(横坐标与纵坐标)

    根据博弈树算法,我们在每一步(每一个棋子)都需要对其价值(权重)进行分析 因此还需保存当前棋的得分。

    对于棋子的得分,我们根据以下评判规则


    最常见的基本棋型大体有以下几种:连五,活四,冲四,活三,眠三,活二,眠二

    ①连五:顾名思义,五颗同色棋子连在一起,不需要多讲。
    图2-1

    ②活四:有两个连五点(即有两个点可以形成五),图中白点即为连五点。
    稍微思考一下就能发现活四出现的时候,如果对方单纯过来防守的话,是已经无法阻止自己连五了。
    图2-2


    ③冲四:有一个连五点,如下面三图,均为冲四棋型。图中白点为连五点。
    相对比活四来说,冲四的威胁性就小了很多,因为这个时候,对方只要跟着防守在那个唯一的连五点上,冲四就没法形成连五。
    图2-3 图2-4 图2-5


    ④活三:可以形成活四的三,如下图,代表两种最基本的活三棋型。图中白点为活四点。
    活三棋型是我们进攻中最常见的一种,因为活三之后,如果对方不以理会,将可以下一手将活三变成活四,而我们知道活四是已经无法单纯防守住了。所以,当我们面对活三的时候,需要非常谨慎对待。在自己没有更好的进攻手段的情况下,需要对其进行防守,以防止其形成可怕的活四棋型。
    图2-6 图2-7

    其中图2-7中间跳着一格的活三,也可以叫做跳活三。

    ⑤眠三只能够形成冲四的三,如下各图,分别代表最基础的六种眠三形状。图中白点代表冲四点。眠三的棋型与活三的棋型相比,危险系数下降不少,因为眠三棋型即使不去防守,下一手它也只能形成冲四,而对于单纯的冲四棋型,我们知道,是可以防守住的。
    图2-8 图2-9 图2-10

    -11 图2-12 图2-13

    如上所示,眠三的形状是很丰富的。对于初学者,在下棋过程中,很容易忽略不常见的眠三形状,例如图2-13所示的眠三。

    温馨提示:学会判断一个三到底是活三还是眠三是非常重要的。所以,需要好好体会。
    后边禁手判断的时候也会有所应用。

    ⑥活二:能够形成活三的二,如下图,是三种基本的活二棋型。图中白点为活三点。
    活二棋型看起来似乎很无害,因为他下一手棋才能形成活三,等形成活三,我们再防守也不迟。但其实活二棋型是非常重要的,尤其是在开局阶段,我们形成较多的活二棋型的话,当我们将活二变成活三时,才能够令自己的活三绵绵不绝微风里,让对手防不胜防。
    图2-14 图2-15 图2-16

    ⑦眠二:能够形成眠三的二。图中四个为最基本的眠二棋型,细心且喜欢思考的同学会根据眠三介绍中的图2-13找到与下列四个基本眠二棋型都不一样的眠二。图中白点为眠三点。
    图2-17 图2-18
    图2-19 图2-20


    判断是否构成眠二

    判断是否构成眠三

    判断是否构成冲四

    判断是否构成活二

    判断是否构成活三

    判断是否构成活四

    判断是否连五

     实际上对当前的局面按照上面的规则的顺序进行比较,如果满足某一条规则的话,就给该局面打分并保存,然后退出规则的匹配。注意这里的规则是根据一般的下棋规律的一个总结,在实际运行的时候,用户可以添加规则和对评分机制加以修正。

    因此设计如下数据结构

    #define GRID_NUM    15 //每一行(列)的棋盘交点数
    #define GRID_COUNT  225//棋盘上交点总数
    #define BLACK        0 //黑棋用0表示
    #define WHITE        1 //白棋用1表示
    #define NOSTONE     '+'  //没有棋子
    //这组宏定义了用以代表几种棋型的数字
    #define STWO        1  //眠二
    #define STHREE        2  //眠三
    #define SFOUR        3  //冲四
    #define TWO        4  //活二
    #define THREE        5  //活三
    #define FOUR        6  //活四
    #define FIVE        7  //五连
    #define NOTYPE        11 //未定义
    #define ANALSISED   255//已分析过的
    #define TOBEANALSIS 0  //已分析过的
    //这个宏用以检查某一坐标是否是棋盘上的有效落子点
    #define IsValidPos(x,y) ((x>=0 && x<GRID_NUM) && (y>=0 && y<GRID_NUM)
    //定义了枚举型的数据类型,精确,下边界,上边界
    enum ENTRY_TYPE{exact,lower_bound,upper_bound};
    //哈希表中元素的结构定义
    typedef struct HASHITEM
    {
    __int64 checksum;         //64位校验码
    ENTRY_TYPE entry_type;//数据类型
    short depth;         //取得此值时的层次
    short eval;         //节点的值
    }HashItem;
    
    typedef struct Node
    {
    int x;
    int y;
    }POINT;
    
    //用以表示棋子位置的结构
    typedef struct _stoneposition
    {
    unsigned char x;
    unsigned char y;
    }STONEPOS;
    
    typedef struct _movestone
    {
    unsigned char nRenjuID;
    POINT ptMovePoint;
    }MOVESTONE;
    //这个结构用以表示走法
    
    typedef struct _stonemove
    {
    STONEPOS StonePos;//棋子位置
    int Score;         //走法的分数
    }STONEMOVE;
    
  • 相关阅读:
    Effective C++ 读书笔记(3544):继承关系与面向对象设计
    《全景探秘游戏设计艺术》读后感之引子
    Effective C++ 读书笔记(1117):构造析构和赋值函数
    Effective C++ 读书笔记(2934):类与函数之实现
    Unity中使用PersistentDataPath加载文件
    打开本地【C】【D】【E】驱动器时候提示 X:\ 找不到应用程序
    C#进制转换
    在VS里编辑unity代码调用系统方法不显示中文注释或英文注释
    Spreadsheet说明
    C#中删除控件的事件的方法类.
  • 原文地址:https://www.cnblogs.com/KID-XiaoYuan/p/6417537.html
Copyright © 2011-2022 走看看