added: input and its subclasses

This commit is contained in:
2024-07-04 22:47:25 -04:00
parent c67dbcc62a
commit f5b5f180a0
9 changed files with 245 additions and 18 deletions

42
src/console_input.cc Normal file
View File

@ -0,0 +1,42 @@
#include "console_input.h"
#include <utility>
#include <string>
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;
}

16
src/console_input.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef __CONSOLE_INPUT_H__
#define __CONSOLE_INPUT_H__
#include <iostream>
#include "input.h"
class console_input final : public input {
private:
std::istream &in;
public:
// This is for cin
console_input(std::istream &cin);
game_command get_command() override;
};
#endif

View File

@ -6,8 +6,7 @@
#include <vector> #include <vector>
#include "position.h" #include "position.h"
// IMPORTANT: added END to the end of all valued enums so that you can // IMPORTANT: panic is reserved for invalid results
// iterate over them
enum error {none}; 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_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}; enum stat_name {HP, ATK, DEF, hostile};
const int LAYER_CNT = 4; // TODO: update as you go 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; const int DIRECTION_CNT = 8;
// IMPORTANT: east is positive for x and SOUTH is positive for y // IMPORTANT: east is positive for x and SOUTH is positive for y
// initializes all directions to an int // initializes all directions to an int
enum direction {east = 0, west, north, south, northeast, enum direction { north = 0, south, east, west, northeast,
northwest, southeast, southest northwest, southeast, southest
}; };
const position MOVE[DIRECTION_CNT] = { 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} {1, -1}, {-1, -1}, {1, 1}, {-1, 1}
}; };

75
src/curses_input.cc Normal file
View File

@ -0,0 +1,75 @@
#include "curses_input.h"
curses_input::curses_input(const std::unique_ptr<cursor> &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;
}

17
src/curses_input.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef __CURSES_INPUT_H__
#define __CURSES_INPUT_H__
#include <memory>
#include "input.h"
#include "constants.h"
#include "cursor.h"
class curses_input final: public input {
private:
const std::unique_ptr<cursor> &curse;
public:
curses_input(const std::unique_ptr<cursor> &new_curse);
game_command get_command() override;
};
#endif

View File

@ -4,20 +4,25 @@
#include <ncurses.h> #include <ncurses.h>
#include "position.h" #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: private:
public: public:
cursor(); cursor();
~cursor(); ~cursor();
int getcmd() const; int getcmd() const;
void show() 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 #endif

42
src/file_input.cc Normal file
View File

@ -0,0 +1,42 @@
#include "file_input.h"
#include <utility>
#include <string>
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;
}

16
src/file_input.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef __FILE_INPUT_H__
#define __FILE_INPUT_H__
#include <fstream>
#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

View File

@ -1,11 +1,11 @@
#ifndef __INPUT_H__ #ifndef __INPUT_H__
#define __INPUT_H__ #define __INPUT_H__
#include <string> #include "constants.h"
#include "cursor.h"
class input{ class input {
public: public:
input(cursor &new_curse); virtual ~input() = 0;
virtual game_command get_command() = 0;
}; };
#endif #endif