• 人机博弈-吃子棋游戏(二)算气


    算法步骤例如以下。输入计算棋气的起始子。检查我方棋子其周边的空白,并查看此空白是否已经计算过气了。假设没有计算过气加一,假设已经计算则略过。进而递归调用计算我方棋子上下左右子的气,最后算法会返回棋串的子数和气数。算法凝视十分详尽。

    这个计算棋子气的算法,參考http://www.cnblogs.com/tuanzang/archive/2013/02/27/2935861.html,结合我们自身的应用须要优化和改动。这篇博文介绍了很多其它关于围棋的算法,有兴趣的朋友能够进一步阅读。

    原文suanqi函数会反复计算已经计算过的棋串效率不高。应该对已经算过气的函数不在反复算气。而且我们须要知道棋串的长度。


    #include <iostream>
    #include <utility>
    
    #define EDGE 19
    int go[EDGE][EDGE];//棋盘数据,0为黑棋。1为白棋。2为空白
    int gokong[EDGE][EDGE]; //0=该空点未曾计算过气,1=已计算。避免反复计算公气
    int gozi[EDGE][EDGE]; //0=该子未计算串气。1=已计算。避免反复计算同一个子的气
    int goqi; //此棋串气数
    int goziLength;//此棋串子数
    int g_gozi[EDGE][EDGE];
    
    
     void str_qi(int x,int y,int hb)
      {
        //本函数计算 x,y 处的hb颜色棋子的气
        gozi[x][y]=1; //标记本子已经计算过气
        goziLength++;
        /////////////////////////////////////////////////////右临子
        if (x+1<=19)//假设没有超出棋盘边线
        {
          if ((go[x+1][y]==2)&&(gokong[x+1][y]==0))
          //假设右临点为空而且该点未曾计算过气则
          {
            goqi++; //气数加一
            gokong[x+1][y]=1; //标记本空点已经计算过气
          }
          else if ((go[x+1][y]==hb)&&(gozi[x+1][y]==0))
          //否则假设右临点为和本子同色子而且该子未曾计算过气则
          str_qi(x+1,y,hb); //递归调用到右临子
        }
        /////////////////////////////////////////////////////左临子
        if (x-1>=1) //果没有超出棋盘边线
        {
          if ((go[x-1][y]==2)&&(gokong[x-1][y]==0))
          //假设左临点为空而且该点未曾计算过气则
          {
            goqi++; //气数加一
            gokong[x-1][y]=1; //标记本空点已经计算过气
          }
          else if ((go[x-1][y]==hb)&&(gozi[x-1][y]==0))
          //否则假设左临点为和本子同色子而且该子未曾计算过气则
          str_qi(x-1,y,hb); //递归调用到左临子
        }
        ////////////////////////////////////////////////////下临子
        if (y-1>=1)//假设没有超出棋盘边线
        {
          if ((go[x][y-1]==2)&&(gokong[x][y-1]==0))
          //假设下临点为空而且该点未曾计算过气则
          {
            goqi++; //气数加一
            gokong[x][y-1]=1; //标记本空点已经计算过气
          }
          else if ((go[x][y-1]==hb)&&(gozi[x][y-1]==0))
          //否则假设下临子点为和本子同色子而且该子未曾计算过气则
          str_qi(x,y-1,hb); //递归调用到下临子
        }
        ////////////////////////////////////////////////////上临点
        if (y+1<=19)//假设没有超出棋盘边线
        {
          if ((go[x][y+1]==2)&&(gokong[x][y+1]==0))
          //假设上临点为空而且该点未曾计算过气则
          {
            goqi++; //气数加一
            gokong[x][y+1]=1; //标记本空点已经计算过气
          }
          else if ((go[x][y+1]==hb)&&(gozi[x][y+1]==0))
          //否则假设上临点为和本子同色子而且该子未曾计算过气则
          str_qi(x,y+1,hb); //递归调用到上临子
        }
      }
    
      std::pair<int,int> str_lib(int x,int y, int hb)
      {
    
        for (int i = 1; i <= 19; i++)
          for (int j = 1; j <= 19; j++)
          {
            gozi[i][j] = 0; //初始化变量。表示该子未计算串气
            gokong[i][j] = 0; //初始化变量,表示该空点未计算串气
          }
        goqi=0; //棋串气初值
        goziLength=0;//棋串初始子数
        str_qi(x,y,hb); //调用串气子程序
        for(int i=0;i<EDGE;i++)
         for(int j=0;j<EDGE;j++){
          if(gozi[i][j]==1)
          g_gozi[i][j]=1;
         }
        return std::make_pair<int,int>(goqi,goziLength);
      }
    
      void suanqi()
      {
        int qq;
        for (int i = 0; i <EDGE; i++)
          for (int j = 0; j <EDGE; j++)
          {
            go[i][j]=qipan[i][j].color;//初始化go数组
          }
        for (int i = 0; i <EDGE; i++)
          for (int j = 0; j <EDGE; j++)
          {
            if (go[i][j]!=2&&g_gozi[i][j]==0)//仅处理未计算过的棋串
            {
    
              qq=str_lib(i,j,go[i][j]).first;
              qipan[i][j].qs=qq;
            }
          }
      }
    

    转载请标明出处。谢谢

  • 相关阅读:
    281. Zigzag Iterator
    298. Binary Tree Longest Consecutive Sequence
    482. License Key Formatting
    361. Bomb Enemy
    373. Find K Pairs with Smallest Sums
    304. Range Sum Query 2D
    308. Range Sum Query 2D
    307. Range Sum Query
    303. Range Sum Query
    247. Segment Tree Query II
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/7216983.html
Copyright © 2020-2023  润新知