2016-09-21 64 views
1

这是一个真正的简单问题。我正在写一个滑块益智游戏进行练习。C++矢量值不断变化?

1, 1, 1, 1, 1, 
1, 0, 3, 4, 1, 
1, 0, 2, 2, 1, 
1, 1, 1, 1, 1, 

它接收输入如在上述形式中,用“0”表示空的空间,“1”表示墙壁,和所有其他的数字表示的块。

下面是类定义和构造用于游戏状态:

class GameState { 

    public: 
     GameState(int hght, int wdth); 
     GameState(const GameState &obj); 
     ~GameState(); 
     int getHeight(); 
     int getWidth(); 
     int getElem(int i, int j); 
     void setElem(int i, int j, int val); 
     void display(); 
     void readFile(char* filename); 
     bool checkSolved(); 
     map<int, vector<int*> > blockLocations; 
     vector<int> blockList; 
     void getBlockLocations(); 
     void findBlock(int n); 
    private: 
     int **grid; 
     int height, width; 
     void allocate() { 
     grid = new int*[height]; 
     for(int i = 0; i < height; i++) 
     { 
      grid[i] = new int[width]; 
     } 
     } 
}; 

GameState::GameState(int hght, int wdth) { 
    height = hght; 
    width = wdth; 
    allocate(); 
    for(int i = 0; i < hght; i++) { 
     for (int j = 0; j < wdth; j++) { 
     grid[i][j] = 0; 
     } 
    } 
}; 

本质上,网格由整数的二维指针数组来表示。 heightwidth是不言自明的; blockLocations是一个将块编号映射到其形式(y,x)的逐点坐标的映射。目前,如果一个块占据多个空间,则只列出最右端的空间。矩阵初始化为零而不是零;实际值从csv读入。

所有这些方法都已定义,但两种关注方法是getBlockLocations()findBlock(int n)

void GameState::getBlockLocations() { 
    for (int i = 0; i < height; i++) { 
     for (int j = 0; j < width; j++) { 
     blockList.push_back(grid[i][j]); 
     int pos[2] = {i, j}; 
     vector<int*> v; 
     v.push_back(pos); 
     blockLocations[grid[i][j]] = v; 
     } 
    } 
} 

void GameState::findBlock(int n) { 
    vector<int>::iterator it; 
    it = find(blockList.begin(), blockList.end(), n); 
    if (it != blockList.end()) { 
     vector<int*> * posList = &blockLocations[n]; 
     for (int itr = 0; itr < posList->size(); itr++) { 
     vector<int*> curPos = *posList; 
     cout << curPos[itr][0] << ", " << curPos[itr][1] << endl; 
     } 
    } 
} 

当我真正运行这个时出现问题。作为一个例子,当我运行getBlockLocations()时,它将'2'的坐标正确存储为(2,3)。但是,当我要求程序使用findBlock(2)显示该块的位置时,生成的输出是沿着(16515320,0)行的东西。每次都不一样,但从不正确。我没有看到指针错误,我正在做出这样的错误值。

+0

[OT]:对于矩阵,宁可'的std ::矢量超过'矢量<性病::矢量>''上INT **''。 (第一个需要简单的数学变换索引如想)。 – Jarod42

+0

[OT]:'std :: map'有它自己的'find'功能。看起来你可能想花时间在C++中研究'iterators'和'references'。另请参阅http://pastebin.com/hJ4Frmep – kfsone

回答

2

这是不好的:

for (int j = 0; j < width; j++) { 
    blockList.push_back(grid[i][j]); 
    int pos[2] = {i, j}; 
    vector<int*> v; 
    v.push_back(pos); 
    blockLocations[grid[i][j]] = v; 
    } 

您在本地创建一个pos变量和存储其参考。当你超出for循环的范围时,它是无效的/数据可以被别的东西替代。

(居然Barmar指出,由于pos地址总是在循环中一样,值在每次迭代变化)

你可以使用一个std::pair<int,int>来存储你的价值观来代替。 在向量中插入该对时,数据将被复制,而不仅仅是指针:它是安全的。

typedef std::pair<int,int> IntIntPair; 

IntIntPair pos(i,j); 
std::vector<IntIntPair> v; 
+0

至于他的问题,'for'循环的每次迭代都会结束并重新启动范围。所以它可以在每次循环中使用相同的地址。 – Barmar

+0

是的,因为地址不变。 –

+0

我想我不明白如何使用不同的数据类型去除你描述的行为?我承认我通常使用Python编写代码,所以这对我来说有点新意。编辑:无论如何,无论如何谢谢。 – user3025945