Skip to content

Commit e6fec81

Browse files
committed
Break up big function in chapter 9
1 parent da7e149 commit e6fec81

File tree

1 file changed

+45
-25
lines changed

1 file changed

+45
-25
lines changed

Chapter9/main.cpp

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <algorithm>
22
#include <cassert>
3+
#include <concepts>
34
#include <execution>
45
#include <format>
56
#include <iostream>
@@ -13,8 +14,11 @@
1314
#include <utility>
1415
#include <vector>
1516

17+
using Reel = std::vector<int>;
18+
1619
// Listing 9.1 Make the first few triangle numbers
17-
std::vector<int> make_triangle_numbers(int count)
20+
// constexpr added in section 9.2
21+
constexpr std::vector<int> make_triangle_numbers(int count)
1822
{
1923
std::vector<int> numbers(count);
2024
std::iota(numbers.begin(), numbers.end(), 1);
@@ -56,19 +60,36 @@ void demo_further_properties()
5660
}
5761
}
5862

59-
//std::any_of
63+
// Listing 9.5 Setup reels
64+
template<std::invocable<std::vector<Reel>::iterator, std::vector<Reel>::iterator> T>
65+
constexpr std::vector<Reel> make_reels(int numbers, int number_of_reels, T shuffle)
66+
{
67+
std::vector<Reel> reels(number_of_reels, make_triangle_numbers(numbers));
68+
69+
for (auto& reel : reels)
70+
{
71+
shuffle(reel.begin(), reel.end());
72+
}
73+
return reels;
74+
}
75+
76+
// Listing 9.6 Display reels
77+
void show_reels(std::ostream& s, const std::vector<int>& left, const std::vector<int>& middle, const std::vector<int>& right)
78+
{
79+
s << std::format(" {:>3} {:>3} {:>3}\n", left.back(), middle.back(), right.back());
80+
s << std::format("-{:>3} {:>3} {:>3}-\n", left[0], middle[0], right[0]);
81+
s << std::format(" {:>3} {:>3} {:>3}\n", left[1], middle[1], right[1]);
82+
}
6083

84+
// Listing 9.7 Calculate payout
6185
int calculate_payout_v1(int left, int middle, int right)
6286
{
63-
const int left_unit = left % 10;
64-
const int middle_unit = middle % 10;
65-
const int right_unit = right % 10;
6687
int payout = 0;
67-
if (left_unit == middle_unit && middle_unit == right_unit)
88+
if (left == middle && middle == right)
6889
{
6990
payout = 2;
7091
}
71-
else if (left_unit == middle_unit || middle_unit == right_unit || left_unit == right_unit)
92+
else if (left == middle || middle == right || left == right)
7293
{
7394
payout = 1;
7495
}
@@ -85,7 +106,7 @@ std::map<int, size_t> frequencies(std::convertible_to<int> auto ...numbers)
85106

86107
int calculate_payout(int left, int middle, int right)
87108
{
88-
std::map<int, size_t> counter=frequencies(left, middle, right);
109+
std::map<int, size_t> counter = frequencies(left, middle, right);
89110
// for loop first then dots:
90111
//for (int number : {left, middle, right})
91112
//{
@@ -116,7 +137,7 @@ int calculate_payout(int left, int middle, int right)
116137
* The function-like entities described on this page are niebloids, that is:
117138
* Explicit template argument lists cannot be specified when calling any of them.
118139
* None of them are visible to argument-dependent lookup.
119-
* When any of them are found by normal unqualified lookup as the name to the left of the function-call operator,
140+
* When any of them are found by normal unqualified lookup as the name to the left of the function-call operator,
120141
* argument-dependent lookup is inhibited.
121142
*/
122143
auto it = std::max_element(counter.begin(), counter.end(),
@@ -127,45 +148,37 @@ int calculate_payout(int left, int middle, int right)
127148
{
128149
int digit = it->first;
129150
size_t count = it->second;
130-
constexpr int value[] = {0, 0, 1, 2};
151+
constexpr int value[] = { 0, 0, 1, 2 };
131152
auto pay = ((digit == 8 || digit == 3) ? 2 : 1) * value[count];
132153
return pay;
133154
}
134155
return 0;
135156
}
136157

137-
158+
// Listing 9.8 A simple one armed bandit game
138159
void triangle_machine_spins_only()
139160
{
140161
constexpr int numbers = 20;
141162
constexpr size_t number_of_reels = 3u;
142-
std::vector<std::vector<int>> reels(number_of_reels, make_triangle_numbers(numbers));
143163
std::random_device rd;
144164
std::mt19937 gen{ rd() };
165+
auto shuffle = [&gen](auto begin, auto end) { std::shuffle(begin, end, gen); };
145166

146-
for (auto& reel : reels)
147-
{
148-
std::shuffle(reel.begin(), reel.end(), gen);
149-
}
167+
std::vector<Reel> reels = make_reels(numbers, number_of_reels, shuffle);
150168

151-
std::uniform_int_distribution dist(1, numbers - 1); // int dis includes last number, but rotate mustn't use a middle equal to or beyond end
169+
std::uniform_int_distribution dist(1, numbers - 1);
152170
int credit = 1;
153171
while (true)
154172
{
155-
const int left = reels[0][0];
156-
const int middle = reels[1][0];
157-
const int right = reels[2][0];
158-
std::cout << std::format(" {:>3} {:>3} {:>3}\n", reels[0][numbers - 1], reels[1][numbers - 1], reels[2][numbers - 1]);
159-
std::cout << std::format("-{:>3} {:>3} {:>3}-\n", reels[0][0], reels[1][0], reels[2][0]);
160-
std::cout << std::format(" {:>3} {:>3} {:>3}\n", reels[0][1], reels[1][1], reels[2][1]);
173+
show_reels(std::cout, reels[0], reels[1], reels[2]);
174+
const int won = calculate_payout(reels[0][0]%10, reels[1][0]%10, reels[2][0]%10);
161175
--credit;
162-
int won = calculate_payout(left, middle, right);
163176
credit += won;
164177
std::cout << "won " << won << " credit = " << credit << '\n';
165178

166179
std::string response;
167180
std::getline(std::cin, response);
168-
if (response == "q") // for quit
181+
if (response != "")
169182
{
170183
break;
171184
}
@@ -215,6 +228,13 @@ void check_properties()
215228
assert(calculate_payout(0, 0, 0) == 2);
216229
assert(calculate_payout(3, 3, 3) == 4);
217230
assert(calculate_payout(8, 8, 8) == 4);
231+
232+
constexpr auto no_op = [](auto begin, auto end) { };
233+
static_assert(make_reels(1, 1, no_op).size() == 1);
234+
235+
std::vector v{ 1,2,3,4,5 };
236+
std::rotate(v.begin(), v.begin() + 3, v.end());
237+
assert(v[0] == 4);
218238
}
219239

220240
int main()

0 commit comments

Comments
 (0)