class 中的 c++ int 被设置为值,似乎无处不在
c++ int in class gets set to value, seemingly out of nowhere
int winner
在某些情况下应该设置为 2,但不知何故它被设置为各种更高的值,最常见的是 6。我不知道这是怎么发生的,因为没有其他功能在影响 winner
的 class 中,甚至在程序的其他任何地方都没有提到该变量。最让我困惑的是,我有一个几乎相同的函数 (P2Move()
),它在如何将 winner
变量设置为 P1Move()
方面完全相同,并且该函数运行完美。
一些信息:class 这是其中的一部分,称为棋盘,它充当由方形 class 对象组成的棋盘阵列。
下面是导致问题的函数。在底部附近,语句 else if((canTake.size()==0)&&(canMove.size()==0)) {Board::winner = 2;}
导致了问题。当我从函数中删除有问题的部分时,其他一切似乎都能正常工作,但我需要该部分正常工作才能提交最终项目。
void Board::P1Move()
{
P1pieces = 0;
std::vector <Move> canMove;
std::vector <Move> canTake;
for(int j = 0; j < bSize; j++)
{ //Start of j loop.
for(int i = 0; i < bSize; i++)
{ //Start of i loop.
Square sq = board[i][j];
bool cTakeL = canTakeL(i,j);
bool cTakeR = canTakeR(i,j);
bool cMoveL = canMoveL(i,j);
bool cMoveR = canMoveR(i,j);
if(board[i][j].getPl() == P1)
{
P1pieces++;
if(cTakeL)
{
Move a = Move(sq.getIndex(),board[i-2][j+2].getIndex(),board[i-1][j+1].getIndex(),0);
canTake.push_back(a);
}
if(cTakeR)
{
Move b = Move(sq.getIndex(),board[i+2][j+2].getIndex(),board[i+1][j+1].getIndex(),0);
canTake.push_back(b);
}
if(cMoveL)
{
Move c = Move(sq.getIndex(),board[i-1][j+1].getIndex(),0,0);
canMove.push_back(c);
}
if(cMoveR)
{
Move d = Move(sq.getIndex(),board[i+1][j+1].getIndex(),0,0);
setWinner(d.getSpos());
canMove.push_back(d);
}
}
} //End of i loop.
} //End of j loop.
if(canTake.size()!=0)
{
time_t t;
time(&t);
srand(t);
int moveNum = rand()%canTake.size();
std::string output = "p1 ";
Move out = canTake.at(moveNum);
int i = 0;
int j = 0;
for(int y = 0; y < bSize; y++)
{
for(int x = 0; x < bSize; x++)
{
if(board[x][y].getIndex()==out.getSpos())
{
i = x;
j = y;
}
}
}
if(board[i-2][j+2].getIndex()==out.getEndPos())
{
board[i-2][j+2].setOcc(true);
board[i-2][j+2].setPl(P1);
board[i-1][j+1].setOcc(false);
board[i-1][j+1].setPl(NA);
}
else if(board[i+2][j+2].getIndex()==out.getEndPos())
{
board[i+2][j+2].setOcc(true);
board[i+2][j+2].setPl(P1);
board[i+1][j+1].setOcc(false);
board[i+1][j+1].setPl(NA);
}
output = output + out.toString();
setCmove(output);
board[i][j].setOcc(false);
board[i][j].setPl(NA);
}
else if(canMove.size()!=0)
{
time_t t;
time(&t);
srand(t);
int moveNum = rand()%canMove.size();
std::string output = "p1 ";
Move out = canMove.at(moveNum);
int i = 0;
int j = 0;
for(int y = 0; y < bSize; y++)
{
for(int x = 0; x < bSize; x++)
{
if(board[x][y].getIndex()==out.getSpos())
{
i = x;
j = y;
}
}
}
if(board[i-1][j+1].getIndex()==out.getEndPos())
{
board[i-1][j+1].setOcc(true);
board[i-1][j+1].setPl(P1);
}
else if(board[i+1][j+1].getIndex()==out.getEndPos())
{
board[i+1][j+1].setOcc(true);
board[i+1][j+1].setPl(P1);
}
output = output + out.toString();
setCmove(output);
board[i][j].setOcc(false);
board[i][j].setPl(NA);
}
else if((canTake.size()==0)&&(canMove.size()==0))
{
Board::winner = 2;
}
P1pieces = canTake.size() + canMove.size();
}
您正在与 std::vector
合作,这是一件好事。 (太多初学者 "C++" 代码使用 C 数组。)vector
class 模板提供了一种非常简单的方法来找出您是否以及在何处可能有越界访问(正如评论中所建议的那样):
不要使用 operator[]
访问向量元素,而是更改代码以使用 .at()
成员函数。 .at()
是边界检查,如果您越界访问(而不是默默地破坏您的程序),将抛出异常。
在生产代码中,operator[]
通常是首选,因为省略边界检查效率更高。但是在学习的过程中,.at()
可以帮到你很多。
此外,养成使用 valgrind or the assert
宏之类的代码检查器来检查您的假设的习惯是一件好事,即使您已经过了不再使用 .at()
的地步.
int winner
在某些情况下应该设置为 2,但不知何故它被设置为各种更高的值,最常见的是 6。我不知道这是怎么发生的,因为没有其他功能在影响 winner
的 class 中,甚至在程序的其他任何地方都没有提到该变量。最让我困惑的是,我有一个几乎相同的函数 (P2Move()
),它在如何将 winner
变量设置为 P1Move()
方面完全相同,并且该函数运行完美。
一些信息:class 这是其中的一部分,称为棋盘,它充当由方形 class 对象组成的棋盘阵列。
下面是导致问题的函数。在底部附近,语句 else if((canTake.size()==0)&&(canMove.size()==0)) {Board::winner = 2;}
导致了问题。当我从函数中删除有问题的部分时,其他一切似乎都能正常工作,但我需要该部分正常工作才能提交最终项目。
void Board::P1Move()
{
P1pieces = 0;
std::vector <Move> canMove;
std::vector <Move> canTake;
for(int j = 0; j < bSize; j++)
{ //Start of j loop.
for(int i = 0; i < bSize; i++)
{ //Start of i loop.
Square sq = board[i][j];
bool cTakeL = canTakeL(i,j);
bool cTakeR = canTakeR(i,j);
bool cMoveL = canMoveL(i,j);
bool cMoveR = canMoveR(i,j);
if(board[i][j].getPl() == P1)
{
P1pieces++;
if(cTakeL)
{
Move a = Move(sq.getIndex(),board[i-2][j+2].getIndex(),board[i-1][j+1].getIndex(),0);
canTake.push_back(a);
}
if(cTakeR)
{
Move b = Move(sq.getIndex(),board[i+2][j+2].getIndex(),board[i+1][j+1].getIndex(),0);
canTake.push_back(b);
}
if(cMoveL)
{
Move c = Move(sq.getIndex(),board[i-1][j+1].getIndex(),0,0);
canMove.push_back(c);
}
if(cMoveR)
{
Move d = Move(sq.getIndex(),board[i+1][j+1].getIndex(),0,0);
setWinner(d.getSpos());
canMove.push_back(d);
}
}
} //End of i loop.
} //End of j loop.
if(canTake.size()!=0)
{
time_t t;
time(&t);
srand(t);
int moveNum = rand()%canTake.size();
std::string output = "p1 ";
Move out = canTake.at(moveNum);
int i = 0;
int j = 0;
for(int y = 0; y < bSize; y++)
{
for(int x = 0; x < bSize; x++)
{
if(board[x][y].getIndex()==out.getSpos())
{
i = x;
j = y;
}
}
}
if(board[i-2][j+2].getIndex()==out.getEndPos())
{
board[i-2][j+2].setOcc(true);
board[i-2][j+2].setPl(P1);
board[i-1][j+1].setOcc(false);
board[i-1][j+1].setPl(NA);
}
else if(board[i+2][j+2].getIndex()==out.getEndPos())
{
board[i+2][j+2].setOcc(true);
board[i+2][j+2].setPl(P1);
board[i+1][j+1].setOcc(false);
board[i+1][j+1].setPl(NA);
}
output = output + out.toString();
setCmove(output);
board[i][j].setOcc(false);
board[i][j].setPl(NA);
}
else if(canMove.size()!=0)
{
time_t t;
time(&t);
srand(t);
int moveNum = rand()%canMove.size();
std::string output = "p1 ";
Move out = canMove.at(moveNum);
int i = 0;
int j = 0;
for(int y = 0; y < bSize; y++)
{
for(int x = 0; x < bSize; x++)
{
if(board[x][y].getIndex()==out.getSpos())
{
i = x;
j = y;
}
}
}
if(board[i-1][j+1].getIndex()==out.getEndPos())
{
board[i-1][j+1].setOcc(true);
board[i-1][j+1].setPl(P1);
}
else if(board[i+1][j+1].getIndex()==out.getEndPos())
{
board[i+1][j+1].setOcc(true);
board[i+1][j+1].setPl(P1);
}
output = output + out.toString();
setCmove(output);
board[i][j].setOcc(false);
board[i][j].setPl(NA);
}
else if((canTake.size()==0)&&(canMove.size()==0))
{
Board::winner = 2;
}
P1pieces = canTake.size() + canMove.size();
}
您正在与 std::vector
合作,这是一件好事。 (太多初学者 "C++" 代码使用 C 数组。)vector
class 模板提供了一种非常简单的方法来找出您是否以及在何处可能有越界访问(正如评论中所建议的那样):
不要使用 operator[]
访问向量元素,而是更改代码以使用 .at()
成员函数。 .at()
是边界检查,如果您越界访问(而不是默默地破坏您的程序),将抛出异常。
在生产代码中,operator[]
通常是首选,因为省略边界检查效率更高。但是在学习的过程中,.at()
可以帮到你很多。
此外,养成使用 valgrind or the assert
宏之类的代码检查器来检查您的假设的习惯是一件好事,即使您已经过了不再使用 .at()
的地步.