2014-08-29 172 views
-1

我正在嘗試爲井字遊戲製作無與倫比的AI,非常類似於http://perfecttictactoe.herokuapp.com/中的AI。但是,由於我仍然在學習C語言,所以它更簡單一些,因爲用戶總是先走了,而且沒有GUI,而ASCII藝術被用於圖形。我已經查看了MiniMax算法的各種實現,因爲它似乎是解決這個問題最值得推薦的方法,根據這個網站以及其他許多人。我遇到了一些問題,因爲算法似乎沒有工作。相反,它從平方(1,1)(數組中的[0,0])開始穩步地從左向右移動,一旦到達行的末尾就下移到下一行。我已經嘗試了很多東西,從精心梳理我的代碼重寫它,但似乎沒有任何工作。我希望這裏的美妙社區能幫助我!在井字遊戲中爲C實現MiniMax算法C

在此先感謝!

代碼:

#include <stdio.h> 
#include "simpio.h" 
#include "stdlib.h" 

void print(char board[3][3]); 
char didwin(char board[3][3]); 
void AImove(char board[3][3], int *rows, int *columns); 
int MinMax(char board[3][3], int player); 

int main(void) 
{ 
    int i, i2, player, rows=0,columns=0; 
    char board[3][3], tempboard[3][3], winner; 
    string name; 
    printf("The computer will now play tic-tac-tow with you.\n"); 
    printf("The computer will use \"O\" and you will use \"X\".\n"); 
    printf("You will go first. To begin, please enter your name: "); 
    name=GetLine(); 
    while(true) 
    { 
     for(i=0;i<3;i++) 
     { 
      for(i2=0;i2<3;i2++) 
      { 
       board[i][i2]='\0'; 
      } 
     } 
     print(board); 
     for(i=0;i<9&&winner==0;i++) 
     { 
      printf("\n"); 
      player=i%2+1; 
      if(player==1) 
      { 
       printf("\n%s, what row is your square in?\t", name); 
       rows=GetInteger()-1; 
       printf("\n%s, what column is your square in?\t", name); 
       columns=GetInteger()-1; 
      } 
      else if(player==2) 
      { 
       printf("\nThe computer will move now.\n"); 
       for(i=0;i<3;i++) 
       { 
        for(i2=0;i2<3;i2++) 
        { 
         tempboard[i][i2]=board[i][i2]; 
        } 
       } 
       AImove(tempboard, &rows, &columns); 
      } 
      if(rows<0||rows>3||columns<0||columns>3||board[rows][columns]=='X'||board[rows][columns]=='O') 
      { 
       if(player==1) 
       { 
        printf("The space is already taken or out of bounds, please try again");  
       } 
       i--; 
      } 
      else 
      { 
       if(player==1) board[rows][columns]='X'; 
       else board[rows][columns]='O'; 
       print(board); 
      } 
      winner = didwin(board); 
     } 
     if(winner!='\0') 
     { 
      if(winner=='X') printf("\n\nYou won!"); 
      else printf("\n\nThe computer won! Try harder next time."); 
      break; 

     } 
     else 
     { 
      printf("No winner this round. Try again."); 
      break; 
     } 
    } 
} 

void print(char board[3][3]) 
{ 
    int i,i2; 
    printf("\n"); 
    for(i=0;i<3;i++) 
    { 
     for(i2=0;i2<3;i2++) 
     { 
      if(board[i][i2]=='\0') 
      { 
       printf(" "); 
      } 
      else 
      { 
       printf(" %c ", board[i][i2]); 
      } 
      if(i2<2) printf("|"); 
     } 
     if(i<2) 
     { 
      printf("\n-----------\n"); 
     } 
    } 
} 

