• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

eric15342335 / comp2113-engg1340-group-project / #16

13 Jun 2024 02:07AM UTC coverage: 73.489% (+6.4%) from 67.084%
#16

push

travis-ci

web-flow
Coverall Integration (#140)

Test case coverage

1447 of 1969 relevant lines covered (73.49%)

706.77 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.08
/src/file_io.cpp
1
/// @file file_io.cpp
2
/// Implementation of the file input/output functions.
3
/*
4
This program is free software: you can redistribute it and/or modify it under the
5
terms of the GNU Lesser General Public License as published by the Free Software
6
Foundation, either version 3 of the License, or (at your option) any later version.
7

8
This program is distributed in the hope that it will be useful, but WITHOUT ANY
9
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
11

12
You should have received a copy of the GNU Lesser General Public License along with this
13
program. If not, see <https://www.gnu.org/licenses/>.
14
*/
15

16
#include "file_io.h"
17

18
#include <algorithm>
19
#include <filesystem>
20
#include <fstream>
21
#include <iostream>
22
using namespace std;
23

24
const std::string USER_SAVE_OPTION::NEW_GAME = "0";
25
const std::string USER_SAVE_OPTION::LOAD_GAME = "1";
26
const std::string USER_SAVE_OPTION::DELETE_GAME = "2";
27
const std::string USER_SAVE_OPTION::EXIT_GAME = "3";
28
const std::string USER_SAVE_OPTION_PROMPT =
29
    "Please enter.\n" + USER_SAVE_OPTION::NEW_GAME + " for new save,\n" +
30
    USER_SAVE_OPTION::LOAD_GAME + " for loading old save(s),\n" +
31
    USER_SAVE_OPTION::DELETE_GAME + " for deleting save,\n" +
32
    USER_SAVE_OPTION::EXIT_GAME + " to quit: ";
33

34
vector<string> parseLogo(void) {
7✔
35
    vector<string> logo;
7✔
36
    // clang-format off
37
    logo.reserve(27);
7✔
38
    logo.emplace_back(R"(            __                       __)");
7✔
39
    logo.emplace_back(R"(           |  \                     |  \)");
7✔
40
    logo.emplace_back(R"(  _______ _| $$_    ______   _______| $$   __)");
7✔
41
    logo.emplace_back(R"( /       |   $$ \  /      \ /       | $$  /  \)");
7✔
42
    logo.emplace_back(R"(|  $$$$$$$\$$$$$$ |  $$$$$$|  $$$$$$| $$_/  $$)");
7✔
43
    logo.emplace_back(R"( \$$    \  | $$ __| $$  | $| $$     | $$   $$)");
7✔
44
    logo.emplace_back(R"( _\$$$$$$\ | $$|  | $$__/ $| $$_____| $$$$$$\)");
7✔
45
    logo.emplace_back(R"(|       $$  \$$  $$\$$    $$\$$     | $$  \$$\)");
7✔
46
    logo.emplace_back(R"( \$$$$$$$    \$$$$  \$$$$$$  \$$$$$$$\$$   \$$)");
7✔
47
    logo.emplace_back(R"(                                __                 __)");
7✔
48
    logo.emplace_back(R"(                               |  \               |  \)");
7✔
49
    logo.emplace_back(R"( ______ ____   ______   ______ | $$   __  ______ _| $$_)");
7✔
50
    logo.emplace_back(R"(|      \    \ |      \ /      \| $$  /  \/      |   $$ \)");
7✔
51
    logo.emplace_back(R"(| $$$$$$\$$$$\ \$$$$$$|  $$$$$$| $$_/  $|  $$$$$$\$$$$$$)");
7✔
52
    logo.emplace_back(R"(| $$ | $$ | $$/      $| $$   \$| $$   $$| $$    $$| $$ __)");
7✔
53
    logo.emplace_back(R"(| $$ | $$ | $|  $$$$$$| $$     | $$$$$$\| $$$$$$$$| $$|  \)");
7✔
54
    logo.emplace_back(R"(| $$ | $$ | $$\$$    $| $$     | $$  \$$\\$$     \ \$$  $$)");
7✔
55
    logo.emplace_back(R"( \$$  \$$  \$$ \$$$$$$$\$$      \$$   \$$ \$$$$$$$  \$$$$)");
7✔
56
    logo.emplace_back(R"(          __                       __           __)");
7✔
57
    logo.emplace_back(R"(         |  \                     |  \         |  \)");
7✔
58
    logo.emplace_back(R"(  _______ \$$______ ____  __    __| $$ ______ _| $$_    ______   ______)");
7✔
59
    logo.emplace_back(R"( /       |  |      \    \|  \  |  | $$|      |   $$ \  /      \ /      \)");
7✔
60
    logo.emplace_back(R"(|  $$$$$$| $| $$$$$$\$$$$| $$  | $| $$ \$$$$$$\$$$$$$ |  $$$$$$|  $$$$$$\)");
7✔
61
    logo.emplace_back(R"( \$$    \| $| $$ | $$ | $| $$  | $| $$/      $$| $$ __| $$  | $| $$   \$$)");
7✔
62
    logo.emplace_back(R"( _\$$$$$$| $| $$ | $$ | $| $$__/ $| $|  $$$$$$$| $$|  | $$__/ $| $$)");
7✔
63
    logo.emplace_back(R"(|       $| $| $$ | $$ | $$\$$    $| $$\$$    $$ \$$  $$\$$    $| $$)");
7✔
64
    logo.emplace_back(R"( \$$$$$$$ \$$\$$  \$$  \$$ \$$$$$$ \$$ \$$$$$$$  \$$$$  \$$$$$$ \$$      )");
7✔
65
    // clang-format on
66
    return logo;
7✔
67
}
×
68

69
void createplayer(string & playerName) {
3✔
70
    ofstream fout;
3✔
71
    string savefolder =
72
        SAVE_FOLDER_PREFIX; // create folder when it does not exist (first run)
3✔
73
    string foldername;
3✔
74
    filesystem::create_directory(SAVE_FOLDER_PREFIX);
3✔
75
    cout << "Enter player name:" << endl;
3✔
76
    getline(cin, playerName);
3✔
77
    foldername = SAVE_FOLDER_PREFIX + playerName;
3✔
78
    while ((filesystem::exists(foldername) || playerName.find(' ') != string::npos) ||
10✔
79
           playerName.empty()) { // check whether file already exists
3✔
80
        if (!playerName.empty()) {
4✔
81
            cout << "Invalid Playername. ";
1✔
82
            cout << "Playername should not contain spaces or cannot be the same as "
83
                    "existing ";
1✔
84
            cout << "playername" << endl << "Please enter a new player name: " << endl;
1✔
85
        }
86
        getline(cin, playerName);
4✔
87
        foldername = SAVE_FOLDER_PREFIX + playerName;
4✔
88
    }
89
    filesystem::create_directory(foldername); // create a empty folder for new save
3✔
90
}
3✔
91

92
void load_hsi(std::vector<float> & hsi_history, const string & playerName) {
2✔
93
    std::string filesave =
94
        SAVE_FOLDER_PREFIX + playerName + "/hsi" + SAVE_FILE_EXTENSION_TXT;
4✔
95
    std::ifstream fin;
2✔
96
    fin.open(filesave.c_str());
2✔
97
    float hsi;
98
    while (fin >> hsi) {
44✔
99
        hsi_history.emplace_back(hsi);
42✔
100
    }
101
    fin.close();
2✔
102
}
2✔
103

104
void savestatus(unsigned int rounds_played, vector<Stock> stocks_list, float balance,
46✔
105
    const string & playerName) {
106
    string stocksave;
46✔
107
    ofstream fout;
46✔
108
    stocksave =
109
        SAVE_FOLDER_PREFIX + playerName + "/playerstatus" + SAVE_FILE_EXTENSION_TXT;
46✔
110
    fout.open(stocksave.c_str());
46✔
111
    fout << playerName << " " << rounds_played << " " << balance
46✔
112
         << endl; // saving basic info out of class inside playerstatus.save
46✔
113
    fout.close();
46✔
114
    for (unsigned long i = 0; i < stocks_list.size(); i++) {
966✔
115
        stocks_list[i].save(
920✔
116
            playerName, i); // save stock info inside class in seperate file
117
    }
118
}
46✔
119

120
void loadstatus(unsigned int & rounds_played, vector<Stock> & stocks_list,
3✔
121
    float & balance, string & playerName, vector<float> & hsi_history) {
122
    string stockload;
3✔
123
    string stockname;
3✔
124
    ifstream fin;
3✔
125
    vector<string> players;
3✔
126
    filesystem::create_directory(
3✔
127
        SAVE_FOLDER_PREFIX); // prevent error when no folder exists
128
    players = get_saves();   // generate a vector of name of folders
3✔
129
    if (players.empty()) {
3✔
130
        cout << "No player saves found, please create a new player." << endl;
1✔
131
        createplayer(playerName);
1✔
132
        return; // rejection of loading when no save files exist
1✔
133
    }
134
    cout << "Enter player name from the following:" << endl;
2✔
135
    printvector(players);
2✔
136
    while (std::find(players.begin(), players.end(), playerName) ==
8✔
137
           players.end()) { // reject incorrect input
12✔
138
        if (!playerName.empty()) {
4✔
139
            cout << "Player name does not exist, please enter a new name from the "
140
                    "following:"
×
141
                 << endl;
×
142
            printvector(players);
×
143
        }
144
        getline(cin, playerName);
4✔
145
    }
146
    stockload =
147
        SAVE_FOLDER_PREFIX + playerName + "/playerstatus" + SAVE_FILE_EXTENSION_TXT;
2✔
148
    fin.open(stockload.c_str());
2✔
149
    fin >> playerName >> rounds_played >> balance;
2✔
150
    fin.close(); // output basic info from playerstatus.save and return by reference
2✔
151
    load_hsi(hsi_history, playerName);
2✔
152
    for (unsigned long i = 0; i < initial_stock_count; i++) {
42✔
153
        stocks_list[i].load(
40✔
154
            playerName, i); // load stocks info to class in seperate files
155
    }
156
}
6✔
157

158
void delsave(string & mode) {
2✔
159
    string stockdel;
2✔
160
    string stockname;
2✔
161
    string inputname;
2✔
162
    string confirm;
2✔
163
    ifstream fin;
2✔
164
    vector<string> players;
2✔
165
    filesystem::create_directory(
2✔
166
        SAVE_FOLDER_PREFIX); // prevent error when no folder exists
167
    players = get_saves();   // generate a vector of name of folders
2✔
168
    if (players.empty()) {
2✔
169
        cout << "No player saves found, please enter " << USER_SAVE_OPTION::NEW_GAME
170
             << " for new save or enter " << USER_SAVE_OPTION::EXIT_GAME
171
             << " to quit: ";
×
172
        std::cin >> mode;
×
173
        while (
×
174
            mode != USER_SAVE_OPTION::NEW_GAME && mode != USER_SAVE_OPTION::EXIT_GAME) {
×
175
            std::cout << "Invalid input. Please enter " + USER_SAVE_OPTION::NEW_GAME
×
176
                      << " for new save or enter " + USER_SAVE_OPTION::EXIT_GAME +
×
177
                             " to quit: ";
×
178
            std::cin >> mode; // choose new file or load previous file
×
179
        }
180
        return;
×
181
    }
182
    cout << "Enter player name from the following:" << endl;
2✔
183
    printvector(players);
2✔
184
    while (std::find(players.begin(), players.end(), inputname) ==
8✔
185
           players.end()) { // reject incorrect input
12✔
186
        if (!inputname.empty()) {
4✔
187
            cout << "Player name does not exist, please enter a new name from the "
188
                    "following: "
×
189
                 << endl;
×
190
            printvector(players);
×
191
        }
192
        getline(cin, inputname);
4✔
193
    }
194

195
    cout << "WARNING! This action is irreversible and will delete all data associated "
196
            "with the player save."
2✔
197
         << endl;
2✔
198
    cout << "Player save " << inputname
199
         << " is going to be deleted, please enter Y to confirm" << endl;
2✔
200
    cin >> confirm;
2✔
201
    if (confirm == "Y" || confirm == "y") {
2✔
202
        stockdel = SAVE_FOLDER_PREFIX + inputname;
2✔
203
        for (const auto & path : std::filesystem::directory_iterator(stockdel)) {
50✔
204
            std::filesystem::remove(path);
44✔
205
        }
2✔
206
        std::filesystem::remove_all(stockdel);
2✔
207
        cout << "Player save " << inputname << " has been deleted." << endl;
2✔
208
    }
209
    else {
210
        cout << "The deletion has been cancelled." << endl;
×
211
    }
212
}
2✔
213

214
vector<string> get_saves(void) {
5✔
215
    vector<string> saves;
5✔
216
    for (const auto & entry : std::filesystem::directory_iterator(SAVE_FOLDER_PREFIX)) {
21✔
217
        saves.emplace_back(entry.path().string().substr(SAVE_FOLDER_PREFIX.size()));
6✔
218
    }
5✔
219
    return saves;
5✔
220
}
×
221

222
void printvector(const vector<string> & avector) {
4✔
223
    cout << avector[0];
4✔
224
    // note: start from 1 to avoid printing the first element twice
225
    for (unsigned long i = 1; i < avector.size(); i++) {
6✔
226
        cout << ", " << avector[i];
2✔
227
    }
228
    cout << endl;
4✔
229
}
4✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc