2016-03-08 35 views
2

我正在創建一個tictactoe遊戲,並且我需要測試玩家是否贏得了所有動作,這給我帶來了很多麻煩。我把所有可能的贏組合的2D矢量:在tictactoe遊戲中可能獲勝的測試

vector<vector<int>> possibleWins {{1,2,3},{4,5,6},{7,8,9},{1,4,7},{2,5,8},{3,6,9},{1,5,9},{3,5,7}}; 

一舉一動我遍歷二維矢量和追加PLAYER1和player2向量與他們任何標記細胞:

vector<int> totalX {}; 
vector<int> totalO {}; 
int count = 1; 
for(int i=0; i<3; i++) { 
    for(int j=0; j<3; j++) { 
     if(board[i][j] == 'x') { 
      if(totalX.size() == 0) { 
       totalX.push_back(count); 
      } 
      for(int k=0; k<totalX.size(); k++) { 
       if(count == totalX[k]) { 
        break; 
       } 
       else { 
        totalX.push_back(count); 
       } 
      } 
     } 
     else if(board[i][j] == 'o') { 
      if(totalO.size() == 0) { 
       totalO.push_back(count); 
      } 
      for(int k=0; k<totalO.size(); k++) { 
       if(count == totalO[k]) { 
        break; 
       } 
       else { 
        totalO.push_back(count); 
       } 
      } 
     } 
     count++; 
    } 
} 

我再試試測試是否在每個玩家的細胞載體的細胞是細胞的一個成功的組合,而這被證明對我來說是困難的:

int xInRow = 0; 
for(int x=0; x<totalX.size(); x++) { 
    for(int y=0; y<possibleWins.size(); y++) { 
     xInRow = 0; 
     for(int z=0; z<3; z++) { 
      if(totalX[x] == possibleWins[y][z]) { 
       xInRow++; 
       if(xInRow == 3) { 
        return X_WON; 
       } 
      } 
     } 
    } 
} 

這不工作,我已經試過implemen用很多不同的方式來處理它,但我真的不知道如何枚舉所有可能的勝利,並測試一個球員是否有這些組合之一。

有沒有一種方法可以更好地構造它使其工作?我很迷茫。

+2

使用'std :: vector >'對於tictactoe板來說是矯枉過正的,並帶有_huge_缺點。你應該定義一個TicTacToeBoard類,其中有九個值表示遊戲的九個方塊(NW,N,NE,W,C,E,SW,S,SE)的狀態(空,x或o)。 – YSC

+1

順便說一句,如果您將棋盤表示爲3x3 {-1,0,1}矩陣A,那麼'[111] * A'和'A * [111]^T'會告訴您是否有贏家並且誰獲勝:如果任何一個乘法結果的複合數是3,1勝,如果是-3,1勝。 – YSC

回答

2

有兩種方法。你的代碼對於簡單的操作來說太複雜了,所以我不打算去理解它。

我同意YSC你不需要std :: vector。你知道每次都是3x3的網格,所以3x3枚舉數組應該更好。類似於

enum TTTState { 
    EMPTY=0, 
    X, 
    O 
} 

TTState board[3][3]; 

會爲您節省很多頭痛。您可以說board[0][0]是左上角,而board[2][2]是右下角。

選項1

我喜歡你possibleWins的想法,所以新board[3][3]數據結構,可以存儲對數字有int solutions[8][3][2]但這已經是樣的混亂。

for each solution in solutions 
    for each triplet in solution 
     for each pair in triplet 
      if board[pair[0]][pair[1]] matches all other pair in triplet 
       then whoever has pieces in the row has won 

選項2

這可能是更清潔。有三種可能的贏得方式。水平,垂直和對角線。你可以單獨檢查這三種方式。

for i = 0 ; i != 3; i++ 
    type = board[i][0] 
    won = true 
    for ii = 1; ii != 3; ii++ 
     if board[i][ii] is not type 
      won = false 
    if won then you can return the function with who won 

for i = 0 ; i != 3; i++ 
    type = board[0][i] 
    won = true 
    for ii = 1; ii != 3; ii++ 
     if board[ii][i] is not type 
      won = false 
    if won then you can return the function with who won 

對角線只能硬編碼,因爲只有兩個可能的勝利位置..

0

你讓事情變得複雜一點。
您不需要先收集玩家使用的位置,並查看其中有多少位處於獲勝位置。
既然你已經知道獲勝的位置,你只需要檢查是否有任何一個球員已經佔領了一個。

假設' '標誌着空方,

for(const auto& win: possibleWins) 
{ 
    if (board[win[0]] == board[win[1]] 
    && board[win[1]] == board[win[2]] 
    && board[win[0]] != ' ') 
    { 
     // if board[win[0]] == 'X' , then X won 
     // if board[win[0]] == 'O' , then O won 
    } 
} 

應該做的。

0
| | 
---+---+--- 
    | | 
---+---+--- 
    | | 

是一個int myArray [9];你把它myArray[played_position] = playerValue;的球員動作,那麼你可以使用你的vector<vector<int>> possibleWins {{1,2,3},{4,5,6},{7,8,9},{1,4,7},{2,5,8},{3,6,9},{1,5,9},{3,5,7}};後3移動到檢查位置對應相同的值(球員!)...

for(int idx=0; idx<possibleWins.size(); idx++) 
{ 
    if(myArray[possibleWins[idx][0]] == myArray[possibleWins[idx][1]] == myArray[possibleWins[idx][2]]) 
     { 
      return myArray[possibleWins[idx][0]; 
     } 
} 

這只是一個想法,希望它可以幫助你詳細說明....