diff --git a/src/console_input.cc b/src/console_input.cc new file mode 100644 index 0000000..a284db2 --- /dev/null +++ b/src/console_input.cc @@ -0,0 +1,42 @@ +#include "console_input.h" +#include +#include + +console_input::console_input(std::istream &cin): + in{cin} {} + +inline game_command get_direction(std::string &str, const char *COMMANDS[], + const int COMMANDS_CNT) { + for (int i = 0; i < COMMANDS_CNT; ++i) + if (str == COMMANDS[i] && + i >= game_command::move_north && + i <= game_command::move_southeast) + return (game_command)i; + + return game_command_panic; +} + +game_command console_input::get_command() { + const char *COMMANDS[] = { + "q", "no", "so", "ea", "we", "ne", "nw", "se", "sw", "u", "a" + }; + const int COMMANDS_CNT = 11; + std::string cmd; + in >> cmd; + game_command tmp; + + if (cmd == "q") + return game_command_terminate; + else if (cmd == "u") + return (game_command)((tmp = get_direction(cmd, COMMANDS, + COMMANDS_CNT)) == game_command_panic + ? tmp : tmp - move_north + apply_north); + else if (cmd == "a") + return (game_command)((tmp = get_direction(cmd, COMMANDS, + COMMANDS_CNT)) == game_command_panic + ? tmp : tmp - move_north + attack_north); + else // is just moving + return get_direction(cmd, COMMANDS, COMMANDS_CNT); + + return game_command_pass; +} diff --git a/src/console_input.h b/src/console_input.h new file mode 100644 index 0000000..4ec4ffe --- /dev/null +++ b/src/console_input.h @@ -0,0 +1,16 @@ +#ifndef __CONSOLE_INPUT_H__ +#define __CONSOLE_INPUT_H__ + +#include +#include "input.h" + +class console_input final : public input { +private: + std::istream ∈ +public: + // This is for cin + console_input(std::istream &cin); + game_command get_command() override; +}; + +#endif diff --git a/src/constants.h b/src/constants.h index 8b732a9..d649c07 100644 --- a/src/constants.h +++ b/src/constants.h @@ -6,8 +6,7 @@ #include #include "position.h" -// IMPORTANT: added END to the end of all valued enums so that you can -// iterate over them +// IMPORTANT: panic is reserved for invalid results enum error {none}; @@ -16,6 +15,21 @@ enum result {fine, died, go_down, hit, moved}; enum game_status {terminated, main_menu, in_game, options}; +enum game_command {game_command_terminate = 0, + move_north, move_south, move_east, move_west, + move_northeast, move_northwest, + move_southeast, move_southwest, + apply_north, apply_south, apply_east, apply_west, + apply_northeast, apply_northwest, + apply_southeast, apply_southwest, + apply_prompt, apply_panic, // for curses_input specifically + attack_north, attack_south, attack_east, attack_west, + attack_northeast, attack_northwest, + attack_southeast, attack_southwest, + up_stairs, down_stairs, + game_command_pass, game_command_panic + }; + enum stat_name {HP, ATK, DEF, hostile}; const int LAYER_CNT = 4; // TODO: update as you go @@ -35,12 +49,12 @@ const char CHARACTER_REP[RACE_CNT] = {'@', 'S'}; const int DIRECTION_CNT = 8; // IMPORTANT: east is positive for x and SOUTH is positive for y // initializes all directions to an int -enum direction {east = 0, west, north, south, northeast, - northwest, southeast, southest +enum direction { north = 0, south, east, west, northeast, + northwest, southeast, southest }; const position MOVE[DIRECTION_CNT] = { - {1, 0}, {-1, 0}, {0, -1}, {0, 1}, + {0, -1}, {0, 1}, {1, 0}, {-1, 0}, {1, -1}, {-1, -1}, {1, 1}, {-1, 1} }; diff --git a/src/curses_input.cc b/src/curses_input.cc new file mode 100644 index 0000000..7c14444 --- /dev/null +++ b/src/curses_input.cc @@ -0,0 +1,75 @@ +#include "curses_input.h" + +curses_input::curses_input(const std::unique_ptr &new_curse): + curse{new_curse} {} + +game_command curses_input::get_command() { + switch (curse->getcmd()) { + case 'h': + return game_command::move_west; + + case 'j': + return game_command::move_south; + + case 'k': + return game_command::move_north; + + case 'l': + return game_command::move_east; + + case 'y': + return game_command::move_northwest; + + case 'u': + return game_command::move_northeast; + + case 'b': + return game_command::move_southwest; + + case 'n': + return game_command::move_southeast; + + case 'a': + break; // wait for another command + + case '<': + return game_command::up_stairs; + + case '>': + return game_command::down_stairs; + + default: + return game_command_pass; + } + + switch (curse->getcmd()) { + case 'h': + return game_command::apply_west; + + case 'j': + return game_command::apply_south; + + case 'k': + return game_command::apply_north; + + case 'l': + return game_command::apply_east; + + case 'y': + return game_command::apply_northwest; + + case 'u': + return game_command::apply_northeast; + + case 'b': + return game_command::apply_southwest; + + case 'n': + return game_command::apply_southeast; + + default: + return game_command::apply_panic; + } + + return game_command::game_command_panic; +} diff --git a/src/curses_input.h b/src/curses_input.h new file mode 100644 index 0000000..e4cc2c2 --- /dev/null +++ b/src/curses_input.h @@ -0,0 +1,17 @@ +#ifndef __CURSES_INPUT_H__ +#define __CURSES_INPUT_H__ + +#include +#include "input.h" +#include "constants.h" +#include "cursor.h" + +class curses_input final: public input { +private: + const std::unique_ptr &curse; +public: + curses_input(const std::unique_ptr &new_curse); + game_command get_command() override; +}; + +#endif diff --git a/src/cursor.h b/src/cursor.h index a43b650..8be54ce 100644 --- a/src/cursor.h +++ b/src/cursor.h @@ -4,20 +4,25 @@ #include #include "position.h" -class cursor{ +// IMPORTANT: use unique_ptr for cursor because: +// 1. Every instance of cursor will initialize a new ncurses screen +// Hence you should only have one instance of cursor at a time +// Otherwise IDK what'll happen +// 2. unique_ptr insures that only one copy of a pre-declared cursor can exist +class cursor final { private: public: - cursor(); + cursor(); - ~cursor(); + ~cursor(); - int getcmd() const; - - void show() const; + int getcmd() const; - void print_char(const position &pos) const; + void show() const; - void print_str(const position &head, const std::string str) const; + void print_char(const position &pos) const; + + void print_str(const position &head, const std::string str) const; }; #endif diff --git a/src/file_input.cc b/src/file_input.cc new file mode 100644 index 0000000..9980646 --- /dev/null +++ b/src/file_input.cc @@ -0,0 +1,42 @@ +#include "file_input.h" +#include +#include + +file_input::file_input(std::ifstream &&ifs): + in{std::move(ifs)} {} + +inline game_command get_direction(std::string &str, const char *COMMANDS[], + const int COMMANDS_CNT) { + for (int i = 0; i < COMMANDS_CNT; ++i) + if (str == COMMANDS[i] && + i >= game_command::move_north && + i <= game_command::move_southeast) + return (game_command)i; + + return game_command_panic; +} + +game_command file_input::get_command() { + const char *COMMANDS[] = { + "q", "no", "so", "ea", "we", "ne", "nw", "se", "sw", "u", "a" + }; + const int COMMANDS_CNT = 11; + std::string cmd; + in >> cmd; + game_command tmp; + + if (cmd == "q") + return game_command_terminate; + else if (cmd == "u") + return (game_command)((tmp = get_direction(cmd, COMMANDS, + COMMANDS_CNT)) == game_command_panic + ? tmp : tmp - move_north + apply_north); + else if (cmd == "a") + return (game_command)((tmp = get_direction(cmd, COMMANDS, + COMMANDS_CNT)) == game_command_panic + ? tmp : tmp - move_north + attack_north); + else // is just moving + return get_direction(cmd, COMMANDS, COMMANDS_CNT); + + return game_command_pass; +} diff --git a/src/file_input.h b/src/file_input.h new file mode 100644 index 0000000..afcb220 --- /dev/null +++ b/src/file_input.h @@ -0,0 +1,16 @@ +#ifndef __FILE_INPUT_H__ +#define __FILE_INPUT_H__ + +#include +#include "input.h" + +class file_input final : public input { +private: + std::ifstream in; +public: + // This is for cin + file_input(std::ifstream &&ifs); + game_command get_command() override; +}; + +#endif diff --git a/src/input.h b/src/input.h index 4a50f77..51148a9 100644 --- a/src/input.h +++ b/src/input.h @@ -1,11 +1,11 @@ #ifndef __INPUT_H__ #define __INPUT_H__ -#include -#include "cursor.h" +#include "constants.h" -class input{ - public: - input(cursor &new_curse); +class input { +public: + virtual ~input() = 0; + virtual game_command get_command() = 0; }; #endif