1414// the source template at `configured_files/config.hpp.in`.
1515#include < internal_use_only/config.hpp>
1616
17- template <std::size_t Width, std::size_t Height> struct GameBoard
18- {
19- static constexpr std::size_t width = Width;
20- static constexpr std::size_t height = Height;
21-
22- std::array<std::array<std::string, height>, width> strings;
23- std::array<std::array<bool , height>, width> values{};
24-
25- std::size_t move_count{ 0 };
26-
27- std::string &get_string (std::size_t x, std::size_t y) { return strings.at (x).at (y); }
28-
29-
30- void set (std::size_t x, std::size_t y, bool new_value)
31- {
32- get (x, y) = new_value;
33-
34- if (new_value) {
35- get_string (x, y) = " ON" ;
36- } else {
37- get_string (x, y) = " OFF" ;
38- }
39- }
40-
41- void visit (auto visitor)
42- {
43- for (std::size_t x = 0 ; x < width; ++x) {
44- for (std::size_t y = 0 ; y < height; ++y) { visitor (x, y, *this ); }
45- }
46- }
47-
48- [[nodiscard]] bool get (std::size_t x, std::size_t y) const { return values.at (x).at (y); }
49-
50- [[nodiscard]] bool &get (std::size_t x, std::size_t y) { return values.at (x).at (y); }
51-
52- GameBoard ()
53- {
54- visit ([](const auto x, const auto y, auto &gameboard) { gameboard.set (x, y, true ); });
55- }
56-
57- void update_strings ()
58- {
59- for (std::size_t x = 0 ; x < width; ++x) {
60- for (std::size_t y = 0 ; y < height; ++y) { set (x, y, get (x, y)); }
61- }
62- }
63-
64- void toggle (std::size_t x, std::size_t y) { set (x, y, !get (x, y)); }
65-
66- void press (std::size_t x, std::size_t y)
67- {
68- ++move_count;
69- toggle (x, y);
70- if (x > 0 ) { toggle (x - 1 , y); }
71- if (y > 0 ) { toggle (x, y - 1 ); }
72- if (x < width - 1 ) { toggle (x + 1 , y); }
73- if (y < height - 1 ) { toggle (x, y + 1 ); }
74- }
75-
76- [[nodiscard]] bool solved () const
77- {
78- for (std::size_t x = 0 ; x < width; ++x) {
79- for (std::size_t y = 0 ; y < height; ++y) {
80- if (!get (x, y)) { return false ; }
81- }
82- }
83-
84- return true ;
85- }
86- };
87-
88-
89- void consequence_game ()
90- {
91- auto screen = ftxui::ScreenInteractive::TerminalOutput ();
92-
93- GameBoard<3 , 3 > gb;
94-
95- std::string quit_text;
96-
97- const auto update_quit_text = [&quit_text](const auto &game_board) {
98- quit_text = fmt::format (" Quit ({} moves)" , game_board.move_count );
99- if (game_board.solved ()) { quit_text += " Solved!" ; }
100- };
101-
102- const auto make_buttons = [&] {
103- std::vector<ftxui::Component> buttons;
104- for (std::size_t x = 0 ; x < gb.width ; ++x) {
105- for (std::size_t y = 0 ; y < gb.height ; ++y) {
106- buttons.push_back (ftxui::Button (&gb.get_string (x, y), [=, &gb] {
107- if (!gb.solved ()) { gb.press (x, y); }
108- update_quit_text (gb);
109- }));
110- }
111- }
112- return buttons;
113- };
114-
115- auto buttons = make_buttons ();
116-
117- auto quit_button = ftxui::Button (&quit_text, screen.ExitLoopClosure ());
118-
119- auto make_layout = [&] {
120- std::vector<ftxui::Element> rows;
121-
122- std::size_t idx = 0 ;
123-
124- for (std::size_t x = 0 ; x < gb.width ; ++x) {
125- std::vector<ftxui::Element> row;
126- for (std::size_t y = 0 ; y < gb.height ; ++y) {
127- row.push_back (buttons[idx]->Render ());
128- ++idx;
129- }
130- rows.push_back (ftxui::hbox (std::move (row)));
131- }
132-
133- rows.push_back (ftxui::hbox ({ quit_button->Render () }));
134-
135- return ftxui::vbox (std::move (rows));
136- };
137-
138-
139- static constexpr int randomization_iterations = 100 ;
140- static constexpr int random_seed = 42 ;
141-
142- std::mt19937 gen32{ random_seed };// NOLINT fixed seed
143- std::uniform_int_distribution<std::size_t > x (static_cast <std::size_t >(0 ), gb.width - 1 );
144- std::uniform_int_distribution<std::size_t > y (static_cast <std::size_t >(0 ), gb.height - 1 );
145-
146- for (int i = 0 ; i < randomization_iterations; ++i) { gb.press (x (gen32), y (gen32)); }
147- gb.move_count = 0 ;
148- update_quit_text (gb);
149-
150- auto all_buttons = buttons;
151- all_buttons.push_back (quit_button);
152- auto container = ftxui::Container::Horizontal (all_buttons);
153-
154- auto renderer = ftxui::Renderer (container, make_layout);
155-
156- screen.Loop (renderer);
157- }
15817
15918struct Color
16019{
@@ -312,8 +171,7 @@ int main(int argc, const char **argv)
312171 R"( intro
313172
314173 Usage:
315- intro turn_based
316- intro loop_based
174+ intro
317175 intro (-h | --help)
318176 intro --version
319177 Options:
@@ -329,11 +187,7 @@ int main(int argc, const char **argv)
329187 my_awesome_game::cmake::project_version));// version string, acquired
330188 // from config.hpp via CMake
331189
332- if (args[" turn_based" ].asBool ()) {
333- consequence_game ();
334- } else {
335- game_iteration_canvas ();
336- }
190+ game_iteration_canvas ();
337191
338192 // consequence_game();
339193 } catch (const std::exception &e) {
0 commit comments