类中的 C++ int 被设置为值,似乎不知从何而来
c++ int in class gets set to value, seemingly out of nowhere
在某些条件下,int winner
应该设置为 2,但它以某种方式被设置为各种更高的值,最常见的是 6。我不知道这是怎么发生的,因为我的类中没有其他函数会影响winner
,而且该程序中甚至没有提到该变量。最让我困惑的是,我有一个几乎相同的函数(P2Move()
(,它在将winner
变量设置为P1Move()
的方式上实际上是相同的,并且该函数完美运行。
一些信息:这是一部分的类称为 Board,它充当由 Square 类对象组成的棋盘数组。
下面是导致问题的函数。在底部附近,语句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
类模板提供了一种非常简单的方法来了解您是否以及在哪里可能具有越界访问权限(如注释中建议的那样(:
不要使用operator[]
访问向量元素,而是更改代码以使用.at()
成员函数。.at()
是边界检查,如果您访问越界(而不是静默地破坏程序(,则会引发异常。
在生产代码中,通常首选operator[]
,因为省略边界检查更有效。但是在学习的同时,.at()
可以为您提供很多帮助。
此外,养成使用代码检查器(如 valgrind 或assert
宏(来检查假设的习惯是一件好事,即使您已经过了不再使用.at()
的地步。
相关文章:
- 为什么在全局范围内使用"extern int a"似乎不行?
- int(c) 和 c-'0' 之间的区别。C++
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 是否可以从int转换为enum类类型
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 'short int'持有的值溢出,但"自动"不会溢出?
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 调用'begin(int [n])'没有匹配函数
- 没有显式声明的int[]中的foreach
- 在c++中访问int到类对象的映射时出错
- 为什么我无法更改"set<set>"循环中的值<int>
- 长 长 int 不要 长 int 好
- C++程序在循环后给出奇怪的int值
- 如何计算数据类型的范围,例如int
- 如果"new int"返回"int*",那么为什么"new int[n]"不返回"int**"?
- 如何在cpp.中使用协议缓冲区存储大缓冲区/数组(char/int)