2014-09-23 165 views
-2

我正在用C++製作一個2人的tic tac toe遊戲,而我正在修復一對夫婦的問題。所以這個節目是完整的,除了1個細節之外,玩家可以覆蓋其他玩家的動作。所以如果我們有玩家1(「x」)和玩家2(「o」),玩家1可以在「o」上放置一個「x」,從而消除玩家2的移動!我不知道是否有什麼辦法可以阻止這種情況發生,我使用了一個二維數組,我的「董事會」:如何阻止char變量被覆蓋?

Game.cpp

#include "Game.h" 
#include <iostream> 
#include <cstdlib> 
using namespace std; 


Game::Game() 
{ 
    char b[3][3]= { {'.','.','.'},{'.','.','.'},{'.','.','.'}}; 
    for(x=0;x<3;x++) 
    { 
     for(y=0;y<3;y++) 
     { 
      board[x][y]=b[x][y]; 
     } 

} 
counter = 1; 
printBoard2(); 
} 



void Game::printBoard2() 
{ 
    for(x=0; x < 3; x++) 
    { 
     for(y =0; y<3; y++) 
     { 
      cout << board[x][y] << " " ; 

     } 
     cout << endl; 
    } 

cout << endl; 
showMoves(); 


} 

void Game::printBoard() 
{ 
    for(x=0; x < 3; x++) 
    { 
     for(y =0; y<3; y++) 
     { 
      cout << board[x][y] << " " ; 

     } 
     cout << endl; 
    } 

cout << endl; 
cout << "Move # " << counter << endl; 
checkWinner(board); 
counter ++; 
checkNoWinner(counter); 
} 

void Game::showMoves() 
{ 

    cout << endl; 
    cout << "Player 1, enter where you want to place an 'x' " << endl; 
    cout << endl; 
    cout << "Top right (1)" << endl; 
    cout << "Top left (2)" << endl; 
    cout << "Center (3)" << endl; 
    cout << "Center top (4) " << endl; 
    cout << "Center bottom (5)" << endl; 
    cout << "Center right (6) " << endl; 
    cout << "Center left (7)" << endl; 
    cout << "Bottom right (8)" << endl; 
    cout << "Bottom left (9)" << endl; 
    p1M(); 


} 

void Game::p1M() 
{ 
    cin >> userMove; 
    updateBoardX(userMove); 

} 

void Game::p2M() 
{ 
    cin >> userMove; 
    updateBoardO(userMove); 
} 

void Game::updateBoardX(int m) 
{ 
    switch(userMove) 
    { 
case 1: 
    board[0][2] = 'x'; 
    printBoard(); 
    break; 
case 2: 
    board[0][0] = 'x'; 
    printBoard(); 
    break; 
case 3: 
    board[1][1] = 'x'; 
    printBoard(); 
    break; 
case 4: 
    board[0][1] = 'x'; 
    printBoard(); 
    break; 
case 5: 
    board[2][1] = 'x'; 
    printBoard(); 
    break; 
case 6: 
    board[1][2] = 'x'; 
    printBoard(); 
    break; 
case 7: 
    board[1][0] = 'x'; 
    printBoard(); 
    break; 
case 8: 
    board[2][2] = 'x'; 
    printBoard(); 
    break; 
case 9: 
    board[2][0] = 'x'; 
    printBoard(); 
    break; 
    } 

p2Turn(); 

} 
void Game::updateBoardO(int m2) 
{ 

    switch(userMove) 
    { 
case 1: 
    board[0][2] = 'o'; 
    printBoard(); 
    break; 
case 2: 
    board[0][0] = 'o'; 
    printBoard(); 
    break; 
case 3: 
    board[1][1] = 'o'; 
    printBoard(); 
    break; 
case 4: 
    board[0][1] = 'o'; 
    printBoard(); 
    break; 
case 5: 
    board[2][1] = 'o'; 
    printBoard(); 
    break; 
case 6: 
    board[1][2] = 'o'; 
    printBoard(); 
    break; 
case 7: 
    board[1][0] = 'o'; 
    printBoard(); 
    break; 
case 8: 
    board[2][2] = 'o'; 
    printBoard(); 
    break; 
case 9: 
    board[2][0] = 'o'; 
    printBoard(); 
    break; 
    } 

showMoves(); 

} 




void Game::p2Turn() 
{ 
    cout << "Alright player 2, your turn" << endl; 
    cout << endl; 
    cout << "Top right (1)" << endl; 
    cout << "Top left (2)" << endl; 
    cout << "Center (3)" << endl; 
    cout << "Center top (4) " << endl; 
    cout << "Center bottom (5)" << endl; 
    cout << "Center right (6) " << endl; 
    cout << "Center left (7)" << endl; 
    cout << "Bottom right (8)" << endl; 
    cout << "Bottom left (9)" << endl; 
    p2M(); 
} 


