2017-04-20 54 views
0

我有一個隨機生成的大小爲gameSize x gameSize(用戶輸入)的數字網格,它包含在矢量向量中。用戶可以輸入兩個座標(x,y),以便將網格內的數字更改爲預定義的值。C++控制檯保存並加載保存的「遊戲」

因此,例如,用戶輸入,X:0 Y:0:

{9, 7, 9} 

{9, 6, 8} 

{5, 1, 4} 

變爲:

{0, 7, 9} <-- Changes position 0,0 to 0 (the predefined value) 

{9, 6, 8} 

{5, 1, 4} 

我試圖找出如何使它使用戶可以保存當前的電路板狀態並在以後訪問它。我知道我需要以某種方式將遊戲(myGame)保存到一個文件中,這樣我就可以訪問它並將其重新加載到控制檯應用程序中,從本質上保存並重新啓動保存的遊戲,但我不知道從哪裏開始。

+0

我會從輸入和輸出文件流開始。如果你有一本教科書,應該有一個文件輸入和輸出部分。然後就是將一系列數字打印到一個文件中,然後在加載過程中將它們讀回來 – jdow

+0

如果要保存/加載矢量矢量,則必須將內部矢量大小「烘烤」爲文件格式。否則,加載程序無法適當地恢復內部向量。在你的情況下,內部矢量似乎總是相同的大小。這簡化了一些事情:第一,我會使用其他修正大小的東西(例如一個結構體)。對於具有修訂大小的元素向量的第二個文件I/O更容易(並且可以像已經提出的那樣直接向前輸入/輸出流)完成。然而,第二個arg。甚至會適用於您當前的數據模型。 – Scheff

回答

1

您可以使用來自標準庫的fstream,並添加特殊的方法,以你的遊戲類,這裏是工作示例:

#include <fstream> 
#include <iostream> 
#include <string> 
#include <vector> 

using namespace std; 

class Game 
{ 
public: 
    Game(int gameSize) : size(gameSize), field(size, vector<int>(size)) 
    { 
     //Randomize(); //generate random numbers 
//just filling example for test 
     for (int i = 0; i < size; i++) { 
      for (int j = 0; j < size; j++) { 
       field[i][j] = i * size + j; 
      } 
     } 
    } 

    Game(string filename) { 
     Load(filename); 
    } 

    void Load(string filename) { 
     fstream in; 
     in.open(filename, fstream::in); 
     in >> size; 
     field.resize(size, vector<int>(size)); 
     for (int i = 0; i < size; i++) { 
      for (int j = 0; j < size; j++) { 
       in >> field[i][j]; 
      } 
     } 
     in.close(); 
    } 

    void Save(string filename) { 
     fstream out; 
     out.open(filename, fstream::out); 
     out << size << endl; 
     for (int i = 0; i < size; i++) { 
      for (int j = 0; j < size; j++) { 
       out << field[i][j] << " "; 
      } 
      out << endl; //for user friendly look of file 
     } 
     out.close(); 
    } 

private: 
    int size; 
    vector<vector<int>> field; 
}; 

int main() { 
    Game game(3); 
    game.Save("game.txt"); 
    game.Load("game.txt"); 
    game.Save("game2.txt"); 

    return 0; 
} 

不要忘了在文件中存儲遊戲大小的閱讀舒適。如果你想加載已經存儲的遊戲,那麼爲你的類添加size屬性並且有另一個構造函數是很好的。此外,如果添加一些檢查文件格式適當的話會更好。 如果他們不在那裏,你可以將所有轉成邏輯的方法添加到Game類中作爲方法。祝你好運!

0

首先,你應該閱讀關於CSV格式。要求用戶爲你的遊戲設置一個名稱,然後將數組保存到這樣的文件中:
- 1每行保存一次。
- 行以保存名稱
開頭 - 接下來的兩個值分別代表大小X和大小Y.
- 直到行結束的下一個值代表數組數據。
加載保存遊戲進行這樣的:
- 用戶提供的可用列表保存
- 用戶輸入其保存打算加載
- 應用程序加載這樣的數據:搜索的文件,其中包含行它打算加載的名稱,讀取大小x和大小y以初始化該大小的數組,將內容加載到數組中。

+0

爲什麼要將CSV用於這麼簡單的任務?他也可以使用json來描述一個遊戲並從服務器加載它,但我認爲這超出了現在的項目範圍。 :) –

+0

因爲他陳述了控制檯應用程序...和CSV代表逗號分隔值。如果這是我的應用程序,我會使用XML,有些庫可以解釋XML並使您的生活更加輕鬆,同時使用CSV格式,這意味着您可以從此應用程序中學到一些東西。同樣在一個單獨的文件中,您可以存儲多個保存...使用您的方法,它可以存儲1個保存/文件。 –

1

保存一行一行,每行一個行:

void Game::save(std::istream& s) 
{ 
    for (const auto& row: myGame) 
    { 
     for (auto cell: row) 
     { 
      s << cell << ' '; 
     } 
     s << '\n'; 
    } 
} 

一行然後讀回線和創建行,當您去:

void Game::load(std::istream& s) 
{ 
    myGame.clear(); 
    std::string line; 
    while (std::getline(s, line)) 
    { 
     std::istringstream cells(line); 
     std::vector<int> row; 
     int cell = 0; 
     while (cells >> cell) 
     { 
      row.push_back(cell); 
     } 
     myGame.push_back(row); 
    } 
} 

行分離成線意味着你不需要跟蹤長度。
使用istream&ostream&參數意味着你不僅限於使用的文件,但可以使用任何流,像stringstream,或cincout
後者可以派上用場進行調試。