亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

基于C++實(shí)現(xiàn)五子棋AI算法思想

 更新時(shí)間:2022年05月05日 11:49:38   作者:shenmirenLcy  
這篇文章主要為大家詳細(xì)介紹了基于C++實(shí)現(xiàn)五子棋AI算法思想,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

今天我想要分享一下我做五子棋AI的思路。因?yàn)樵谧鲞@個(gè)之前,我沒(méi)有接觸過(guò)任何像這種類(lèi)似的東西。通過(guò)這一次,我也算是有所了解,我的思路也是來(lái)自很多網(wǎng)絡(luò)上的博客,看了很多,最終總結(jié)出了自己的這樣一個(gè)。

那我的五子棋是15*15的大?。ㄒ话阋簿褪沁@樣的一個(gè)大小)。我的AI算法要求每一次落子之后都要去計(jì)算每一個(gè)空暇的位置的“分值”,簡(jiǎn)單的說(shuō),我們需要一個(gè)存放棋子的數(shù)組,表示是否存放了棋子,還要一個(gè)計(jì)算每一個(gè)空格的數(shù)組來(lái)記錄“分?jǐn)?shù)”,這個(gè)分?jǐn)?shù)是后期AI用來(lái)運(yùn)算的基礎(chǔ),也是你AI難度控制的點(diǎn)。

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

首先初始化你的分?jǐn)?shù)數(shù)組,讓他們?nèi)繛榱?。然后在每一次落子之后進(jìn)行全盤(pán)的遍歷,如果發(fā)現(xiàn)該處為空白,于是檢查其四周八個(gè)方向(當(dāng)然如果是邊緣位置就相對(duì)修改,判斷是否出了邊界)。若在空白處,且發(fā)現(xiàn)在某一對(duì)角線方向發(fā)現(xiàn)有一個(gè)其他顏色的棋子,那么相對(duì)的給這個(gè)空白區(qū)域的分?jǐn)?shù)數(shù)組加上一定的分值,然后繼續(xù)往這個(gè)方向檢測(cè)是否還有連續(xù)的同一顏色的棋子,若沒(méi)有則檢查其他方向或者檢測(cè)下一個(gè)空白位置。若是還在同一方向上面找到了相同顏色的棋子,那么第二個(gè)棋子的出現(xiàn),你可以給改空白處加上雙倍的分值,表明這個(gè)空白位置更加重要。一次類(lèi)推,繼續(xù)檢測(cè)。(PS:因?yàn)樽罱KAI棋子落在什么地方,依靠的是最后遍歷整個(gè)分?jǐn)?shù)數(shù)組,然后根據(jù)分?jǐn)?shù)的高低來(lái)進(jìn)行判斷落子落在哪里的,在下面講)。

經(jīng)過(guò)上一遍的遍歷,每一次落子都會(huì)使得分?jǐn)?shù)數(shù)組得到一些變化,每一次都會(huì)導(dǎo)致AI判斷的變化。在這個(gè)基礎(chǔ)上,每一次落子還要進(jìn)行一次對(duì)自己本身棋子顏色的一個(gè)遍歷,判斷自己的情況,同時(shí)加分加在分?jǐn)?shù)數(shù)組之中,這樣一來(lái),電腦就會(huì)根據(jù)自己的棋子的情況以及玩家的落子情況進(jìn)行判斷,哪一個(gè)地方更加適合落子。

因?yàn)槲沂堑谝淮巫鯝I,網(wǎng)絡(luò)上搜到的一些思想一般也是這種類(lèi)似的遍歷思想。理解了以后寫(xiě)代碼就比較方便。最后可能會(huì)有一些點(diǎn)的分?jǐn)?shù)是相同的,所以還有設(shè)置一下隨機(jī)落子。把分?jǐn)?shù)相同的地點(diǎn)隨機(jī)落子。

個(gè)人感覺(jué)AI的強(qiáng)弱是根據(jù)你每一次給他增加分?jǐn)?shù)的多少來(lái)確定的。這個(gè)我的AI有時(shí)候也會(huì)抽風(fēng),不過(guò)一般情況比較正常,可能運(yùn)氣也占了一部分,當(dāng)初設(shè)計(jì)加分的時(shí)候其實(shí)沒(méi)想那么多,現(xiàn)在卻發(fā)現(xiàn)好像還不錯(cuò)。

