如何阻止char变量被覆盖?

时间:2014-09-23 16:10:34

标签: c++ arrays char multidimensional-array tic-tac-toe

我正在用C ++制作一个2人的tic tac toe游戏,我目前正在解决一些与之相关的问题。所以程序完成除了1个微小的细节,玩家可以覆盖其他玩家的动作。因此,如果我们有玩家1(“x”)和玩家2(“o”),玩家1可以在“o”上放置“x”,从而消除玩家2的移动!我想知道是否有任何方法可以阻止这种情况发生,我在我的“电路板”上使用了二维数组:

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;
}

2 个答案:

答案 0 :(得分:1)

在updateBoardX和updateBoardO函数中,您可以立即设置电路板元素的值。像:

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

我建议在此之前检查值是否已经是'x'或'o'以查看该元素是否已被前一次移动占用。例如:

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

答案 1 :(得分:0)

首先,检查一下[x] [y]是否是&#39; o&#39;或者&#39; x&#39;。如果是,那么这不是一个合法的举动。

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

但在此之前,您的代码应该减少冗余。例如,查看您的代码以编写&#39; x&#39;或者是&#39; o在董事会的位置。它几乎完全相同,唯一的区别是&#39; x&#39;和&#39; o&#39;字符。

优秀的程序员在他们的代码中找到模式,并在找到时尝试并概括模式。在您的情况下,首先编写一个函数,然后通过&#39; x&#39;或者&#39; o&#39; 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;
        //...
    }
}

现在,您只需致电updateBoardX,然后通过&#39; x&#39;而不是致电updateBoardYupdateBoard。或者&#39; y&#39;作为参数。

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

然后接下来就是简化case语句并可能消除它们。这可以通过将移动与板上的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显示提示。请注意除了播放器编号外,提示相同。再次,编写一个函数,并将播放器传递给函数,而不是编写两个单独的函数。