1- #include < algorithm>
2- #include < filesystem>
3- #include < iostream>
4- #include < numeric>
5- #include < string>
6- #include < vector>
7-
81#include < str_format/str_format.hpp>
92
3+ #include < array>
4+
105#include " models.hpp"
116#include " utils.hpp"
127
@@ -46,19 +41,50 @@ void print_splash_screen(const std::filesystem::path& assets_dir)
4641
4742 std::cout << ' \n ' << std::setfill (' ' ) << std::setw (19 );
4843
49- for (const char & c : " copyright (c) 2021 cpp-gamedev" )
44+ utils::slow_print (" copyright (c) 2021 cpp-gamedev" , std::chrono::milliseconds{50 });
45+ }
46+
47+ void print_move_table (const models::Pokemon& pkmn)
48+ {
49+ // +----------------------------------------------------------+
50+ // | MOVE POWER ACCURACY |
51+ // | 1. move1 100 90 |
52+ // | first move description |
53+ // | 2. move2 90 50 |
54+ // | second move description |
55+ // | 3. move3 120 10 |
56+ // | third move description |
57+ // | 4. move4 30 70 |
58+ // | fourth move description |
59+ // +----------------------------------------------------------+
60+
61+ constexpr int width = 60 ;
62+ utils::Color border_color = utils::Color::YELLOW;
63+ std::string border = utils::style (std::string (" |" ), border_color);
64+ std::string horizontal_line = utils::style (std::string (" +" ).append (std::string (width - 2 , ' -' )).append (" +" ), border_color);
65+
66+ std::cout << horizontal_line << ' \n ' ;
67+ std::cout << border << std::string (4 , ' ' ) << " MOVE" << std::string (32 , ' ' ) << " POWER" << std::string (4 , ' ' ) << " ACCURACY" << ' ' << border << ' \n ' ;
68+
69+ for (std::size_t i = 0 ; i < pkmn.move_set .size (); ++i)
5070 {
51- std::cout << c;
52- utils::sleep (100 );
71+ // move name, power and accuracy
72+ std::string name = kt::format_str (" {}. {}" , i + 1 , pkmn.move_set [i].name );
73+ std::cout << border << ' ' << utils::style (name, utils::Color::GREEN) << std::setfill (' ' ) << std::setw (width - 7 - name.length ())
74+ << utils::style (std::to_string (pkmn.move_set [i].power ), utils::Color::RED) << std::setfill (' ' ) << std::setw (21 )
75+ << utils::style (std::to_string (pkmn.move_set [i].accuracy ), utils::Color::CYAN) << ' ' << border << ' \n ' ;
76+ // flavor text
77+ std::cout << border << std::string (4 , ' ' ) << pkmn.move_set [i].flavor_text << std::setfill (' ' ) << std::setw (width + 4 - pkmn.move_set [i].flavor_text .length ())
78+ << border << ' \n ' ;
5379 }
80+
81+ std::cout << horizontal_line << ' \n ' ;
5482}
5583
56- std::vector <models::Pokemon> load_main_menu (utils::Manifest manifest)
84+ std::array <models::Pokemon, 2 > load_main_menu (const utils::Manifest& manifest)
5785{
5886 // 1. set difficulty
59- int selection{};
60- utils::print_enum_table ({" easy" , " moderate" , " hard" }, " difficulty" );
61- selection = utils::get_user_input<int >(" >>> " );
87+ int selection{utils::validate_user_input ({" easy" , " moderate" , " hard" }, " (1/2) SET DIFFICULTY" )};
6288 auto difficulty = (selection == 1 ) ? models::Difficulty::EASY : (selection == 2 ) ? models::Difficulty::MODERATE : models::Difficulty::HARD;
6389
6490 // 2. instantiate all available pokemons
@@ -71,17 +97,15 @@ std::vector<models::Pokemon> load_main_menu(utils::Manifest manifest)
7197 std::vector<std::string> names{};
7298 names.reserve (pkmns.size ());
7399 std::for_each (pkmns.begin (), pkmns.end (), [&names](models::Pokemon& pkmn) { names.push_back (pkmn.name ); });
74- utils::print_enum_table (names, " pokemons" );
75- selection = utils::get_user_input<int >(" >>> " );
100+ selection = utils::validate_user_input (names, " (2/2) CHOOSE A POKEMON" );
76101 models::Pokemon player = pkmns[selection - 1 ];
77102
78103 // 4. remove selection from pkmns, so that player won't fight against his doppelganger
79104 pkmns.erase (std::remove_if (pkmns.begin (), pkmns.end (), [player](models::Pokemon pkmn) { return player.id == pkmn.id ; }), pkmns.end ());
80-
81105 return {player, pkmns.size () > 1 ? utils::random_choice (pkmns) : pkmns[0 ]};
82106}
83107
84- void print_frame (const models::Pokemon& pkmn1, const models::Pokemon& pkmn2)
108+ int print_frame (const models::Pokemon& pkmn1, const models::Pokemon& pkmn2)
85109{
86110 std::string healthbars{};
87111 std::string sprites{};
@@ -94,20 +118,34 @@ void print_frame(const models::Pokemon& pkmn1, const models::Pokemon& pkmn2)
94118 if (padding > 30 )
95119 padding -= 2 * (padding - 30 );
96120
121+ // gather healthbars
97122 for (std::size_t i = 0 ; i < 3 ; i++)
98123 healthbars.append (healthbar1[i]).append (std::string (padding, ' ' )).append (healthbar2[i]).append (" \n " );
99124
100- std::cout << healthbars;
101-
125+ // gather sprites
102126 for (std::size_t i = 0 ; i < 20 ; i++)
103127 {
104128 std::string tmp = pkmn1.sprite [i]; // strip new line
105129 tmp.erase (std::remove (tmp.begin (), tmp.end (), ' \n ' ), tmp.end ());
106130 sprites.append (tmp).append (std::string (20 , ' ' )).append (pkmn2.sprite [i]);
107131 }
108132
109- std::cout << sprites;
133+ int answer{};
134+ std::vector<int > choices (pkmn1.move_set .size ());
135+ std::iota (choices.begin (), choices.end (), 1 );
136+
137+ // read and return user-selected move
138+ while (std::find (choices.begin (), choices.end (), answer) == choices.end ())
139+ {
140+ utils::clear_screen ();
141+ std::cout << healthbars;
142+ std::cout << sprites;
143+ print_move_table (pkmn1);
144+ answer = utils::get_user_input<int >(" >>> " );
145+ std::cin.clear ();
146+ std::cin.ignore (utils::str_max, ' \n ' );
147+ }
110148
111- return ;
149+ return answer ;
112150}
113151} // namespace anim
0 commit comments