我正在用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;
}
答案 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;而不是致电updateBoardY
或updateBoard
。或者&#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显示提示。请注意除了播放器编号外,提示相同。再次,编写一个函数,并将播放器传递给函数,而不是编写两个单独的函数。