-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcider.cpp
More file actions
185 lines (174 loc) · 7.54 KB
/
Copy pathcider.cpp
File metadata and controls
185 lines (174 loc) · 7.54 KB
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
/*
Vector of all possible game sets.
More information on these sets can be found here: https://boardgamegeek.com/wiki/page/Apples_to_Apples_Series
*/
static const std::vector<std::string> POSSIBLE_SETS = {
"Core Set",
"Core Expansion 1",
"Core Expansion 2",
"Core Expansion 3",
"Core Expansion 4",
"Party Box",
"Party Box Expansion 1",
"Kids Set",
"Junior Set"
};
/*
Unordered Map of all red cards. Red cards contain nouns.
Noun => Flavor Text
*/
static std::unordered_map<std::string, std::string> RED = {};
/*
Unordered Map of all green cards. Green cards contain adjectives.
Adjective => Synonyms
*/
static std::unordered_map<std::string, std::string> GREEN = {};
// Taken from BambooCutterLayover (https://github.com/MechaDragonX/BambooCutterLayover)
/*
Parameters: Reference to an input string, and a character to split by
Returns: A vector<string> that contains all the parts of the string
Description: Takes a string, splits it by a delimiter character, and return a vector with all the parts of the string
*/
std::vector<std::string> splitStringByDelimiter(std::string& input, char delimiter) {
std::vector<std::string> result = {};
size_t pos = 0;
std::string token;
// Loop until the end of the string
while((pos = input.find(delimiter)) != std::string::npos) {
// Make the token the current portion
token = input.substr(0, pos);
// Remove blank matches
if(token != "") {
result.push_back(token);
}
// Remove everything looked at so far
input.erase(0, pos + 1);
}
// Append the remaing bits to the vector
result.push_back(input);
return result;
}
/*
Parameters: A path to the file to read, an int representing which deck to populate (0: Red, 1: Green; Set to Red by default), and a vector of indices of accepted sets
Returns: Success boolean
Description: Read the provided file and populate the specified deck's map with its values
*/
bool populateDecks(std::string path, int color = 0, const std::vector<int>& acceptedSets = {}) {
std::ifstream inStream(path);
if(!inStream.good()) {
inStream.close();
return false;
}
std::string line = "";
std::vector<std::string> parts;
// If the current line is in an accept set
bool valid;
// While the the stream still has lines in the file to look at
while(!inStream.eof()) {
getline(inStream, line);
// If the current line isn't blank...
if(line != "") {
// Get the parts of the current line: item and flavor text / synonyms
parts = splitStringByDelimiter(line, '\t');
// Check if the acceptedSets Vector is not empty
if(!acceptedSets.empty()) {
// Set validity flag to false whenever a new line is looked at
valid = false;
// if not, loop through every single provided index in acceptedSets
for(int index : acceptedSets) {
// If an accepted set is found in the second part of the line
if(parts[1].find(POSSIBLE_SETS[index]) != std::string::npos) {
// If so, set validity to true and break
valid = true;
break;
}
/*
The above conditional will only check to see if any one of the accepted sets appears in the line.
If an accepted set and unaccepted set are both present, it will read that the accepted set is present, and set validity to true.
*/
}
} else {
// If acceptedSets is empty, then all sets are valid. Set validity bool to true
valid = true;
}
// If the current line is of a valid set
if(valid) {
// Add them to the specified deck's map
// if color == 0 then deck is red
if(color == 0) {
RED.insert({ parts[0], parts[1] });
// else it is 1, which means deck is green
} else {
GREEN.insert({ parts[0], parts[1] });
}
}
} else {
// There's always a new line at the end of the file, so there's nothing to see if the current line is blank
break;
}
}
inStream.close();
return true;
}
int main(int argc, char** argv) {
if(argc < 3) {
std::cout << "ERROR: That's too few arguments! You only need one argument!" << std::endl;
// If the program is running on Windows (does not apply to Cygwin, MSYS2, WSL, etc.)
#ifdef WINNT
// Give proper usage based on Command Prompt and Powershell
std::cout << "Usage on Command Prompt: cider.exe <text file for red deck> <text file for green deck>" << std::endl;
std::cout << "Usage on PowerShell: .\\cider.exe <text file for red deck> <text file for green deck>" << std::endl;
// Otherwise, the user will most likely be on Unix
#else
// Give proper usage based on Unix
std::cout << "Usage: ./cider.out <text file for red deck> <text file for green deck>" << std::endl;
#endif
return 1;
}
if(argc > 3) {
std::cout << "ERROR: That's too many arguments! You only need one argument!" << std::endl;
// If the program is running on Windows (does not apply to Cygwin, MSYS2, WSL, etc.)
#ifdef WINNT
// Give proper usage based on Command Prompt and Powershell
std::cout << "Usage on Command Prompt: cider.exe <text file for red deck> <text file for green deck>" << std::endl;
std::cout << "Usage on PowerShell: .\\cider.exe <text file for red deck> <text file for green deck>" << std::endl;
// Otherwise, the user will most likely be on Unix
#else
// Give proper usage based on Unix
std::cout << "Usage: ./cider.out <text file for red deck> <text file for green deck>" << std::endl;
#endif
return 1;
}
// Try Populating the red deck's map using the contents of the first text file passed
if(!populateDecks(argv[1]/*, 0, { 0, 1, 2, 3, 4, 5, 6 }*/)) {
// if it failed, print an error message
std::cout << "The text file passed for the red deck doesn't exist! Are you sure you spelled it right?" << std::endl;
return 1;
}
// Try Populating the green deck's map using the contents of the second text file passed
if(!populateDecks(argv[2], 1/*, { 0, 1, 2, 3, 4, 5, 6 }*/)) {
// if it failed, print an error message
std::cout << "The text file passed for the green deck doesn't exist! Are you sure you spelled it right?" << std::endl;
return 1;
}
// Initialize RNG with current time as seed
srand(time(nullptr));
// Iterate to random key in Red deck
auto iterator = RED.begin();
std::advance(iterator, rand() % RED.size());
// Print out that random key and value
std::cout << iterator->first + ": " + iterator->second << std::endl;
// Iterate to random key in Green deck
iterator = GREEN.begin();
std::advance(iterator, rand() % GREEN.size());
// Print out that random key and value
std::cout << iterator->first + ": " + iterator->second << std::endl;
return 0;
}