-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathutils.cpp
181 lines (159 loc) · 4.78 KB
/
utils.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
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
#include <random>
#include "utils.hh"
QIcon utils::get_icon(const int icon)
{
//The requested icon is guaranteed to be found when this function is
//only passed arguments via the icons enum.
return QIcon(ICON_SUFFIX + icon_names.at(icon) + ICON_FILE_TYPE);
}
void utils::calculate_factors(const int value, unsigned& smaller_factor,
unsigned& larger_factor)
{
for (auto i = 1; i * i <= value; ++i)
{
if (value % i == 0)
{
smaller_factor = i;
}
}
larger_factor = value / smaller_factor;
}
std::vector<int> utils::get_random_card_icons(const int card_count)
{
//generate numbers 2 ... ANIMAL_ICON_COUNT + 1 to an int vector
//(these values correspond to valid card icons in the icon enum)
std::vector<int> icons(ANIMAL_ICON_COUNT);
auto i = 1;
std::generate(icons.begin(), icons.end(), [&] { return ++i; });
//random shuffle elements with a mersenne twister engine seeded with
//a true random number from std::random_device (if supported)
std::shuffle(icons.begin(), icons.end(),
std::mt19937(std::random_device()()));
//remove elements from the vector so that only card_count / 2 elements exist
icons.erase(icons.begin(),
icons.begin() + (ANIMAL_ICON_COUNT - card_count / 2));
//duplicate the vector with itself to get one pair of each
const auto old_size = icons.size();
icons.reserve(2 * old_size);
std::copy_n(icons.begin(), old_size, std::back_inserter(icons));
//shuffle one last time
std::shuffle(icons.begin(), icons.end(),
std::mt19937(std::random_device()()));
return icons;
}
QString utils::seconds_to_time_string(const unsigned seconds)
{
//if time is over 999 mins 59 secs, just return 999:99
if (seconds >= 60000)
{
return "999:99";
}
//divide with precision loss to automatically floor
const auto mins = QString::number(seconds / 60);
//modulo to get remainder
const auto secs = QString::number(seconds % 60);
//add a zero if minute or second is a 1 digit number
return QString((mins.length() == 1 ? "0" + mins : mins) + ":"
+ (secs.length() == 1 ? "0" + secs : secs));
}
QString utils::icon_name_to_plural(const int icon)
{
switch(icon)
{
//can be converted to plural just by adding an 's'
case bird:
case camel:
case cat:
case chicken:
case cow:
case dog:
case donkey:
case duck:
case elephant:
case flamingo:
case horse:
case lizard:
case llama:
case panda:
case pig:
case rooster:
case squirrel:
{
//convert the first character to upper case
//check for empty just so [0] access is safe, even though
//it shouldn't be possible to be empty
auto name = icon_names.at(icon);
if (!name.isEmpty())
{
name[0] = name[0].toUpper();
}
return name + "s";
}
//unusual plural forms
case bunny:
return "Bunnies";
case monke:
return "Monke";
case sheep:
return "Sheep";
default:
return "";
}
}
QString utils::player_vector_to_names(const std::vector<Player*>& players)
{
const auto size = players.size();
QString name_string = "";
//size is one-based
auto i = 1u;
for (const auto player : players)
{
name_string += player->get_name();
//if not the last element
if (i != size)
{
//ternary, if next element is the last element
name_string += ++i == size ? " and " : ", ";
}
}
return name_string;
}
std::vector<QString> utils::split(const QString& text, const char separator,
const bool include_empty)
{
if (text.isEmpty())
{
return std::vector<QString> {""};
}
//vector to hold the separated parts
std::vector<QString> parts{};
//temp variable to hold the current part
QString part = "";
//loop through each character looking for occurrences of
//the separator character
for (const auto c : text)
{
//ignore carriage returns
if (c == '\r')
{
continue;
}
if (c == separator)
{
//include empty parts only if asked for
if (!part.isEmpty() || include_empty)
{
parts.push_back(part);
}
part = "";
continue;
}
part += c;
}
//also add in whatever was after the last separator
if (!part.isEmpty() || include_empty)
{
parts.push_back(part);
}
return parts;
}