亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

基于C++實現五子棋AI算法思想

發布時間:2020-09-02 06:08:43 來源:腳本之家 閱讀:471 作者:shenmirenLcy 欄目:編程語言

         今天我想要分享一下我做五子棋AI的思路。因為在做這個之前,我沒有接觸過任何像這種類似的東西。通過這一次,我也算是有所了解,我的思路也是來自很多網絡上的博客,看了很多,最終總結出了自己的這樣一個。

         那我的五子棋是15*15的大小(一般也就是這樣的一個大小)。我的AI算法要求每一次落子之后都要去計算每一個空暇的位置的“分值”,簡單的說,我們需要一個存放棋子的數組,表示是否存放了棋子,還要一個計算每一個空格的數組來記錄“分數”,這個分數是后期AI用來運算的基礎,也是你AI難度控制的點。

         我現有的思路就是分兩部分。首先是如果是玩家先落子,那么要求電腦AI隨即在你落子的地方的任意一個方向,隨機落子,這是第一步。接下來以后就正式進入到算法中去。

首先初始化你的分數數組,讓他們全部為零。然后在每一次落子之后進行全盤的遍歷,如果發現該處為空白,于是檢查其四周八個方向(當然如果是邊緣位置就相對修改,判斷是否出了邊界)。若在空白處,且發現在某一對角線方向發現有一個其他顏色的棋子,那么相對的給這個空白區域的分數數組加上一定的分值,然后繼續往這個方向檢測是否還有連續的同一顏色的棋子,若沒有則檢查其他方向或者檢測下一個空白位置。若是還在同一方向上面找到了相同顏色的棋子,那么第二個棋子的出現,你可以給改空白處加上雙倍的分值,表明這個空白位置更加重要。一次類推,繼續檢測。(PS:因為最終AI棋子落在什么地方,依靠的是最后遍歷整個分數數組,然后根據分數的高低來進行判斷落子落在哪里的,在下面講)。

         經過上一遍的遍歷,每一次落子都會使得分數數組得到一些變化,每一次都會導致AI判斷的變化。在這個基礎上,每一次落子還要進行一次對自己本身棋子顏色的一個遍歷,判斷自己的情況,同時加分加在分數數組之中,這樣一來,電腦就會根據自己的棋子的情況以及玩家的落子情況進行判斷,哪一個地方更加適合落子。

         因為我是第一次做AI,網絡上搜到的一些思想一般也是這種類似的遍歷思想。理解了以后寫代碼就比較方便。最后可能會有一些點的分數是相同的,所以還有設置一下隨機落子。把分數相同的地點隨機落子。

         個人感覺AI的強弱是根據你每一次給他增加分數的多少來確定的。這個我的AI有時候也會抽風,不過一般情況比較正常,可能運氣也占了一部分,當初設計加分的時候其實沒想那么多,現在卻發現好像還不錯。

         大家要多去實踐練習,多改改分數可能就會出來不錯的AI了,o(^▽^)o。

下面貼上我的代碼! 