大家要多去實(shí)踐練習(xí),多改改分?jǐn)?shù)可能就會(huì)出來(lái)不錯(cuò)的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;   //記錄這個(gè)點(diǎn) 
    printpart(*x, *y, tp);     //打印出電腦AI第一次落子 
    isTouch = true; 
    tp++; 
    tp = tp % 2; 
  } 
  else      //從第2步開(kāi)始,使用評(píng)分系統(tǒng) 
  { 
    Findscore(*x, *y); 
  } 
} 
 
 
void GameScene::Findscore(int &x, int &y)   //查找評(píng)分最高的坐標(biāo) 
{ 
  srand((unsigned)time(NULL)); 
  int i, j, x1, x2, y1, y2, lx; 
  int Max = 0; 
  ChessScore();      //調(diào)用評(píng)分函數(shù) 
  for (i = 0; i<15; i++) 
  { 
    for (j = 0; j<15; j++) 
    { 
      if (Score[i][j]>Max) 
      { 
        Max = Score[i][j];  //獲取所有點(diǎn)中,評(píng)分最高的 
        x1 = i; 
        y1 = j; 
      } 
    } 
  } 
  x2 = x1; y2 = y1; 
  for (i = 0; i<15; i++)    //可能的話,有評(píng)分相同的多個(gè)點(diǎn) 
  { 
    for (j = 0; j<15; j++) 
    { 
      if (Score[i][j] == Max&&i != x2&&j != y2)   //在這么多個(gè)相同分?jǐn)?shù)的點(diǎn)中,隨機(jī)找一個(gè) 
      { 
        lx = rand() % 10; 
        if (lx<5) 
        { 
          x2 = i, y2 = j; 
          break; 
        } 
      } 
    } 
  } 
  if (x2 != x1 || y2 != y1)   //棋盤(pán)上有2個(gè)最高分 
  { 
    lx = rand() % 10;    //隨機(jī)一個(gè) 
    if (lx>6) 
    { 
      x = x1, y = y1; 
    } 
    else 
    { 
      x = x2, y = y2; 
    } 
  } 
  else    //棋盤(pán)上只有一個(gè)最高分 
  { 
    x = x1, y = y1; 
  } 
  Max = 0;    //清空最大值 
  ch[x][y] = tp;       //記錄這個(gè)點(diǎn) 
  printpart(x, y, tp);    //打印出電腦AI落子 
  if (winerValue==2) 
  { 
    isTouch = true; 
  } 
   
  tp++; 
  tp = tp % 2; 
} 
 
 
inline void GameScene::ChessOne(int &x, int &y)   //玩家走第1步時(shí)的落子 
{ 
  int i, j; 
  srand((unsigned)time(NULL));    //隨機(jī)數(shù)隨著時(shí)間的改變而改變 
  for (i = 0; i<15; i++) 
  { 
    for (j = 0; j<15; j++) 
    { 
      if (ch[i][j] == 0)  //如果找到了玩家的棋子,在它的8個(gè)方的任意一點(diǎn)落子 
      { 
        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;      //循環(huán)變量 
  int number1 = 0, number2 = 0;   //number用來(lái)統(tǒng)計(jì)玩家或電腦棋子連成個(gè)數(shù) 
  int empty = 0;    //empty用來(lái)統(tǒng)計(jì)空點(diǎn)個(gè)數(shù) 
  memset(Score, 0, sizeof(Score));                    //把評(píng)分?jǐn)?shù)組先清零 
  for (x = 0; x<15; x++) 
  { 
    for (y = 0; y<15; y++) 
    { 
      if (ch[x][y] == 2)    //如果這個(gè)點(diǎn)為空  
      { 
        for (i = -1; i <= 1; i++) 
        { 
          for (j = -1; j <= 1; j++)   //判斷8個(gè)方向  
          { 
            if (i != 0 || j != 0)   //若是都為0的話,那不就是原坐標(biāo)嘛 
            { 
              //對(duì)玩家落點(diǎn)評(píng)分 
              for (k = 1; i <= 4; k++)   //循環(huán)4次 
              {                        //這點(diǎn)沒(méi)越界  且這點(diǎn)存在黑子(玩家) 
                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)     //這點(diǎn)是個(gè)空點(diǎn),+1后退出 
                {  
                  empty++;  
                  break;  
                }    
                else                    //否則是墻或者對(duì)方的棋子了  
                {  
                  break;  
                }     
              } 
              for (k = -1; k >= -4; k--)            //向它的相反方向判斷  
              {                        //這點(diǎn)沒(méi)越界  且這點(diǎn)存在黑子(玩家) 
                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)     //這點(diǎn)是個(gè)空點(diǎn),+1后退出 
                {  
                  empty++;  
                  break;  
                }   
                else 
                {  
                  break; 
                } 
              } 
              if (number2 == 1)   //2個(gè)棋子  
              {  
                Score[x][y] += 1;  
              }   
              else if (number1 == 2)   //3個(gè)棋子  
              { 
                if (empty == 1)     
                { 
                  Score[x][y] += 5;   //有一個(gè)空點(diǎn)+5分 死3  
                }      
                else if (empty == 2)  
                {  
                  Score[x][y] += 10;  //有兩個(gè)空點(diǎn)+10分 活3 
                }  
              } 
              else if (number1 == 3)   //4個(gè)棋子  
              { 
                if (empty == 1)    
                {  
                  Score[x][y] += 20;  //有一個(gè)空點(diǎn)+20分 死4  
                }   
                else if (empty == 2) 
                {  
                  Score[x][y] += 100;  //有2個(gè)空點(diǎn)+100分 活4 
                }   
              } 
              else if (number1 >= 4)   
              {  
                Score[x][y] += 1000;  //對(duì)方有5個(gè)棋子,分?jǐn)?shù)要高點(diǎn),先堵 
              }   
 
              empty = 0;   //統(tǒng)計(jì)空點(diǎn)個(gè)數(shù)的變量清零  
 
              //對(duì)電腦落點(diǎn)評(píng)分 
              for (k = 1; i <= 4; k++)   //循環(huán)4次 
              {       //這點(diǎn)沒(méi)越界  且這點(diǎn)存在白子(電腦) 
                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;   //空點(diǎn) 
                }  
                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個(gè)棋子 
              }  
              else if (number2 == 1)   
              { 
                Score[x][y] += 2;    //2個(gè)棋子  
              }    
              else if (number2 == 2)   //3個(gè)棋子 
              { 
                if (empty == 1)    
                {  
                  Score[x][y] += 8;  //死3 
                }   
                else if (empty == 2)  
                {  
                  Score[x][y] += 30;  //活3  
                }  
              } 
              else if (number2 == 3)   //4個(gè)棋子 
              { 
                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;   //自己落在這點(diǎn)能形成5個(gè),也就能勝利了,分?jǐn)?shù)最高 
              }  
 
              number1 = 0;     //清零,以便下次重新統(tǒng)計(jì) 
              number2 = 0;                   
              empty = 0; 
            } 
          } 
        } 
      } 
    } 
  } 
} 

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • STL容器之list源碼詳細(xì)解讀

    STL容器之list源碼詳細(xì)解讀

    這篇文章主要介紹了STL容器之list源碼詳細(xì)解讀,相對(duì)于vector的連續(xù)線性空間,list就顯得更加復(fù)雜,它每插入或者刪除一個(gè)元素,就配置或釋放一個(gè)元素空間,需要的朋友可以參考下
    2024-01-01
  • C++編譯器Clion的使用詳解(總結(jié))

    C++編譯器Clion的使用詳解(總結(jié))

    Clion有一個(gè)比較讓人郁悶的地方就是必須要把編譯環(huán)境配置好了,IDE才去做代碼分析等動(dòng)作,但是還是有很多優(yōu)點(diǎn),本文重點(diǎn)給大家介紹C++編譯器Clion的使用,感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • 基于VC 6.0使用C語(yǔ)言實(shí)現(xiàn)俄羅斯方塊

    基于VC 6.0使用C語(yǔ)言實(shí)現(xiàn)俄羅斯方塊

    這篇文章主要為大家詳細(xì)介紹了基于VC 6.0使用C語(yǔ)言實(shí)現(xiàn)俄羅斯方塊,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • C++虛函數(shù)及虛函數(shù)表簡(jiǎn)析

    C++虛函數(shù)及虛函數(shù)表簡(jiǎn)析

    這篇文章主要介紹了C++虛函數(shù)及虛函數(shù)表,內(nèi)容非常詳細(xì),思路清晰,需要的朋友可以參考下
    2015-08-08
  • C語(yǔ)言一看就懂的指針與結(jié)構(gòu)體介紹

    C語(yǔ)言一看就懂的指針與結(jié)構(gòu)體介紹

    指針提供了對(duì)地址操作的一種方法,因此,使用指針可使得C語(yǔ)言能夠更高效地實(shí)現(xiàn)對(duì)計(jì)算機(jī)底層硬件的操作。另外,通過(guò)指針可以更便捷地操作數(shù)組。C數(shù)組允許定義可存儲(chǔ)相同類(lèi)型數(shù)據(jù)項(xiàng)的變量,結(jié)構(gòu)是C編程中另一種用戶自定義的可用的數(shù)據(jù)類(lèi)型,它允許您存儲(chǔ)不同類(lèi)型的數(shù)據(jù)項(xiàng)
    2022-04-04
  • 一文徹底搞懂IO底層原理

    一文徹底搞懂IO底層原理

    我們今天要給大家講的底層的IO看上去簡(jiǎn)單,實(shí)則抽象。并且在它之上衍生出了語(yǔ)言層面用于實(shí)戰(zhàn)的技術(shù),比如我們熟悉的java語(yǔ)言中的NIO或者像Netty這樣的框架
    2021-06-06
  • C++中template方法undefined reference to的問(wèn)題解決

    C++中template方法undefined reference to的問(wèn)題解決

    Undefined reference to 錯(cuò)誤:這類(lèi)錯(cuò)誤是在連接過(guò)程中出現(xiàn)的,本文就來(lái)介紹一下C++中template方法undefined reference to的問(wèn)題解決,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • C語(yǔ)言實(shí)現(xiàn)計(jì)算圓周長(zhǎng)以及面積

    C語(yǔ)言實(shí)現(xiàn)計(jì)算圓周長(zhǎng)以及面積

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)計(jì)算圓周長(zhǎng)以及面積方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C語(yǔ)言中聯(lián)合體union的實(shí)例詳解

    C語(yǔ)言中聯(lián)合體union的實(shí)例詳解

    這篇文章主要介紹了 C語(yǔ)言中聯(lián)合體union的實(shí)例詳解的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-10-10
  • C語(yǔ)言游戲之猜數(shù)字

    C語(yǔ)言游戲之猜數(shù)字

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言游戲之猜數(shù)字,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02

最新評(píng)論