void Game::checkWinner(char b[][3]) 
{ 


    if(b[0][0]== 'x' and b[0][1]== 'x' and b[0][2]== 'x') 
    { 
      cout << "P1 wins!" << endl; 
      endGame(); 
    }else if(b[1][0]== 'x' and b[1][1]== 'x' and b[1][2]== 'x') 
    { 
      cout << "P1 wins!" << endl; 
      endGame(); 
    }else if(b[2][0]== 'x' and b[2][1]== 'x' and b[2][2]== 'x') 
    { 
      cout << "P1 wins!" << endl; 
      endGame(); 
    }else if(b[0][0]== 'x' and b[1][0]== 'x' and b[2][0]== 'x') 
    { 
      cout << "P1 wins!" << endl; 
      endGame(); 
    }else if(b[0][1]== 'x' and b[1][1]== 'x' and b[2][1]== 'x') 
    { 
      cout << "P1 wins!" << endl; 
      endGame(); 
    }else if(b[0][2]== 'x' and b[1][2]== 'x' and b[2][2]== 'x') 
    { 
      cout << "P1 wins!" << endl; 
      endGame(); 
    }else if(b[0][0]== 'x' and b[1][1]== 'x' and b[2][2]== 'x') 
    { 
      cout << "P1 wins!" << endl; 
      endGame(); 
    }else if(b[0][2]== 'x' and b[1][1]== 'x' and b[2][0]== 'x') 
    { 
      cout << "P1 wins!" << endl; 
      endGame(); 
    } else if(b[0][0]== 'o' and b[0][1]== 'o' and b[0][2]== 'o') 
    { 
      cout << "P2 wins!" << endl; 
      endGame(); 
    }else if(b[1][0]== 'o' and b[1][1]== 'o' and b[1][2]== 'o') 
    { 
      cout << "P2 wins!" << endl; 
      endGame(); 
    }else if(b[2][0]== 'o' and b[2][1]== 'o' and b[2][2]== 'o') 
    { 
      cout << "P2 wins!" << endl; 
      endGame(); 
    }else if(b[0][0]== 'o' and b[1][0]== 'o' and b[2][0]== 'o') 
    { 
      cout << "P2 wins!" << endl; 
      endGame(); 
    }else if(b[0][1]== 'o' and b[1][1]== 'o' and b[2][1]== 'o') 
    { 
      cout << "P2 wins!" << endl; 
      endGame(); 
    }else if(b[0][2]== 'o' and b[1][2]== 'o' and b[2][2]== 'o') 
    { 
      cout << "P2 wins!" << endl; 
      endGame(); 

    }else if(b[0][0]== 'o' and b[1][1]== 'o' and b[2][2]== 'o') 
    { 
      cout << "P2 wins!" << endl; 
      endGame(); 
    }else if(b[0][2]== 'o' and b[1][1]== 'o' and b[2][0]== 'o') 
    { 
      cout << "P1 wins!" << endl; 
      endGame(); 
    } 
} 
void Game::checkNoWinner(int c) 
{ 
    if(counter == 9) 
    { 
     cout << "No winner!" << endl; 
     endGame(); 
    } 
} 



int Game::endGame() 
{ char endG; 
    cout << "Play again? (y/n)" << endl; 
    cin >> endG; 
    if(endG=='n') 
    { 
     exit(0); 
    }else if(endG=='y') 
    { 
     Game(); 

    } 

return 0; 
} 
+0

我的眼睛!請按照[MCVE](http://stackoverflow.com/help/mcve) – 2014-09-23 16:12:24

+0

請不要發佈如此巨大的代碼負載。 – Chantola 2014-09-23 16:13:24

+0

大概您驗證用戶的移動某處。檢查單元格是否爲空,如果它已滿,則讓它們進入新的移動。 – 2014-09-23 16:15:01

回答

1

在updateBoardX和updateBoardO功能,你馬上設置板的一個元素的值。像:

board[0][0] = 'x'; 

我建議,在此之前,你檢查的值,如果它已經是「X」或「O」,看看如果元素已經由先前的移動佔據。例如:

if(board[0][2]=='x' || board[0][2]=='o') 
    //alert the user or something 
0

首先,檢查board [x] [y]是「o」還是「x」。如果是,那麼這不是合法的舉動。

if (board[x][y] == 'o' || board[x][y] == 'x') 
{ 
    // not a legal move 
} 

但是在執行此操作之前,您的代碼應該減少冗餘。例如,看看你的代碼,在一個棋盤上寫一個'x'或'o'。它與「x」和「o」字符唯一的區別幾乎相同。

好的程序員在他們的代碼中找到了模式,當發現時,嘗試並概括模式。在你的情況下,開始編寫一個函數,只是通過「X」或「O」作爲參數:

void Game::updateBoard(int m, char player) 
{ 
    switch(userMove) 
    { 
     case 1: 
      board[0][2] = player; 
      printBoard(); 
     break; 
     case 2: 
      board[0][0] = 'x'; 
      printBoard(); 
     break; 
     //... 
    } 
} 

所以現在不是調用updateBoardXupdateBoardY,你只需要調用updateBoard並通過其中的「x」或'y'作爲參數。

updateBoard(userMove, 'x'); // if it's x's move 

然後接下來的事情是簡化案例陳述,並可能消除它們。這可以通過將移動與棋盤上的x,y位置關聯來實現。爲此,可以使用std::pair<int,int>的數組。

我不會進入任何深度解讀,但你的updateBoard功能可以減少到這一點:

#include <map> 
//... 
using namespace std; 
//... 
void Game::updateBoard(int m, char player) 
{ 
    const std::pair<int, int> boardPos[] = {make_pair(0,2), make_pair(0,0), make_pair(1,1), 
              make_pair(0,1), make_pair(2,1), make_pair(1,2), 
              make_pair(1,0), make_pair(2,2), make_pair(2,0)}; 
    if (m >= 1 && m <= 10) 
    { 
     const std::pair<int,int>& pos = boardPos[m-1]; 
     board[pos.first][pos.second] = player; 
     printBoard(); 
    } 
} 

所以對眼睛容易得多。

您還有其他代碼冗餘,例如向玩家1或玩家2顯示提示。請注意,提示除了玩家號碼外是相同的。再次,編寫一個函數,並將播放器傳遞給函數,而不是編寫兩個單獨的函數。