-
Notifications
You must be signed in to change notification settings - Fork 0
/
recordmanager.cpp
116 lines (101 loc) · 3.29 KB
/
recordmanager.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include "recordmanager.h"
#include <fstream>
#include <sstream>
#include <algorithm>
using std::ifstream;
using std::ofstream;
using std::runtime_error;
using std::endl;
/**
* @brief Load record from given path.
*
* @remark Record file format:
* L1: config file trunked into one line
* L2: map file trunked into one line
* L2+: movement (M {W, A, S, D})
* up: W; left: A; down: S; right: D
* or food generation (F, X, Y, V)
* position: (X, Y); score: V
*/
Record RecordManager::LoadRecord(const string &path, Record &record) {
record.foodSequence.clear();
record.moveSequence.clear();
record.sequence.clear();
record.timestamp.clear();
ifstream ifs(path);
if (!ifs.is_open()) {
throw runtime_error("文件操作异常");
}
char buffer[1048576];
ifs.getline(buffer, 1048576);
if (!ifs.good()) {
throw runtime_error("打开配置失败");
}
record.config = ConfigManager::LoadConfigFromString(buffer);
ifs.getline(buffer, 1048576);
if (!ifs.good()) {
throw runtime_error("打开地图失败");
}
record.map = MapManager::LoadMapFromString(buffer);
char op;
while (ifs >> op) {
if (op == 'F') {
int tme, x, y;
int value;
ifs >> tme >> x >> y >> value;
record.foodSequence.emplace_back(Point{x, y}, value);
record.timestamp.emplace_back(tme);
} else if (op == 'M') {
int tme;
char dire;
ifs >> tme >> dire;
record.moveSequence += dire;
record.timestamp.emplace_back(tme);
}
record.sequence += op;
}
return record;
}
void RecordManager::SaveRecord(const string &path, const Record &record) {
ofstream ofs(path);
if (!ofs.is_open()) {
throw runtime_error("文件操作异常");
}
string config = ConfigManager::GetConfigString(record.config);
replace(config.begin(), config.end(), '\n', ' ');
ofs << config << "\n";
string map = MapManager::GetMapString(record.map);
replace(map.begin(), map.end(), '\n', ' ');
ofs << map << "\n";
int foodPtr = 0, movePtr = 0, seqPtr = 0, seqLen = (int) record.sequence.length();
while (seqPtr != seqLen) {
char op = record.sequence[seqPtr];
if (op == 'F') {
int tme = record.timestamp[seqPtr], x = record.foodSequence[foodPtr].first.x, y = record.foodSequence[foodPtr].first.y, v = record.foodSequence[foodPtr].second;
foodPtr++;
ofs << "F " << tme << " " << x << " " << y << " " << v << "\n";
} else if (op == 'M') {
int tme = record.timestamp[seqPtr];
char dire = record.moveSequence[movePtr];
movePtr++;
ofs << "M " << tme << " " << dire << "\n";
}
seqPtr++;
}
}
void Record::Reset(const Map &_map, const Config &_config) {
map = _map;
config = _config;
sequence = "";
while(!timestamp.empty()) timestamp.pop_back();
while(!foodSequence.empty()) foodSequence.pop_back();
moveSequence = "";
}
void Record::Reset(const Record& record) {
map = record.map;
config = record.config;
sequence = record.sequence;
timestamp = record.timestamp;
foodSequence = record.foodSequence;
moveSequence = record.moveSequence;
}