人機博弈-吃子棋遊戲(二)算氣

來源:互聯網
上載者:User

標籤:c++   演算法   吃子棋   

演算法過程如下,輸入計算棋氣的起始子,檢查我方棋子其周邊的空白,並查看此空白是否已經計算過氣了,如果沒有計算過氣加一,如果已經計算則略過,進而遞迴調用計算我方棋子上下左右子的氣,最後演算法會返回棋串的子數和氣數。演算法注釋十分詳盡。

這個計算棋子氣的演算法,參考http://www.cnblogs.com/tuanzang/archive/2013/02/27/2935861.html,結合我們自身的應用需要最佳化和修改。這篇博文介紹了更多關於圍棋的演算法,有興趣的朋友可以進一步閱讀。

原文suanqi函數會重複計算已經計算過的棋串效率不高,應該對已經算過氣的函數不在重複算氣,並且我們需要知道棋串的長度。


#include <iostream>#include <utility>#define EDGE 19int 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)  {    //本Function Compute 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;        }      }  }

轉載請標明出處,謝謝

人機博弈-吃子棋遊戲(二)算氣

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.