void GameScene::Robot(int *x, int *y, int *Sum) 
{ 
  ExWhile1 = true; 
  if (*Sum == 1) 
  { 
    while (ExWhile1) 
    { 
      ChessOne(*x, *y); 
      if (ch[*x][*y] == 2){ ExWhile1 = false; } 
    } 
    ch[*x][*y] = tp;   //記錄這個點 
    printpart(*x, *y, tp);     //打印出電腦AI第一次落子 
    isTouch = true; 
    tp++; 
    tp = tp % 2; 
  } 
  else      //從第2步開始,使用評分系統 
  { 
    Findscore(*x, *y); 
  } 
} 
 
 
void GameScene::Findscore(int &x, int &y)   //查找評分最高的坐標 
{ 
  srand((unsigned)time(NULL)); 
  int i, j, x1, x2, y1, y2, lx; 
  int Max = 0; 
  ChessScore();      //調用評分函數 
  for (i = 0; i<15; i++) 
  { 
    for (j = 0; j<15; j++) 
    { 
      if (Score[i][j]>Max) 
      { 
        Max = Score[i][j];  //獲取所有點中,評分最高的 
        x1 = i; 
        y1 = j; 
      } 
    } 
  } 
  x2 = x1; y2 = y1; 
  for (i = 0; i<15; i++)    //可能的話,有評分相同的多個點 
  { 
    for (j = 0; j<15; j++) 
    { 
      if (Score[i][j] == Max&&i != x2&&j != y2)   //在這么多個相同分數的點中,隨機找一個 
      { 
        lx = rand() % 10; 
        if (lx<5) 
        { 
          x2 = i, y2 = j; 
          break; 
        } 
      } 
    } 
  } 
  if (x2 != x1 || y2 != y1)   //棋盤上有2個最高分 
  { 
    lx = rand() % 10;    //隨機一個 
    if (lx>6) 
    { 
      x = x1, y = y1; 
    } 
    else 
    { 
      x = x2, y = y2; 
    } 
  } 
  else    //棋盤上只有一個最高分 
  { 
    x = x1, y = y1; 
  } 
  Max = 0;    //清空最大值 
  ch[x][y] = tp;       //記錄這個點 
  printpart(x, y, tp);    //打印出電腦AI落子 
  if (winerValue==2) 
  { 
    isTouch = true; 
  } 
   
  tp++; 
  tp = tp % 2; 
} 
 
 
inline void GameScene::ChessOne(int &x, int &y)   //玩家走第1步時的落子 
{ 
  int i, j; 
  srand((unsigned)time(NULL));    //隨機數隨著時間的改變而改變 
  for (i = 0; i<15; i++) 
  { 
    for (j = 0; j<15; j++) 
    { 
      if (ch[i][j] == 0)  //如果找到了玩家的棋子,在它的8個方的任意一點落子 
      { 
        int lx = rand() % 7; 
        if (lx == 0) 
        { 
          x = i + 1; y = j + 1; 
          if (ch[x][y] == 2){ break; } 
        } 
        else if (lx == 1) 
        { 
          x = i + 1; y = j - 1; 
          if (ch[x][y] == 2){ break; } 
        } 
        else if (lx == 2) 
        { 
          x = i - 1; y = j - 1; 
          if (ch[x][y] == 2){ break; } 
        } 
        else if (lx == 3) 
        { 
          x = i - 1; y = j + 1; 
          if (ch[x][y] == 2){ break; } 
        } 
        else if (lx == 4) 
        { 
          x = i - 1; y = j;    //上 
          if (ch[x][y] == 2){ break; } 
        } 
        else if (lx == 5) 
        { 
          x = i; y = j - 1;   //左 
          if (ch[x][y] == 2){ break; } 
        } 
        else if (lx == 6) 
        { 
          x = i; y = j + 1;   //右 
          if (ch[x][y] == 2){ break; } 
        } 
        else 
        { 
          x = i + 1; y = j;    //下 
          if (ch[x][y] == 2){ break; } 
        } 
      } 
    } 
  } 
} 
 
