2016-09-21 52 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