char didwin(char board[3][3]) 
{ 
    int i,i2; 
    char temp; 
    char winner = '\0'; 

    for(i=0;i<3;i++) 
    { 
     temp=board[i][0]; 
     for(i2=0;i2<3;i2++) 
     { 
      if(board[i][i2]!=temp) 
      { 
       temp='\0'; 
      } 
     } 
     if(temp!='\0') 
     { 
      winner=temp; 
     } 
    } 

    for(i=0;i<3;i++) 
    { 
     temp=board[0][i]; 
     for(i2=0;i2<3;i2++) 
     { 
      if(board[i2][i]!=temp) 
      { 
       temp='\0'; 
      }  
     } 
     if(temp!='\0') 
     { 
      winner=temp; 
     } 
    } 

    temp=board[0][0]; 
    for(i=0;i<3;i++) 
    { 
     if(board[i][i]!=temp) 
     { 
      temp='\0'; 
     } 
    } 
    if(temp!='\0') 
    { 
     winner=temp; 
    } 

    temp=board[0][2]; 
    for(i=0;i<3;i++) 
    { 
     if(board[i][2-i]!= temp) 
     { 
      temp='\0'; 
     } 
    } 
    if(temp!='\0') 
    { 
     winner=temp; 
    } 
    return winner; 
} 

void AImove(char tempboard[3][3], int *rows, int *columns) 
{ 
    int points=-1, temppoints, i, i2; 

    for(i=0;i<3;i++) 
    { 
     for(i2=0;i2<3;i2++) 
     { 
      if(tempboard[i][i2]=='\0') 
      { 
       tempboard[i][i2]='O'; 
       temppoints=MinMax(tempboard, 1); 
       if(temppoints>points) 
       { 
        points=temppoints; 
        *rows=i; 
        *columns=i2; 
       } 
       tempboard[i][i2]='\0'; 
      } 
     } 
    } 
} 

int MinMax(char tempboard[3][3], int player) 
{ 
    int winner, points, temppoints, i, i2; 
    winner=didwin(tempboard); 
    if(winner=='X') return(0); 
    else if (winner=='O') return(999); 
    else 
    { 
     for(i=0;i<3;i++) 
     { 
      for(i2=0;i2<3;i2++) 
      { 
       if(tempboard[i][i2]='\0') 
       { 
        if (player==1) 
        { 
         tempboard[i][i2]='X'; 
        } 
        else 
        { 
         tempboard[i][i2]='O'; 
        } 
        if (player==1) 
        { 
         temppoints=MinMax(tempboard, 2); 
        } 
        else 
        { 
         temppoints=MinMax(tempboard, 1); 
        } 
        if(temppoints>points) 
        { 
         points=temppoints; 
        } 
        tempboard[i][i2]='\0'; 
       } 
      } 
     } 
    } 
    return(points); 
} 

回答

1

代碼並在MinMax()分配,而不是比較。隨着points未初始化和返回,只有UB。

int points 
... 
// if(tempboard[i][i2]='\0') { // never true 
if (tempboard[i][i2] == '\0') { 
    points == ... 
... 
return points; 

BTW:建議明確從main()

+0

我認爲他只是沒有明顯理由而投票給你;就像上面回答的其他人一樣......! :D – jtimz 2014-08-29 02:10:55

+0

@jtimz一個人得到很多贊成票,沒有評論的原因,以及一些沒有評論的贊成票 - 這就是SO的設置方式。上/下選票與評論是建設性的反饋。順便說一句:我不認爲OP有反對票的反對點。 – chux 2014-08-29 02:17:16

+0

那麼,我不太明白爲什麼有人在你說了一些正確的話之後低估了你的投票率......老實說,當這樣的事情發生時,總是莫名其妙。 (雖然這是從我這裏得到的讚揚!yey 0!) – jtimz 2014-08-29 02:21:41

0

你的代碼的關鍵錯誤返回值是算法「最小最大」一直沒有執行權。請注意,根據您的評估,player1是正在嘗試儘可能降低他的得分的Min玩家,而玩家2是正在儘可能提高他的得分的Max玩家。所以,你應該如下分別討論這兩種情況:

if (player==1) 
{ 
    temppoints=MinMax(tempboard, 2); 
} 
else 
{ 
    temppoints=MinMax(tempboard, 1); 
} 
if(player==1 && temppoints<points) //HERE 
{ 
    points=temppoints; 
} 
else if(player==2 && temppoints>points) //HERE 
{          //HERE 
    points=temppoints;     //HERE 
}          //HERE 

除了上面的錯誤,你也可以注意一些疏忽造成的錯誤,如在最小最大函數變化if(tempboard[i][i2]='\0')if(tempboard[i][i2]=='\0')