void GameScene::ChessScore() 
{ 
  int x, y, i, j, k;      //循環變量 
  int number1 = 0, number2 = 0;   //number用來統計玩家或電腦棋子連成個數 
  int empty = 0;    //empty用來統計空點個數 
  memset(Score, 0, sizeof(Score));                    //把評分數組先清零 
  for (x = 0; x<15; x++) 
  { 
    for (y = 0; y<15; y++) 
    { 
      if (ch[x][y] == 2)    //如果這個點為空  
      { 
        for (i = -1; i <= 1; i++) 
        { 
          for (j = -1; j <= 1; j++)   //判斷8個方向  
          { 
            if (i != 0 || j != 0)   //若是都為0的話,那不就是原坐標嘛 
            { 
              //對玩家落點評分 
              for (k = 1; i <= 4; k++)   //循環4次 
              {                        //這點沒越界  且這點存在黑子(玩家) 
                if (x + k*i >= 0 && x + k*i <= 14 &&  
                  y + k*j >= 0 && y + k*j <= 14 &&  
                  ch[x + k*i][y + k*j] == 0) 
                {  
                  number1++; 
                } 
                else if (ch[x + k*i][y + k*j] == 2)     //這點是個空點,+1后退出 
                {  
                  empty++;  
                  break;  
                }    
                else                    //否則是墻或者對方的棋子了  
                {  
                  break;  
                }     
              } 
              for (k = -1; k >= -4; k--)            //向它的相反方向判斷  
              {                        //這點沒越界  且這點存在黑子(玩家) 
                if (x + k*i >= 0 && x + k*i <= 14 && 
                  y + k*j >= 0 && y + k*j <= 14 &&  
                  ch[x + k*i][y + k*j] == 0) 
                {  
                  number1++; 
                } 
                else if (ch[x + k*i][y + k*j] == 2)     //這點是個空點,+1后退出 
                {  
                  empty++;  
                  break;  
                }   
                else 
                {  
                  break; 
                } 
              } 
              if (number2 == 1)   //2個棋子  
              {  
                Score[x][y] += 1;  
              }   
              else if (number1 == 2)   //3個棋子  
              { 
                if (empty == 1)     
                { 
                  Score[x][y] += 5;   //有一個空點+5分 死3  
                }      
                else if (empty == 2)  
                {  
                  Score[x][y] += 10;  //有兩個空點+10分 活3 
                }  
              } 
              else if (number1 == 3)   //4個棋子  
              { 
                if (empty == 1)    
                {  
                  Score[x][y] += 20;  //有一個空點+20分 死4  
                }   
                else if (empty == 2) 
                {  
                  Score[x][y] += 100;  //有2個空點+100分 活4 
                }   
              } 
              else if (number1 >= 4)   
              {  
                Score[x][y] += 1000;  //對方有5個棋子,分數要高點,先堵 
              }   
 
              empty = 0;   //統計空點個數的變量清零  
 
              //對電腦落點評分 
              for (k = 1; i <= 4; k++)   //循環4次 
              {       //這點沒越界  且這點存在白子(電腦) 
                if (x + k*i >= 0 && x + k*i <= 14 &&  
                  y + k*j >= 0 && y + k*j <= 14 &&  
                  ch[x + k*i][y + k*j] == 1) 
                {  
                  number2++; 
                } 
                else if (ch[x + k*i][y + k*j] == 2) 
                {  
                  empty++; break;   //空點 
                }  
                else  
                { 
                  break; 
                } 
              } 
              for (k = -1; k >= -4; k--)   //向它的相反方向判斷  
              { 
                if (x + k*i >= 0 && x + k*i <= 14 && 
                  y + k*j >= 0 && y + k*j <= 14 &&  
                  ch[x + k*i][y + k*j] == 1) 
                {  
                  number2++; 
                } 
                else if (ch[x + k*i][y + k*j] == 2) 
                {  
                  empty++; break; 
                } 
                else 
                {  
                  break;   //注釋與上面玩家版相同 
                }       
              } 
              if (number2 == 0)    
              {  
                Score[x][y] += 1;    //1個棋子 
              }  
              else if (number2 == 1)   
              { 
                Score[x][y] += 2;    //2個棋子  
              }    
              else if (number2 == 2)   //3個棋子 
              { 
                if (empty == 1)    
                {  
                  Score[x][y] += 8;  //死3 
                }   
                else if (empty == 2)  
                {  
                  Score[x][y] += 30;  //活3  
                }  
              } 
              else if (number2 == 3)   //4個棋子 
              { 
                if (empty == 1)    
                {  
                  Score[x][y] += 50;   //死4 
                }   
                else if (empty == 2)  
                {  
                  Score[x][y] += 200;   //活4 
                }   
              } 
              else if (number2 >= 4)  
              {  
                Score[x][y] += 10000;   //自己落在這點能形成5個,也就能勝利了,分數最高 
              }  
 
              number1 = 0;     //清零,以便下次重新統計 
              number2 = 0;                   
              empty = 0; 
            } 
          } 
        } 
      } 
    } 
  } 
} 

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

凌源市| 尼木县| 义马市| 盖州市| 平陆县| 陕西省| 濮阳县| 阿尔山市| 罗平县| 长垣县| 满洲里市| 红安县| 阳曲县| 山东省| 镇原县| 太仆寺旗| 常德市| 华阴市| 阿合奇县| 开化县| 瑞金市| 东方市| 西乡县| 自贡市| 桐梓县| 崇州市| 宾川县| 阿尔山市| 永顺县| 灵川县| 蕲春县| 元谋县| 内黄县| 邳州市| 卓尼县| 和平县| 崇明县| 仪陇县| 涟水县| 喜德县| 鹤岗市|