当我运行ComputerVsComputer时,tic-tac-toe板都是空的。我研究过像试图找出原因一样。我怀疑它与范围有一些关系;但是,我迷失在C ++中并且无法理解它。帮助
TicTacToe.h
#include <iostream>
using namespace std;
class TicTacToeBoard{
public:
TicTacToeBoard(){
for(int x=0; x<9; x++){
board[x]='\0';
}
}
void printBoard(){
cout << endl << board[0] << " |" << board[1] << " |" << board[2] << endl;
cout << "--"<< "|--|" << "--" << endl;
cout << board[3] << " |" << board[4] << " |" << board[5] << endl;
cout << "--" << "|--|" << "--" << endl;
cout << board[6] << " |" << board[7] << " |" << board[8] << endl << endl;
}
char board[9];
string name;
};
class TicTacToePlayer
{
public:
TicTacToePlayer(int isFirstPlayer, TicTacToeBoard& newboard)
: board(newboard)
{
if(isFirstPlayer)
symbol = 'X';
else
symbol = 'O';
}
/* user made move */
void makeMove(int m, int n){
board.board[getIndexRef(m,n)] = symbol;
board.printBoard();
};
/* computer made move */
void automateMove(){
for(int x=0; x<9; x++){
if(board.board[x]=='\0'){
board.board[x]=OpponentSymbol();
break;
}
}
};
/* checks if position in the board is ocupied,
returns 1 for occupied
0 for not occupied */
int checkPoss(int m, int n){
int indexRef;
//if((m>=0 && m<4) && (n>=0 && n<4)){
indexRef = getIndexRef(m,n);
if( board.board[indexRef]=='X' || board.board[indexRef]=='O' ){
return 1;
} else {
return 0;
}
//}
};
/* checks and prints the status of game,
with the help of checkWin()
retuns 0 for inprogress
1 for end of game */
int checkGameStatus(){
int privateStatus = checkWin();
if(privateStatus==0){
if(symbol=='X'){
cout << endl << "You win!" << endl;
} else {
cout << endl << "You lose :(" << endl;
}
return 1;
} else if(privateStatus==1){
if(symbol=='O'){
cout << endl << "You win!" << endl;
} else {
cout << endl << "You lose :(" << endl;
}
return 1;
} else if(privateStatus==2){
cout << endl << "Draw!" << endl;
return 1;
} else {
cout << endl << "The game is in progress! Continue." << endl;
return 0;
}
};
private:
/* Use an appropriate data structure
for storing the board */
TicTacToeBoard board;
char symbol;
/* Checks who won
returns 0 for X win
1 for O win
2 for draw */
int checkWin(){
// check the verticals
if((checkSlots(1,1,'X') && checkSlots(2,1,'X') && checkSlots(3,1,'X')) || (checkSlots(1,2,'X') && checkSlots(2,2,'X') && checkSlots(3,2,'X')) || (checkSlots(1,3,'X') && checkSlots(2,3,'X') && checkSlots(3,3,'X'))){
return 0;
}
// check horizontals
if((checkSlots(1,1,'X') && checkSlots(1,2,'X') && checkSlots(1,3,'X')) || (checkSlots(2,1,'X') && checkSlots(2,2,'X') && checkSlots(2,3,'X')) || (checkSlots(3,1,'X') && checkSlots(3,2,'X') && checkSlots(3,3,'X'))){
return 0;
}
// check diagonals
if((checkSlots(1,1,'X') && checkSlots(2,2,'X') && checkSlots(3,3,'X')) || (checkSlots(3,1,'X') && checkSlots(2,2,'X') && checkSlots(3,1,'X'))){
return 0;
}
// check verticals
if((checkSlots(1,1,'O') && checkSlots(2,1,'O') && checkSlots(3,1,'O')) || (checkSlots(1,2,'O') && checkSlots(2,2,'O') && checkSlots(3,2,'O')) || (checkSlots(1,3,'O') && checkSlots(2,3,'O') && checkSlots(3,3,'O'))){
return 1;
}
// check horizontals
if((checkSlots(1,1,'O') && checkSlots(1,2,'O') && checkSlots(1,3,'O')) || (checkSlots(2,1,'O') && checkSlots(2,2,'O') && checkSlots(2,3,'O')) || (checkSlots(3,1,'O') && checkSlots(3,2,'O') && checkSlots(3,3,'O'))){
return 1;
}
// check diagonals
if((checkSlots(1,1,'O') && checkSlots(2,2,'O') && checkSlots(3,3,'O')) || (checkSlots(3,1,'O') && checkSlots(2,2,'O') && checkSlots(3,1,'O'))){
return 1;
}
// to check if it is a draw, confirm that all slots are filled
for(int x=0; x<9; x++){
if(board.board[x]=='\0'){
return 3; // 3 is neither a win nor a draw
}
}
// if the function hasn't returned by this point, it's a draw
return 2;
}
bool checkSlots(int m, int n, char testSymbol){
return board.board[getIndexRef(m,n)]==testSymbol;
}
int getIndexRef(int row, int col){
int indexRef;
if((row>=0 && row<4) && (col>=0 && col<4)){
if(row==1) {
indexRef = col-1; // col is always 1, 2, or 3, so get board[0], board[1], or board[2]
} else if(row==2) {
indexRef = row+col; // always 2+1, 2+2, or 2+3, or boards 3,4,5
} else if(row==3) {
indexRef = row+col+2; // always 3+1+2, 3+2+2, or 3+3+2, or 6,7,8
}
return indexRef;
} else {
return 99; // error
}
}
char OpponentSymbol(){
if(symbol=='X'){
return 'O';
} else {
return 'X';
}
}
};
现在是ComputerVsComputer
#include <iostream>
#include "TicTacToe.h"
using namespace std;
int main()
{
TicTacToeBoard gameboard;
gameboard.name = "Boo";
TicTacToePlayer player1(true, gameboard);
TicTacToePlayer player2(false, gameboard);
gameboard.printBoard();
while (1)
{
player1.automateMove();
if (player1.checkGameStatus())
{
gameboard.printBoard();
break;
}
gameboard.printBoard();
player2.automateMove();
if (player2.checkGameStatus())
{
gameboard.printBoard();
break;
}
gameboard.printBoard();
}
return 0;
}
答案 0 :(得分:1)
TicTacToePlayer
获取TicTacToeBoard
按值,这意味着它会在每个TicTacToePlayer
对象中复制。当您修改副本时,只修改副本而不是原始副本。
您需要通过引用传递它:
TicTacToePlayer(int isFirstPlayer, TicTacToeBoard& newboard);
并且还要将成员board
作为参考:
TicTacToeBoard& board;
但是,您无法分配引用,需要对其进行初始化,而使用构造函数初始化列表进行初始化:
TicTacToePlayer(int isFirstPlayer, TicTacToeBoard& newboard)
: board(newboard)
{
...
}
现在player1
和player2
都会引用gameboard
变量,而一个玩家对象的更改会更改gameboard
对象。