format
This commit is contained in:
238
src/arguments.cc
238
src/arguments.cc
@ -19,157 +19,157 @@ feature proc_args(int argc, char **argv,
|
|||||||
std::unique_ptr<display> &out,
|
std::unique_ptr<display> &out,
|
||||||
std::unique_ptr<logger> &log,
|
std::unique_ptr<logger> &log,
|
||||||
std::unique_ptr<RNG> &rng) {
|
std::unique_ptr<RNG> &rng) {
|
||||||
feature result = 0;
|
feature result = 0;
|
||||||
std::string str;
|
std::string str;
|
||||||
std::string fn_fin;
|
std::string fn_fin;
|
||||||
std::string fn_fout;
|
std::string fn_fout;
|
||||||
std::string fn_lout;
|
std::string fn_lout;
|
||||||
std::string fn_save;
|
std::string fn_save;
|
||||||
std::string seed;
|
std::string seed;
|
||||||
|
|
||||||
for (int i = 1; i < argc; ++i) {
|
for (int i = 1; i < argc; ++i) {
|
||||||
str = argv[i];
|
str = argv[i];
|
||||||
|
|
||||||
if (str == "-n") {
|
if (str == "-n") {
|
||||||
if (result & (FEATURE_IN_FILE | FEATURE_OUT_FILE))
|
if (result & (FEATURE_IN_FILE | FEATURE_OUT_FILE))
|
||||||
return FEATURE_CONFLICT | i;
|
return FEATURE_CONFLICT | i;
|
||||||
|
|
||||||
result |= FEATURE_NCURSES;
|
result |= FEATURE_NCURSES;
|
||||||
} else if (str == "-r") {
|
} else if (str == "-r") {
|
||||||
result |= FEATURE_RAND_MAP;
|
result |= FEATURE_RAND_MAP;
|
||||||
} else if (str == "-m") {
|
} else if (str == "-m") {
|
||||||
result |= FEATURE_MENU;
|
result |= FEATURE_MENU;
|
||||||
} else if (str == "-c") {
|
} else if (str == "-c") {
|
||||||
result |= FEATURE_ENEMIES_CHASE;
|
result |= FEATURE_ENEMIES_CHASE;
|
||||||
} else if (str == "-i") {
|
} else if (str == "-i") {
|
||||||
result |= FEATURE_INVENTORY;
|
result |= FEATURE_INVENTORY;
|
||||||
} else if (str == "-t") {
|
} else if (str == "-t") {
|
||||||
result |= FEATURE_THROW;
|
result |= FEATURE_THROW;
|
||||||
} else if (str == "-R") {
|
} else if (str == "-R") {
|
||||||
result |= FEATURE_REVISIT;
|
result |= FEATURE_REVISIT;
|
||||||
} else if (str == "-s") {
|
} else if (str == "-s") {
|
||||||
++i;
|
++i;
|
||||||
str = argv[i];
|
str = argv[i];
|
||||||
|
|
||||||
if (!seed.empty() && seed != str)
|
if (!seed.empty() && seed != str)
|
||||||
return FEATURE_CONFLICT | i;
|
return FEATURE_CONFLICT | i;
|
||||||
|
|
||||||
seed = str;
|
seed = str;
|
||||||
result |= FEATURE_SEED;
|
result |= FEATURE_SEED;
|
||||||
} else if (str == "-L") {
|
} else if (str == "-L") {
|
||||||
++i;
|
++i;
|
||||||
str = argv[i];
|
str = argv[i];
|
||||||
|
|
||||||
if (!fn_lout.empty() && fn_lout != str)
|
if (!fn_lout.empty() && fn_lout != str)
|
||||||
return FEATURE_CONFLICT | i;
|
return FEATURE_CONFLICT | i;
|
||||||
|
|
||||||
fn_lout = str;
|
fn_lout = str;
|
||||||
result |= FEATURE_LOG;
|
result |= FEATURE_LOG;
|
||||||
} else if (str == "-I") {
|
} else if (str == "-I") {
|
||||||
++i;
|
++i;
|
||||||
str = argv[i];
|
str = argv[i];
|
||||||
|
|
||||||
if (!fn_fin.empty() && fn_fin != str)
|
if (!fn_fin.empty() && fn_fin != str)
|
||||||
return FEATURE_CONFLICT | i;
|
return FEATURE_CONFLICT | i;
|
||||||
|
|
||||||
fn_fin = str;
|
fn_fin = str;
|
||||||
result |= FEATURE_IN_FILE;
|
result |= FEATURE_IN_FILE;
|
||||||
} else if (str == "-O") {
|
} else if (str == "-O") {
|
||||||
++i;
|
++i;
|
||||||
str = argv[i];
|
str = argv[i];
|
||||||
|
|
||||||
if (!fn_fout.empty() && fn_fout != str)
|
if (!fn_fout.empty() && fn_fout != str)
|
||||||
return FEATURE_CONFLICT | i;
|
return FEATURE_CONFLICT | i;
|
||||||
|
|
||||||
fn_fout = str;
|
fn_fout = str;
|
||||||
result |= FEATURE_OUT_FILE;
|
result |= FEATURE_OUT_FILE;
|
||||||
} else if (str == "-h" || str == "--help") {
|
} else if (str == "-h" || str == "--help") {
|
||||||
return FEATURE_LIST_ARGS;
|
return FEATURE_LIST_ARGS;
|
||||||
} else {
|
} else {
|
||||||
return FEATURE_PANIC | i;
|
return FEATURE_PANIC | i;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (result & FEATURE_IN_FILE) {
|
if (result & FEATURE_IN_FILE) {
|
||||||
std::ifstream fin(fn_fin);
|
std::ifstream fin(fn_fin);
|
||||||
|
|
||||||
if (!fin.good())
|
if (!fin.good())
|
||||||
return FEATURE_PANIC_FILE | FEATURE_IN_FILE;
|
return FEATURE_PANIC_FILE | FEATURE_IN_FILE;
|
||||||
|
|
||||||
in = std::make_unique<file_input>(std::move(fin));
|
in = std::make_unique<file_input>(std::move(fin));
|
||||||
} else if (!(result & FEATURE_NCURSES))
|
} else if (!(result & FEATURE_NCURSES))
|
||||||
in = std::make_unique<console_input>(std::cin);
|
in = std::make_unique<console_input>(std::cin);
|
||||||
|
|
||||||
if (result & FEATURE_OUT_FILE) {
|
if (result & FEATURE_OUT_FILE) {
|
||||||
std::ofstream fout(fn_fout);
|
std::ofstream fout(fn_fout);
|
||||||
|
|
||||||
if (!fout.good())
|
if (!fout.good())
|
||||||
return FEATURE_PANIC_FILE | FEATURE_OUT_FILE;
|
return FEATURE_PANIC_FILE | FEATURE_OUT_FILE;
|
||||||
|
|
||||||
out = std::make_unique<file_output>(std::move(fout));
|
out = std::make_unique<file_output>(std::move(fout));
|
||||||
} else if (!(result & FEATURE_NCURSES))
|
} else if (!(result & FEATURE_NCURSES))
|
||||||
out = std::make_unique<console_output>(std::cout);
|
out = std::make_unique<console_output>(std::cout);
|
||||||
|
|
||||||
if (result & FEATURE_LOG) {
|
if (result & FEATURE_LOG) {
|
||||||
std::ofstream lout(fn_lout);
|
std::ofstream lout(fn_lout);
|
||||||
|
|
||||||
if (!lout.good())
|
if (!lout.good())
|
||||||
return FEATURE_PANIC_FILE | FEATURE_LOG;
|
return FEATURE_PANIC_FILE | FEATURE_LOG;
|
||||||
|
|
||||||
log = std::make_unique<logger>(std::move(lout));
|
log = std::make_unique<logger>(std::move(lout));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result & FEATURE_NCURSES) {
|
if (result & FEATURE_NCURSES) {
|
||||||
curse = std::make_unique<cursor>();
|
curse = std::make_unique<cursor>();
|
||||||
in = std::make_unique<curses_input>(*curse);
|
in = std::make_unique<curses_input>(*curse);
|
||||||
out = std::make_unique<curses_output>(*curse);
|
out = std::make_unique<curses_output>(*curse);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result & FEATURE_SEED) {
|
if (result & FEATURE_SEED) {
|
||||||
std::istringstream iss {seed};
|
std::istringstream iss {seed};
|
||||||
unsigned int tmp;
|
unsigned int tmp;
|
||||||
iss >> tmp;
|
iss >> tmp;
|
||||||
|
|
||||||
if (!iss.good())
|
if (!iss.good())
|
||||||
return FEATURE_PANIC_SEED;
|
return FEATURE_PANIC_SEED;
|
||||||
|
|
||||||
rng = std::make_unique<RNG>(tmp);
|
rng = std::make_unique<RNG>(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// IMPORTANT: This is meant for already panicking
|
// IMPORTANT: This is meant for already panicking
|
||||||
void panic_args(feature panic) {
|
void panic_args(feature panic) {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
if (panic & FEATURE_PANIC)
|
if (panic & FEATURE_PANIC)
|
||||||
cerr << "Invalid argument No. " << (panic ^ FEATURE_PANIC)
|
cerr << "Invalid argument No. " << (panic ^ FEATURE_PANIC)
|
||||||
<< " !" << endl;
|
<< " !" << endl;
|
||||||
else if (panic & FEATURE_CONFLICT)
|
else if (panic & FEATURE_CONFLICT)
|
||||||
cerr << "Argument No. " << (panic ^ FEATURE_CONFLICT)
|
cerr << "Argument No. " << (panic ^ FEATURE_CONFLICT)
|
||||||
<< " conflicts with a previous argument!" << endl;
|
<< " conflicts with a previous argument!" << endl;
|
||||||
else if (panic & FEATURE_PANIC_FILE) {
|
else if (panic & FEATURE_PANIC_FILE) {
|
||||||
switch (panic ^ FEATURE_PANIC_FILE) {
|
switch (panic ^ FEATURE_PANIC_FILE) {
|
||||||
case FEATURE_IN_FILE:
|
case FEATURE_IN_FILE:
|
||||||
cerr << "Cannot open specified input file!" << endl;
|
cerr << "Cannot open specified input file!" << endl;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FEATURE_OUT_FILE:
|
case FEATURE_OUT_FILE:
|
||||||
cerr << "Cannot open specified output file!" << endl;
|
cerr << "Cannot open specified output file!" << endl;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FEATURE_LOG:
|
case FEATURE_LOG:
|
||||||
cerr << "Cannot open specified log file!" << endl;
|
cerr << "Cannot open specified log file!" << endl;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
cerr << "Something must have went really, really, wrong..."
|
cerr << "Something must have went really, really, wrong..."
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
} else if (panic & FEATURE_PANIC_SEED) {
|
} else if (panic & FEATURE_PANIC_SEED) {
|
||||||
cerr << "Invalid seed" << endl;
|
cerr << "Invalid seed" << endl;
|
||||||
} else
|
} else
|
||||||
cerr << "Something must have went really, really, wrong..."
|
cerr << "Something must have went really, really, wrong..."
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "rng.h"
|
#include "rng.h"
|
||||||
|
|
||||||
|
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
|
|
||||||
/* Arguments
|
/* Arguments
|
||||||
|
@ -6,23 +6,20 @@ const int BOOST_ATK = 5;
|
|||||||
const int BOOST_ATK_DROW = 7;
|
const int BOOST_ATK_DROW = 7;
|
||||||
|
|
||||||
boost_atk::boost_atk():
|
boost_atk::boost_atk():
|
||||||
potion{potion_type::boost_atk, -1} {}
|
potion{potion_type::boost_atk, -1} {}
|
||||||
|
|
||||||
void boost_atk::apply(enum race &race, int &HP, int &ATK, int &DEF,
|
void boost_atk::apply(enum race &race, int &HP, int &ATK, int &DEF,
|
||||||
float &base_hit_rate) {
|
float &base_hit_rate) {
|
||||||
if (remaining_duration > 0) {
|
if (remaining_duration > 0) {
|
||||||
if (race == rdrow)
|
if (race == rdrow)
|
||||||
ATK += BOOST_ATK_DROW;
|
ATK += BOOST_ATK_DROW;
|
||||||
else
|
else
|
||||||
ATK += BOOST_ATK;
|
ATK += BOOST_ATK;
|
||||||
|
|
||||||
--remaining_duration;
|
--remaining_duration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int boost_atk::get_priority() const {
|
int boost_atk::get_priority() const {
|
||||||
return CALC_ADD_BASE;
|
return CALC_ADD_BASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,11 +5,10 @@
|
|||||||
|
|
||||||
class boost_atk final: public potion {
|
class boost_atk final: public potion {
|
||||||
public:
|
public:
|
||||||
boost_atk();
|
boost_atk();
|
||||||
void apply(enum race &race, int &HP, int &ATK, int &DEF,
|
void apply(enum race &race, int &HP, int &ATK, int &DEF,
|
||||||
float &base_hit_rate) override;
|
float &base_hit_rate) override;
|
||||||
int get_priority() const override;
|
int get_priority() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -5,22 +5,21 @@
|
|||||||
const int BOOST_DEF = 5;
|
const int BOOST_DEF = 5;
|
||||||
const int BOOST_DEF_DROW = 7;
|
const int BOOST_DEF_DROW = 7;
|
||||||
|
|
||||||
|
|
||||||
boost_def::boost_def():
|
boost_def::boost_def():
|
||||||
potion{potion_type::boost_def, -1} {}
|
potion{potion_type::boost_def, -1} {}
|
||||||
|
|
||||||
void boost_def::apply(enum race &race, int &HP, int &ATK, int &DEF,
|
void boost_def::apply(enum race &race, int &HP, int &ATK, int &DEF,
|
||||||
float &base_hit_rate) {
|
float &base_hit_rate) {
|
||||||
if (remaining_duration > 0) {
|
if (remaining_duration > 0) {
|
||||||
if (race == rdrow)
|
if (race == rdrow)
|
||||||
DEF += BOOST_DEF_DROW;
|
DEF += BOOST_DEF_DROW;
|
||||||
else
|
else
|
||||||
DEF += BOOST_DEF;
|
DEF += BOOST_DEF;
|
||||||
|
|
||||||
--remaining_duration;
|
--remaining_duration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int boost_def::get_priority() const {
|
int boost_def::get_priority() const {
|
||||||
return CALC_ADD_BASE;
|
return CALC_ADD_BASE;
|
||||||
}
|
}
|
@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
class boost_def final: public potion {
|
class boost_def final: public potion {
|
||||||
public:
|
public:
|
||||||
boost_def();
|
boost_def();
|
||||||
void apply(enum race &race, int &HP, int &ATK, int &DEF,
|
void apply(enum race &race, int &HP, int &ATK, int &DEF,
|
||||||
float &base_hit_rate) override;
|
float &base_hit_rate) override;
|
||||||
int get_priority() const override;
|
int get_priority() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,156 +3,154 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
character::character(RNG &rng, const enum race &nrace):
|
character::character(RNG &rng, const enum race &nrace):
|
||||||
rng{rng},
|
rng{rng},
|
||||||
race{nrace}, HP{STARTING_HP[race]},
|
race{nrace}, HP{STARTING_HP[race]},
|
||||||
ATK{STARTING_ATK[race]}, DEF{STARTING_DEF[race]} {}
|
ATK{STARTING_ATK[race]}, DEF{STARTING_DEF[race]} {}
|
||||||
|
|
||||||
enum race character::get_race() const {
|
enum race character::get_race() const {
|
||||||
return race;
|
return race;
|
||||||
}
|
}
|
||||||
|
|
||||||
position character::get_position() const {
|
position character::get_position() const {
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
int character::get_HP() const {
|
int character::get_HP() const {
|
||||||
return HP;
|
return HP;
|
||||||
}
|
}
|
||||||
|
|
||||||
int character::get_ATK() const {
|
int character::get_ATK() const {
|
||||||
return ATK;
|
return ATK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int character::get_DEF() const {
|
int character::get_DEF() const {
|
||||||
return DEF;
|
return DEF;
|
||||||
}
|
}
|
||||||
|
|
||||||
int character::get_gold() const {
|
int character::get_gold() const {
|
||||||
return gold;
|
return gold;
|
||||||
}
|
}
|
||||||
|
|
||||||
float character::get_hitrate() const {
|
float character::get_hitrate() const {
|
||||||
return base_hit_rate;
|
return base_hit_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool character::is_hostile() const {
|
bool character::is_hostile() const {
|
||||||
return hostile;
|
return hostile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void character::set_position(const position &npos) {
|
void character::set_position(const position &npos) {
|
||||||
pos = npos;
|
pos = npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void character::set_HP(const int nHP) {
|
void character::set_HP(const int nHP) {
|
||||||
HP = nHP;
|
HP = nHP;
|
||||||
}
|
}
|
||||||
|
|
||||||
void character::set_ATK(const int nATK) {
|
void character::set_ATK(const int nATK) {
|
||||||
ATK = nATK;
|
ATK = nATK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void character::set_DEF(const int nDEF) {
|
void character::set_DEF(const int nDEF) {
|
||||||
DEF = nDEF;
|
DEF = nDEF;
|
||||||
}
|
}
|
||||||
|
|
||||||
void character::set_gold(const int ngold) {
|
void character::set_gold(const int ngold) {
|
||||||
gold = ngold;
|
gold = ngold;
|
||||||
}
|
}
|
||||||
|
|
||||||
void character::set_hitrate(const float nhitrate) {
|
void character::set_hitrate(const float nhitrate) {
|
||||||
base_hit_rate = nhitrate;
|
base_hit_rate = nhitrate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void character::set_hostile(const bool is_hostile) {
|
void character::set_hostile(const bool is_hostile) {
|
||||||
hostile = is_hostile;
|
hostile = is_hostile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void character::apply_buff(const stat_name statn, const int amount) {
|
void character::apply_buff(const stat_name statn, const int amount) {
|
||||||
// TODO: add checks for bounds
|
// TODO: add checks for bounds
|
||||||
switch (statn) {
|
switch (statn) {
|
||||||
case stat_name::HP:
|
case stat_name::HP:
|
||||||
HP += amount;
|
HP += amount;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case stat_name::ATK:
|
case stat_name::ATK:
|
||||||
ATK += amount;
|
ATK += amount;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case stat_name::DEF:
|
case stat_name::DEF:
|
||||||
DEF += amount;
|
DEF += amount;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case stat_name::hostile: {
|
case stat_name::hostile: {
|
||||||
if (amount > 0)
|
if (amount > 0)
|
||||||
hostile = true;
|
hostile = true;
|
||||||
else
|
else
|
||||||
hostile = false;
|
hostile = false;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
direction_list character::moveable(const position_list &available_positions)
|
direction_list character::moveable(const position_list &available_positions)
|
||||||
const {
|
const {
|
||||||
direction_list result;
|
direction_list result;
|
||||||
|
|
||||||
for (int i = 0; i < DIRECTION_CNT; ++i)
|
for (int i = 0; i < DIRECTION_CNT; ++i)
|
||||||
if (find(available_positions, pos + MOVE[i])
|
if (find(available_positions, pos + MOVE[i])
|
||||||
!= available_positions.size())
|
!= available_positions.size())
|
||||||
result.push_back((direction)i);
|
result.push_back((direction)i);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result character::apply(direction &dir, const potion_list &potions) {
|
result character::apply(direction &dir, const potion_list &potions) {
|
||||||
// TODO: implement this after implementing potions
|
// TODO: implement this after implementing potions
|
||||||
return result::fine;
|
return result::fine;
|
||||||
}
|
}
|
||||||
|
|
||||||
position_list remove_from_list(const position_list &sorted_positions,
|
position_list remove_from_list(const position_list &sorted_positions,
|
||||||
position_list excluded) {
|
position_list excluded) {
|
||||||
std::sort(excluded.begin(), excluded.end());
|
std::sort(excluded.begin(), excluded.end());
|
||||||
|
|
||||||
position_list result{sorted_positions.size() - excluded.size()};
|
position_list result{sorted_positions.size() - excluded.size()};
|
||||||
|
|
||||||
auto exc = excluded.begin();
|
auto exc = excluded.begin();
|
||||||
|
|
||||||
for (auto src : sorted_positions) {
|
for (auto src : sorted_positions) {
|
||||||
if (exc != excluded.end() && src == *exc)
|
if (exc != excluded.end() && src == *exc)
|
||||||
++exc;
|
++exc;
|
||||||
else
|
else
|
||||||
result.push_back(src);
|
result.push_back(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// IMPORTANT: remember to check if player is on the stairs
|
// IMPORTANT: remember to check if player is on the stairs
|
||||||
result character::move(const direction dir,
|
result character::move(const direction dir,
|
||||||
const position_list &available_positions) {
|
const position_list &available_positions) {
|
||||||
if (find(available_positions, pos + MOVE[dir])
|
if (find(available_positions, pos + MOVE[dir])
|
||||||
!= available_positions.size()) {
|
!= available_positions.size()) {
|
||||||
pos += MOVE[dir];
|
pos += MOVE[dir];
|
||||||
return result::moved;
|
return result::moved;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result::fine;
|
return result::fine;
|
||||||
}
|
}
|
||||||
|
|
||||||
result character::move_or_attack(const direction dir,
|
result character::move_or_attack(const direction dir,
|
||||||
const position_list &available_positions,
|
const position_list &available_positions,
|
||||||
character_list &chlist) {
|
character_list &chlist) {
|
||||||
auto res = this->move(dir, available_positions);
|
auto res = this->move(dir, available_positions);
|
||||||
|
|
||||||
if (res != result::fine)
|
if (res != result::fine)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
return this->attack(dir, chlist);
|
return this->attack(dir, chlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int calc_dmg(const int ATK, const int DEF) {
|
int calc_dmg(const int ATK, const int DEF) {
|
||||||
return ceil((100 / (100 + DEF)) * ATK);
|
return ceil((100 / (100 + DEF)) * ATK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,71 +25,70 @@ typedef std::vector<character> character_list;
|
|||||||
|
|
||||||
class character {
|
class character {
|
||||||
public:
|
public:
|
||||||
character(RNG &rng, const race &nrace); // fills out the starting stats
|
character(RNG &rng, const race &nrace); // fills out the starting stats
|
||||||
|
|
||||||
// usually I wouldn't do this but considering that the map has
|
// usually I wouldn't do this but considering that the map has
|
||||||
// a super small size an O(n) solution is acceptable
|
// a super small size an O(n) solution is acceptable
|
||||||
// IMPORTANT: available_positions do NOT have characters in them
|
// IMPORTANT: available_positions do NOT have characters in them
|
||||||
direction_list moveable(const position_list &available_positions) const;
|
direction_list moveable(const position_list &available_positions) const;
|
||||||
virtual result move(const direction dir,
|
virtual result move(const direction dir,
|
||||||
const position_list &available_positions);
|
const position_list &available_positions);
|
||||||
virtual result attack(const direction dir,
|
virtual result attack(const direction dir,
|
||||||
character_list &chlist) = 0;
|
character_list &chlist) = 0;
|
||||||
virtual result move_or_attack(const direction dir,
|
virtual result move_or_attack(const direction dir,
|
||||||
const position_list &available_positions,
|
const position_list &available_positions,
|
||||||
character_list &chlist);
|
character_list &chlist);
|
||||||
virtual result apply(direction &dir,
|
virtual result apply(direction &dir,
|
||||||
const potion_list &potions);
|
const potion_list &potions);
|
||||||
virtual result get_hit(const enum race &race, const int atk,
|
virtual result get_hit(const enum race &race, const int atk,
|
||||||
const float hitrate) = 0;
|
const float hitrate) = 0;
|
||||||
|
|
||||||
enum race get_race() const;
|
enum race get_race() const;
|
||||||
position get_position() const;
|
position get_position() const;
|
||||||
int get_HP() const;
|
int get_HP() const;
|
||||||
int get_ATK() const;
|
int get_ATK() const;
|
||||||
int get_DEF() const;
|
int get_DEF() const;
|
||||||
int get_gold() const;
|
int get_gold() const;
|
||||||
float get_hitrate() const;
|
float get_hitrate() const;
|
||||||
bool is_hostile() const;
|
bool is_hostile() const;
|
||||||
|
|
||||||
void set_position(const position &npos);
|
void set_position(const position &npos);
|
||||||
void set_HP(const int nHP);
|
void set_HP(const int nHP);
|
||||||
void set_ATK(const int nATK);
|
void set_ATK(const int nATK);
|
||||||
void set_DEF(const int nDEF);
|
void set_DEF(const int nDEF);
|
||||||
void set_gold(const int ngold);
|
void set_gold(const int ngold);
|
||||||
void set_hitrate(const float nhitrate);
|
void set_hitrate(const float nhitrate);
|
||||||
void set_hostile(const bool is_hostile);
|
void set_hostile(const bool is_hostile);
|
||||||
|
|
||||||
// if stat is hostile, positive to set it to hostile,
|
// if stat is hostile, positive to set it to hostile,
|
||||||
// negative to set it to peaceful
|
// negative to set it to peaceful
|
||||||
void apply_buff(const stat_name statn, const int amount);
|
void apply_buff(const stat_name statn, const int amount);
|
||||||
// void apply_buff(const stat_name statn, const float mul);
|
// void apply_buff(const stat_name statn, const float mul);
|
||||||
// reserved for later
|
// reserved for later
|
||||||
protected:
|
protected:
|
||||||
RNG &rng;
|
RNG &rng;
|
||||||
const enum race race;
|
const enum race race;
|
||||||
|
|
||||||
int HP;
|
int HP;
|
||||||
|
|
||||||
// IMPORTANT: keep track of ATK and DEF in game at turn time
|
// IMPORTANT: keep track of ATK and DEF in game at turn time
|
||||||
int ATK;
|
int ATK;
|
||||||
int DEF;
|
int DEF;
|
||||||
|
|
||||||
position pos;
|
position pos;
|
||||||
|
|
||||||
int gold; // characters spawn with gold
|
int gold; // characters spawn with gold
|
||||||
potion_list potions;// inventory inventory; // Reserved
|
potion_list potions;// inventory inventory; // Reserved
|
||||||
|
|
||||||
float base_hit_rate; // requires: between [0,1]
|
float base_hit_rate; // requires: between [0,1]
|
||||||
|
|
||||||
bool hostile;
|
bool hostile;
|
||||||
};
|
};
|
||||||
|
|
||||||
// requires: all elements of excluded are in sorted_positions
|
// requires: all elements of excluded are in sorted_positions
|
||||||
position_list remove_from_list(const position_list &sorted_positions,
|
position_list remove_from_list(const position_list &sorted_positions,
|
||||||
position_list excluded);
|
position_list excluded);
|
||||||
|
|
||||||
|
|
||||||
int calc_dmg(const int ATK, const int DEF);
|
int calc_dmg(const int ATK, const int DEF);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
class console_input final : public input {
|
class console_input final : public input {
|
||||||
private:
|
private:
|
||||||
std::istream ∈
|
std::istream ∈
|
||||||
public:
|
public:
|
||||||
// This is for cin
|
// This is for cin
|
||||||
console_input(std::istream &cin);
|
console_input(std::istream &cin);
|
||||||
game_command get_command() override;
|
game_command get_command() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
|
|
||||||
|
|
||||||
console_output::console_output(std::ostream &cout): out{cout} {}
|
console_output::console_output(std::ostream &cout): out{cout} {}
|
||||||
|
|
||||||
/* Attributes
|
/* Attributes
|
||||||
@ -30,70 +29,70 @@ console_output::console_output(std::ostream &cout): out{cout} {}
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
std::string console_output::get_code(const int attrs) {
|
std::string console_output::get_code(const int attrs) {
|
||||||
if (attrs < 255)
|
if (attrs < 255)
|
||||||
return "\033[0m";
|
return "\033[0m";
|
||||||
|
|
||||||
std::string result = "\033[0m\033[";
|
std::string result = "\033[0m\033[";
|
||||||
|
|
||||||
if (attrs & A_BOLD)
|
if (attrs & A_BOLD)
|
||||||
result += "1;";
|
result += "1;";
|
||||||
|
|
||||||
if (attrs & A_UNDERLINE)
|
if (attrs & A_UNDERLINE)
|
||||||
result += "4;";
|
result += "4;";
|
||||||
|
|
||||||
if (attrs & A_STANDOUT)
|
if (attrs & A_STANDOUT)
|
||||||
result += "7;";
|
result += "7;";
|
||||||
|
|
||||||
if ((attrs & COLOR_PAIR(COLOR_WHITE)) == COLOR_PAIR(COLOR_WHITE))
|
if ((attrs & COLOR_PAIR(COLOR_WHITE)) == COLOR_PAIR(COLOR_WHITE))
|
||||||
result += "37;";
|
result += "37;";
|
||||||
else if ((attrs & COLOR_PAIR(COLOR_CYAN)) == COLOR_PAIR(COLOR_CYAN))
|
else if ((attrs & COLOR_PAIR(COLOR_CYAN)) == COLOR_PAIR(COLOR_CYAN))
|
||||||
result += "36;";
|
result += "36;";
|
||||||
else if ((attrs & COLOR_PAIR(COLOR_MAGENTA)) == COLOR_PAIR(COLOR_MAGENTA))
|
else if ((attrs & COLOR_PAIR(COLOR_MAGENTA)) == COLOR_PAIR(COLOR_MAGENTA))
|
||||||
result += "35;";
|
result += "35;";
|
||||||
else if ((attrs & COLOR_PAIR(COLOR_BLUE)) == COLOR_PAIR(COLOR_BLUE))
|
else if ((attrs & COLOR_PAIR(COLOR_BLUE)) == COLOR_PAIR(COLOR_BLUE))
|
||||||
result += "34;";
|
result += "34;";
|
||||||
else if ((attrs & COLOR_PAIR(COLOR_YELLOW)) == COLOR_PAIR(COLOR_YELLOW))
|
else if ((attrs & COLOR_PAIR(COLOR_YELLOW)) == COLOR_PAIR(COLOR_YELLOW))
|
||||||
result += "33;";
|
result += "33;";
|
||||||
else if ((attrs & COLOR_PAIR(COLOR_RED)) == COLOR_PAIR(COLOR_RED))
|
else if ((attrs & COLOR_PAIR(COLOR_RED)) == COLOR_PAIR(COLOR_RED))
|
||||||
result += "31;";
|
result += "31;";
|
||||||
else if ((attrs & COLOR_PAIR(COLOR_GREEN)) == COLOR_PAIR(COLOR_GREEN))
|
else if ((attrs & COLOR_PAIR(COLOR_GREEN)) == COLOR_PAIR(COLOR_GREEN))
|
||||||
result += "32;";
|
result += "32;";
|
||||||
else if ((attrs & COLOR_PAIR(COLOR_BLACK_ON_WHITE)) == COLOR_BLACK_ON_WHITE)
|
else if ((attrs & COLOR_PAIR(COLOR_BLACK_ON_WHITE)) == COLOR_BLACK_ON_WHITE)
|
||||||
result += "30;47;";
|
result += "30;47;";
|
||||||
|
|
||||||
result[result.length() - 1] = 'm';
|
result[result.length() - 1] = 'm';
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void console_output::render() {
|
void console_output::render() {
|
||||||
out << "\x1B[2J\x1B[H";
|
out << "\x1B[2J\x1B[H";
|
||||||
|
|
||||||
for (std::size_t idx = 0; idx < contents.size(); ++idx) {
|
for (std::size_t idx = 0; idx < contents.size(); ++idx) {
|
||||||
if (idx % DISPLAY_WIDTH == 0 && idx)
|
if (idx % DISPLAY_WIDTH == 0 && idx)
|
||||||
out << std::endl;
|
out << std::endl;
|
||||||
|
|
||||||
out << get_code(contents[idx])
|
out << get_code(contents[idx])
|
||||||
<< (char)(contents[idx] ? contents[idx] : ' ');
|
<< (char)(contents[idx] ? contents[idx] : ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
out << std::endl;
|
out << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void console_output::print_char(const position &pos, const char ch,
|
void console_output::print_char(const position &pos, const char ch,
|
||||||
const int attrs) {
|
const int attrs) {
|
||||||
if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT)
|
if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
contents[pos.y * DISPLAY_WIDTH + pos.x] = attrs | ch;
|
contents[pos.y * DISPLAY_WIDTH + pos.x] = attrs | ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
void console_output::print_str(const position &pos, const std::string &str,
|
void console_output::print_str(const position &pos, const std::string &str,
|
||||||
const int attrs) {
|
const int attrs) {
|
||||||
if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT)
|
if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int head = pos.y * DISPLAY_WIDTH + pos.x;
|
int head = pos.y * DISPLAY_WIDTH + pos.x;
|
||||||
|
|
||||||
for (std::size_t i = 0; i < str.length(); ++i)
|
for (std::size_t i = 0; i < str.length(); ++i)
|
||||||
contents[i + head] = attrs | str[i];
|
contents[i + head] = attrs | str[i];
|
||||||
}
|
}
|
||||||
|
@ -6,16 +6,16 @@
|
|||||||
|
|
||||||
class console_output final : public display {
|
class console_output final : public display {
|
||||||
private:
|
private:
|
||||||
std::ostream &out;
|
std::ostream &out;
|
||||||
std::string get_code(const int attrs);
|
std::string get_code(const int attrs);
|
||||||
public:
|
public:
|
||||||
console_output(std::ostream &cout);
|
console_output(std::ostream &cout);
|
||||||
|
|
||||||
void render() override;
|
void render() override;
|
||||||
void print_char(const position &pos,
|
void print_char(const position &pos,
|
||||||
const char ch, const int attrs) override;
|
const char ch, const int attrs) override;
|
||||||
void print_str(const position &pos,
|
void print_str(const position &pos,
|
||||||
const std::string &str, const int attrs) override;
|
const std::string &str, const int attrs) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -53,8 +53,6 @@ const int CALC_ADD_LATER = 2;
|
|||||||
const int CALC_MUL_LATER = 3;
|
const int CALC_MUL_LATER = 3;
|
||||||
const int CALC_ADD_FIXED = 4;
|
const int CALC_ADD_FIXED = 4;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
@ -63,8 +61,8 @@ enum direction { north = 0, south, east, west, northeast,
|
|||||||
};
|
};
|
||||||
|
|
||||||
const position MOVE[DIRECTION_CNT] = {
|
const position MOVE[DIRECTION_CNT] = {
|
||||||
{0, -1}, {0, 1}, {1, 0}, {-1, 0},
|
{0, -1}, {0, 1}, {1, 0}, {-1, 0},
|
||||||
{1, -1}, {-1, -1}, {1, 1}, {-1, 1}
|
{1, -1}, {-1, -1}, {1, 1}, {-1, 1}
|
||||||
};
|
};
|
||||||
|
|
||||||
const int MAP_HEIGHT = 25;
|
const int MAP_HEIGHT = 25;
|
||||||
|
@ -1,84 +1,84 @@
|
|||||||
#include "curses_input.h"
|
#include "curses_input.h"
|
||||||
|
|
||||||
curses_input::curses_input(cursor &new_curse):
|
curses_input::curses_input(cursor &new_curse):
|
||||||
curse{new_curse} {}
|
curse{new_curse} {}
|
||||||
|
|
||||||
game_command curses_input::get_command() {
|
game_command curses_input::get_command() {
|
||||||
switch (curse.getcmd()) {
|
switch (curse.getcmd()) {
|
||||||
case 'h':
|
case 'h':
|
||||||
return game_command::move_west;
|
return game_command::move_west;
|
||||||
|
|
||||||
case 'j':
|
case 'j':
|
||||||
return game_command::move_south;
|
return game_command::move_south;
|
||||||
|
|
||||||
case 'k':
|
case 'k':
|
||||||
return game_command::move_north;
|
return game_command::move_north;
|
||||||
|
|
||||||
case 'l':
|
case 'l':
|
||||||
return game_command::move_east;
|
return game_command::move_east;
|
||||||
|
|
||||||
case 'y':
|
case 'y':
|
||||||
return game_command::move_northwest;
|
return game_command::move_northwest;
|
||||||
|
|
||||||
case 'u':
|
case 'u':
|
||||||
return game_command::move_northeast;
|
return game_command::move_northeast;
|
||||||
|
|
||||||
case 'b':
|
case 'b':
|
||||||
return game_command::move_southwest;
|
return game_command::move_southwest;
|
||||||
|
|
||||||
case 'n':
|
case 'n':
|
||||||
return game_command::move_southeast;
|
return game_command::move_southeast;
|
||||||
|
|
||||||
case 'a':
|
case 'a':
|
||||||
break; // wait for another command
|
break; // wait for another command
|
||||||
|
|
||||||
case '<':
|
case '<':
|
||||||
return game_command::up_stairs;
|
return game_command::up_stairs;
|
||||||
|
|
||||||
case '>':
|
case '>':
|
||||||
return game_command::down_stairs;
|
return game_command::down_stairs;
|
||||||
|
|
||||||
case 'q':
|
case 'q':
|
||||||
return game_command_terminate;
|
return game_command_terminate;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
return game_command::the_world;
|
return game_command::the_world;
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
return game_restart;
|
return game_restart;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return game_command_pass;
|
return game_command_pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (curse.getcmd()) {
|
switch (curse.getcmd()) {
|
||||||
case 'h':
|
case 'h':
|
||||||
return game_command::apply_west;
|
return game_command::apply_west;
|
||||||
|
|
||||||
case 'j':
|
case 'j':
|
||||||
return game_command::apply_south;
|
return game_command::apply_south;
|
||||||
|
|
||||||
case 'k':
|
case 'k':
|
||||||
return game_command::apply_north;
|
return game_command::apply_north;
|
||||||
|
|
||||||
case 'l':
|
case 'l':
|
||||||
return game_command::apply_east;
|
return game_command::apply_east;
|
||||||
|
|
||||||
case 'y':
|
case 'y':
|
||||||
return game_command::apply_northwest;
|
return game_command::apply_northwest;
|
||||||
|
|
||||||
case 'u':
|
case 'u':
|
||||||
return game_command::apply_northeast;
|
return game_command::apply_northeast;
|
||||||
|
|
||||||
case 'b':
|
case 'b':
|
||||||
return game_command::apply_southwest;
|
return game_command::apply_southwest;
|
||||||
|
|
||||||
case 'n':
|
case 'n':
|
||||||
return game_command::apply_southeast;
|
return game_command::apply_southeast;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return game_command::apply_panic;
|
return game_command::apply_panic;
|
||||||
}
|
}
|
||||||
|
|
||||||
return game_command::game_command_panic;
|
return game_command::game_command_panic;
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
|
|
||||||
class curses_input final: public input {
|
class curses_input final: public input {
|
||||||
private:
|
private:
|
||||||
cursor &curse;
|
cursor &curse;
|
||||||
public:
|
public:
|
||||||
curses_input(cursor &new_curse);
|
curses_input(cursor &new_curse);
|
||||||
game_command get_command() override;
|
game_command get_command() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,36 +1,36 @@
|
|||||||
#include "curses_output.h"
|
#include "curses_output.h"
|
||||||
|
|
||||||
curses_output::curses_output(cursor &new_curse):
|
curses_output::curses_output(cursor &new_curse):
|
||||||
curse{new_curse} {}
|
curse{new_curse} {}
|
||||||
|
|
||||||
void curses_output::render() {
|
void curses_output::render() {
|
||||||
curse.show();
|
curse.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void curses_output::clear() {
|
void curses_output::clear() {
|
||||||
curse.clear();
|
curse.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void curses_output::print_char(const position &pos, const char ch,
|
void curses_output::print_char(const position &pos, const char ch,
|
||||||
const int attrs) {
|
const int attrs) {
|
||||||
if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT)
|
if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
curse.print_char(pos, ch, attrs);
|
curse.print_char(pos, ch, attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void curses_output::print_str(const position &pos, const std::string &str,
|
void curses_output::print_str(const position &pos, const std::string &str,
|
||||||
const int attrs) {
|
const int attrs) {
|
||||||
if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT)
|
if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
position tmp = pos;
|
position tmp = pos;
|
||||||
|
|
||||||
for (std::size_t i = 0; i < str.length(); ++i) {
|
for (std::size_t i = 0; i < str.length(); ++i) {
|
||||||
curse.print_char(tmp, str[i], attrs);
|
curse.print_char(tmp, str[i], attrs);
|
||||||
tmp += {1, 0};
|
tmp += {1, 0};
|
||||||
|
|
||||||
if (tmp.x >= DISPLAY_WIDTH)
|
if (tmp.x >= DISPLAY_WIDTH)
|
||||||
tmp = {0, tmp.y + 1};
|
tmp = {0, tmp.y + 1};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,16 +8,16 @@
|
|||||||
|
|
||||||
class curses_output final : public display {
|
class curses_output final : public display {
|
||||||
private:
|
private:
|
||||||
cursor &curse;
|
cursor &curse;
|
||||||
public:
|
public:
|
||||||
curses_output(cursor &new_curse);
|
curses_output(cursor &new_curse);
|
||||||
|
|
||||||
void render() override;
|
void render() override;
|
||||||
void clear() override;
|
void clear() override;
|
||||||
void print_char(const position &pos,
|
void print_char(const position &pos,
|
||||||
const char ch, const int attrs) override;
|
const char ch, const int attrs) override;
|
||||||
void print_str(const position &pos,
|
void print_str(const position &pos,
|
||||||
const std::string &str, const int attrs) override;
|
const std::string &str, const int attrs) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -2,53 +2,53 @@
|
|||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
|
|
||||||
cursor::cursor() {
|
cursor::cursor() {
|
||||||
initscr();
|
initscr();
|
||||||
|
|
||||||
if (has_colors()) {
|
if (has_colors()) {
|
||||||
start_color();
|
start_color();
|
||||||
init_pair(COLOR_RED, COLOR_RED, COLOR_BLACK);
|
init_pair(COLOR_RED, COLOR_RED, COLOR_BLACK);
|
||||||
init_pair(COLOR_GREEN, COLOR_GREEN, COLOR_BLACK);
|
init_pair(COLOR_GREEN, COLOR_GREEN, COLOR_BLACK);
|
||||||
init_pair(COLOR_YELLOW, COLOR_YELLOW, COLOR_BLACK);
|
init_pair(COLOR_YELLOW, COLOR_YELLOW, COLOR_BLACK);
|
||||||
init_pair(COLOR_BLUE, COLOR_BLUE, COLOR_BLACK);
|
init_pair(COLOR_BLUE, COLOR_BLUE, COLOR_BLACK);
|
||||||
init_pair(COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
|
init_pair(COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
|
||||||
init_pair(COLOR_CYAN, COLOR_CYAN, COLOR_BLACK);
|
init_pair(COLOR_CYAN, COLOR_CYAN, COLOR_BLACK);
|
||||||
init_pair(COLOR_WHITE, COLOR_WHITE, COLOR_BLACK);
|
init_pair(COLOR_WHITE, COLOR_WHITE, COLOR_BLACK);
|
||||||
init_pair(COLOR_BLACK_ON_WHITE, COLOR_BLACK, COLOR_WHITE);
|
init_pair(COLOR_BLACK_ON_WHITE, COLOR_BLACK, COLOR_WHITE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor::~cursor() {
|
cursor::~cursor() {
|
||||||
endwin();
|
endwin();
|
||||||
}
|
}
|
||||||
|
|
||||||
int cursor::getcmd() const {
|
int cursor::getcmd() const {
|
||||||
return getch();
|
return getch();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cursor::show() const {
|
void cursor::show() const {
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cursor::clear() const {
|
void cursor::clear() const {
|
||||||
::clear();
|
::clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cursor::print_char(const position &pos, const char ch,
|
void cursor::print_char(const position &pos, const char ch,
|
||||||
const int attrs) const {
|
const int attrs) const {
|
||||||
attrset(attrs);
|
attrset(attrs);
|
||||||
mvaddch(pos.y, pos.x, ch);
|
mvaddch(pos.y, pos.x, ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cursor::print_str(const position &pos, const std::string str,
|
void cursor::print_str(const position &pos, const std::string str,
|
||||||
const int attrs) const {
|
const int attrs) const {
|
||||||
attrset(attrs);
|
attrset(attrs);
|
||||||
mvaddstr(pos.y, pos.x, str.c_str());
|
mvaddstr(pos.y, pos.x, str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_terminal_size() {
|
bool check_terminal_size() {
|
||||||
int max_x;
|
int max_x;
|
||||||
int max_y;
|
int max_y;
|
||||||
getmaxyx(stdscr, max_y, max_x);
|
getmaxyx(stdscr, max_y, max_x);
|
||||||
|
|
||||||
return max_x >= DISPLAY_WIDTH && max_y >= DISPLAY_HEIGHT;
|
return max_x >= DISPLAY_WIDTH && max_y >= DISPLAY_HEIGHT;
|
||||||
}
|
}
|
||||||
|
16
src/cursor.h
16
src/cursor.h
@ -37,20 +37,20 @@
|
|||||||
class cursor final {
|
class cursor final {
|
||||||
private:
|
private:
|
||||||
public:
|
public:
|
||||||
cursor();
|
cursor();
|
||||||
|
|
||||||
~cursor();
|
~cursor();
|
||||||
|
|
||||||
int getcmd() const;
|
int getcmd() const;
|
||||||
|
|
||||||
void show() const;
|
void show() const;
|
||||||
|
|
||||||
void clear() const ;
|
void clear() const ;
|
||||||
|
|
||||||
void print_char(const position &pos, const char ch, const int attrs) const;
|
void print_char(const position &pos, const char ch, const int attrs) const;
|
||||||
|
|
||||||
void print_str(const position &head, const std::string str,
|
void print_str(const position &head, const std::string str,
|
||||||
const int attrs) const;
|
const int attrs) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// IMPORTANT: this will fail when terminal size changes
|
// IMPORTANT: this will fail when terminal size changes
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
#include "display.h"
|
#include "display.h"
|
||||||
|
|
||||||
display::display():
|
display::display():
|
||||||
contents{DISPLAY_BUFFER_SIZE, 0} {
|
contents{DISPLAY_BUFFER_SIZE, 0} {
|
||||||
for (int i = 0; i < DISPLAY_BUFFER_SIZE; ++i)
|
for (int i = 0; i < DISPLAY_BUFFER_SIZE; ++i)
|
||||||
contents.push_back(0);
|
contents.push_back(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void display::clear() {
|
void display::clear() {
|
||||||
contents.clear();
|
contents.clear();
|
||||||
contents.reserve(DISPLAY_BUFFER_SIZE);
|
contents.reserve(DISPLAY_BUFFER_SIZE);
|
||||||
|
|
||||||
for (int i = 0; i < DISPLAY_BUFFER_SIZE; ++i)
|
for (int i = 0; i < DISPLAY_BUFFER_SIZE; ++i)
|
||||||
contents.push_back(0);
|
contents.push_back(0);
|
||||||
}
|
}
|
||||||
|
@ -8,28 +8,28 @@
|
|||||||
|
|
||||||
class display {
|
class display {
|
||||||
protected:
|
protected:
|
||||||
// use an array of ints to keep track of what's on the screen
|
// use an array of ints to keep track of what's on the screen
|
||||||
// This will have a bit of buffer for the last line
|
// This will have a bit of buffer for the last line
|
||||||
// just in case it overflows
|
// just in case it overflows
|
||||||
std::vector<int> contents;
|
std::vector<int> contents;
|
||||||
public:
|
public:
|
||||||
display();
|
display();
|
||||||
|
|
||||||
virtual ~display() = default;
|
virtual ~display() = default;
|
||||||
|
|
||||||
// Only call this to refresh the entire output
|
// Only call this to refresh the entire output
|
||||||
virtual void render() = 0;
|
virtual void render() = 0;
|
||||||
|
|
||||||
// Clears the contents buffer
|
// Clears the contents buffer
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
|
||||||
virtual void print_char(const position &pos, const char ch,
|
virtual void print_char(const position &pos, const char ch,
|
||||||
const int attrs =
|
const int attrs =
|
||||||
A_NORMAL | COLOR_PAIR(COLOR_WHITE)) = 0;
|
A_NORMAL | COLOR_PAIR(COLOR_WHITE)) = 0;
|
||||||
virtual void print_str(const position &pos, const std::string &str,
|
virtual void print_str(const position &pos, const std::string &str,
|
||||||
const int attrs =
|
const int attrs =
|
||||||
A_NORMAL | COLOR_PAIR(COLOR_WHITE)) = 0;
|
A_NORMAL | COLOR_PAIR(COLOR_WHITE)) = 0;
|
||||||
// default arguments are to be set in the base class's declaration
|
// default arguments are to be set in the base class's declaration
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
32
src/drow.cc
32
src/drow.cc
@ -3,30 +3,30 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
drow::drow(RNG &rng, const position_list &available_positions):
|
drow::drow(RNG &rng, const position_list &available_positions):
|
||||||
character{rng, race::rdrow} {
|
character{rng, race::rdrow} {
|
||||||
pos = available_positions[rng.rand_under(available_positions.size())];
|
pos = available_positions[rng.rand_under(available_positions.size())];
|
||||||
gold = 0;
|
gold = 0;
|
||||||
hostile = true;
|
hostile = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
result drow::attack(const direction dir, character_list &chlist) {
|
result drow::attack(const direction dir, character_list &chlist) {
|
||||||
position tmp{pos + MOVE[dir]};
|
position tmp{pos + MOVE[dir]};
|
||||||
|
|
||||||
for (auto &ch : chlist)
|
for (auto &ch : chlist)
|
||||||
if (tmp == ch.get_position()) {
|
if (tmp == ch.get_position()) {
|
||||||
return ch.get_hit(race, ATK, base_hit_rate);
|
return ch.get_hit(race, ATK, base_hit_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result::fine;
|
return result::fine;
|
||||||
}
|
}
|
||||||
|
|
||||||
result drow::get_hit(const enum race &race, const int atk,
|
result drow::get_hit(const enum race &race, const int atk,
|
||||||
const float hitrate) {
|
const float hitrate) {
|
||||||
if (rng.rand_num() <= hitrate * (float)RAND_MAX)
|
if (rng.rand_num() <= hitrate * (float)RAND_MAX)
|
||||||
HP = std::max(HP - calc_dmg(atk, DEF), 0);
|
HP = std::max(HP - calc_dmg(atk, DEF), 0);
|
||||||
|
|
||||||
if (HP == 0)
|
if (HP == 0)
|
||||||
return result::died;
|
return result::died;
|
||||||
|
|
||||||
return result::hit;
|
return result::hit;
|
||||||
}
|
}
|
||||||
|
12
src/drow.h
12
src/drow.h
@ -4,12 +4,12 @@
|
|||||||
|
|
||||||
class drow final: public character {
|
class drow final: public character {
|
||||||
public:
|
public:
|
||||||
drow(RNG &rng,
|
drow(RNG &rng,
|
||||||
const position_list &available_positions);
|
const position_list &available_positions);
|
||||||
virtual result attack(const direction dir,
|
virtual result attack(const direction dir,
|
||||||
character_list &chlist) override;
|
character_list &chlist) override;
|
||||||
virtual result get_hit(const enum race &race, const int atk,
|
virtual result get_hit(const enum race &race, const int atk,
|
||||||
const float hit_rate) override;
|
const float hit_rate) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,40 +3,40 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
file_input::file_input(std::ifstream &&ifs):
|
file_input::file_input(std::ifstream &&ifs):
|
||||||
in{std::move(ifs)} {}
|
in{std::move(ifs)} {}
|
||||||
|
|
||||||
game_command file_input::get_command() {
|
game_command file_input::get_command() {
|
||||||
std::string cmd;
|
std::string cmd;
|
||||||
|
in >> cmd;
|
||||||
|
game_command tmp;
|
||||||
|
|
||||||
|
if (in.eof())
|
||||||
|
return game_command_terminate;
|
||||||
|
|
||||||
|
if (cmd == "q")
|
||||||
|
return game_command_terminate;
|
||||||
|
else if (cmd == "f")
|
||||||
|
return the_world;
|
||||||
|
else if (cmd == "r")
|
||||||
|
return game_restart;
|
||||||
|
else if (cmd == "u" || cmd == "a") {
|
||||||
|
bool use = cmd == "u";
|
||||||
|
|
||||||
in >> cmd;
|
in >> cmd;
|
||||||
game_command tmp;
|
|
||||||
|
|
||||||
if (in.eof())
|
if (in.eof())
|
||||||
return game_command_terminate;
|
return game_command_panic;
|
||||||
|
|
||||||
if (cmd == "q")
|
return (game_command)((tmp = get_direction(cmd)) ==
|
||||||
return game_command_terminate;
|
game_command_panic
|
||||||
else if (cmd == "f")
|
? tmp : tmp - move_north +
|
||||||
return the_world;
|
(use ? apply_north : attack_north));
|
||||||
else if (cmd == "r")
|
} else {
|
||||||
return game_restart;
|
auto tmp = get_direction(cmd);
|
||||||
else if (cmd == "u" || cmd == "a") {
|
|
||||||
bool use = cmd == "u";
|
|
||||||
|
|
||||||
in >> cmd;
|
if (tmp != game_command_panic)
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
if (in.eof())
|
return game_command_pass;
|
||||||
return game_command_panic;
|
|
||||||
|
|
||||||
return (game_command)((tmp = get_direction(cmd)) ==
|
|
||||||
game_command_panic
|
|
||||||
? tmp : tmp - move_north +
|
|
||||||
(use ? apply_north : attack_north));
|
|
||||||
} else {
|
|
||||||
auto tmp = get_direction(cmd);
|
|
||||||
|
|
||||||
if (tmp != game_command_panic)
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return game_command_pass;
|
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
class file_input final : public input {
|
class file_input final : public input {
|
||||||
private:
|
private:
|
||||||
std::ifstream in;
|
std::ifstream in;
|
||||||
public:
|
public:
|
||||||
// This is for cin
|
// This is for cin
|
||||||
file_input(std::ifstream &&ifs);
|
file_input(std::ifstream &&ifs);
|
||||||
game_command get_command() override;
|
game_command get_command() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,34 +3,34 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
file_output::file_output(std::ofstream &&ofs):
|
file_output::file_output(std::ofstream &&ofs):
|
||||||
out{std::move(ofs)} {}
|
out{std::move(ofs)} {}
|
||||||
|
|
||||||
void file_output::render() {
|
void file_output::render() {
|
||||||
for (std::size_t idx = 0; idx < contents.size(); ++idx) {
|
for (std::size_t idx = 0; idx < contents.size(); ++idx) {
|
||||||
if (idx % DISPLAY_WIDTH == 0 && idx)
|
if (idx % DISPLAY_WIDTH == 0 && idx)
|
||||||
out << std::endl;
|
out << std::endl;
|
||||||
|
|
||||||
out << (char)(contents[idx] ? contents[idx] : ' ');
|
out << (char)(contents[idx] ? contents[idx] : ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
out << std::endl;
|
out << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void file_output::print_char(const position &pos, const char ch,
|
void file_output::print_char(const position &pos, const char ch,
|
||||||
const int attrs) {
|
const int attrs) {
|
||||||
if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT)
|
if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
contents[pos.y * DISPLAY_WIDTH + pos.x] = ch;
|
contents[pos.y * DISPLAY_WIDTH + pos.x] = ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
void file_output::print_str(const position &pos, const std::string &str,
|
void file_output::print_str(const position &pos, const std::string &str,
|
||||||
const int attrs) {
|
const int attrs) {
|
||||||
if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT)
|
if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int head = pos.y * DISPLAY_WIDTH + pos.x;
|
int head = pos.y * DISPLAY_WIDTH + pos.x;
|
||||||
|
|
||||||
for (std::size_t i = 0; i < str.length(); ++i)
|
for (std::size_t i = 0; i < str.length(); ++i)
|
||||||
contents[i + head] = str[i];
|
contents[i + head] = str[i];
|
||||||
}
|
}
|
||||||
|
@ -6,15 +6,15 @@
|
|||||||
|
|
||||||
class file_output final : public display {
|
class file_output final : public display {
|
||||||
private:
|
private:
|
||||||
std::ofstream out;
|
std::ofstream out;
|
||||||
public:
|
public:
|
||||||
file_output(std::ofstream &&ofs);
|
file_output(std::ofstream &&ofs);
|
||||||
|
|
||||||
void render() override;
|
void render() override;
|
||||||
void print_char(const position &pos,
|
void print_char(const position &pos,
|
||||||
const char ch, const int attrs) override;
|
const char ch, const int attrs) override;
|
||||||
void print_str(const position &pos,
|
void print_str(const position &pos,
|
||||||
const std::string &str, const int attrs) override;
|
const std::string &str, const int attrs) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,44 +1,44 @@
|
|||||||
#include "fraction.h"
|
#include "fraction.h"
|
||||||
|
|
||||||
fraction fraction::operator+(const fraction &frac) {
|
fraction fraction::operator+(const fraction &frac) {
|
||||||
fraction tmp = *this;
|
fraction tmp = *this;
|
||||||
tmp.numerator = tmp.numerator * frac.denominator +
|
tmp.numerator = tmp.numerator * frac.denominator +
|
||||||
tmp.denominator * frac.numerator;
|
tmp.denominator * frac.numerator;
|
||||||
tmp.denominator = tmp.denominator * frac.denominator;
|
tmp.denominator = tmp.denominator * frac.denominator;
|
||||||
return tmp.simplify();
|
return tmp.simplify();
|
||||||
}
|
}
|
||||||
|
|
||||||
fraction fraction::operator*(const fraction &frac) {
|
fraction fraction::operator*(const fraction &frac) {
|
||||||
fraction tmp = *this;
|
fraction tmp = *this;
|
||||||
tmp.numerator = tmp.numerator * frac.numerator;
|
tmp.numerator = tmp.numerator * frac.numerator;
|
||||||
tmp.denominator = tmp.denominator * frac.denominator;
|
tmp.denominator = tmp.denominator * frac.denominator;
|
||||||
return tmp.simplify();
|
return tmp.simplify();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fraction::operator==(const fraction &frac) {
|
bool fraction::operator==(const fraction &frac) {
|
||||||
this->simplify();
|
this->simplify();
|
||||||
return gcd(frac.numerator, this->numerator) == this->numerator &&
|
return gcd(frac.numerator, this->numerator) == this->numerator &&
|
||||||
gcd(frac.denominator, this->denominator) == this->denominator;
|
gcd(frac.denominator, this->denominator) == this->denominator;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fraction::operator!=(const fraction &frac) {
|
bool fraction::operator!=(const fraction &frac) {
|
||||||
return !(*this == frac);
|
return !(*this == frac);
|
||||||
}
|
}
|
||||||
|
|
||||||
fraction &fraction::simplify() {
|
fraction &fraction::simplify() {
|
||||||
int g = gcd(numerator, denominator);
|
int g = gcd(numerator, denominator);
|
||||||
numerator /= g;
|
numerator /= g;
|
||||||
denominator /= g;
|
denominator /= g;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
float fraction::real() {
|
float fraction::real() {
|
||||||
return (float)numerator / denominator;
|
return (float)numerator / denominator;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fraction::gcd(int a, int b) {
|
int fraction::gcd(int a, int b) {
|
||||||
if (a % b == 0)
|
if (a % b == 0)
|
||||||
return b;
|
return b;
|
||||||
|
|
||||||
return gcd(b, a % b);
|
return gcd(b, a % b);
|
||||||
}
|
}
|
||||||
|
@ -2,17 +2,17 @@
|
|||||||
#define __FRACTION_H__
|
#define __FRACTION_H__
|
||||||
|
|
||||||
struct fraction final {
|
struct fraction final {
|
||||||
int numerator;
|
int numerator;
|
||||||
int denominator;
|
int denominator;
|
||||||
|
|
||||||
fraction operator+(const fraction &frac);
|
fraction operator+(const fraction &frac);
|
||||||
fraction operator*(const fraction &frac);
|
fraction operator*(const fraction &frac);
|
||||||
bool operator==(const fraction &frac);
|
bool operator==(const fraction &frac);
|
||||||
bool operator!=(const fraction &frac);
|
bool operator!=(const fraction &frac);
|
||||||
fraction &simplify();
|
fraction &simplify();
|
||||||
float real();
|
float real();
|
||||||
private:
|
private:
|
||||||
int gcd(int a, int b);
|
int gcd(int a, int b);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
26
src/game.h
26
src/game.h
@ -12,21 +12,21 @@
|
|||||||
|
|
||||||
class game final {
|
class game final {
|
||||||
private:
|
private:
|
||||||
feature features;
|
feature features;
|
||||||
input ∈
|
input ∈
|
||||||
display &out;
|
display &out;
|
||||||
logger &log;
|
logger &log;
|
||||||
RNG &rng;
|
RNG &rng;
|
||||||
std::unique_ptr<character> player;
|
std::unique_ptr<character> player;
|
||||||
public:
|
public:
|
||||||
game(const feature enabled_features,
|
game(const feature enabled_features,
|
||||||
input &new_in,
|
input &new_in,
|
||||||
display &new_out,
|
display &new_out,
|
||||||
logger &new_log,
|
logger &new_log,
|
||||||
RNG &new_rng);
|
RNG &new_rng);
|
||||||
game_status run();
|
game_status run();
|
||||||
private:
|
private:
|
||||||
int getcmd() const;
|
int getcmd() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,36 +3,36 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
goblin::goblin(RNG &rng, const position_list &available_positions):
|
goblin::goblin(RNG &rng, const position_list &available_positions):
|
||||||
character{rng, race::rshade} {
|
character{rng, race::rshade} {
|
||||||
pos = available_positions[rng.rand_under(available_positions.size())];
|
pos = available_positions[rng.rand_under(available_positions.size())];
|
||||||
gold = 0;
|
gold = 0;
|
||||||
hostile = true;
|
hostile = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
result goblin::attack(const direction dir, character_list &chlist) {
|
result goblin::attack(const direction dir, character_list &chlist) {
|
||||||
position tmp{pos + MOVE[dir]};
|
position tmp{pos + MOVE[dir]};
|
||||||
|
|
||||||
for (auto &ch : chlist)
|
for (auto &ch : chlist)
|
||||||
if (tmp == ch.get_position()) {
|
if (tmp == ch.get_position()) {
|
||||||
auto res = ch.get_hit(race, ATK, base_hit_rate);
|
auto res = ch.get_hit(race, ATK, base_hit_rate);
|
||||||
|
|
||||||
if (res == result::died) {
|
if (res == result::died) {
|
||||||
gold += GAIN_GOLD;
|
gold += GAIN_GOLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result::fine;
|
return result::fine;
|
||||||
}
|
}
|
||||||
|
|
||||||
result goblin::get_hit(const enum race &race, const int atk,
|
result goblin::get_hit(const enum race &race, const int atk,
|
||||||
const float hitrate) {
|
const float hitrate) {
|
||||||
if (rng.rand_num() <= hitrate * (float)RAND_MAX)
|
if (rng.rand_num() <= hitrate * (float)RAND_MAX)
|
||||||
HP = std::max(HP - calc_dmg(atk, DEF), 0);
|
HP = std::max(HP - calc_dmg(atk, DEF), 0);
|
||||||
|
|
||||||
if (HP == 0)
|
if (HP == 0)
|
||||||
return result::died;
|
return result::died;
|
||||||
|
|
||||||
return result::hit;
|
return result::hit;
|
||||||
}
|
}
|
||||||
|
12
src/goblin.h
12
src/goblin.h
@ -6,12 +6,12 @@ const int GAIN_GOLD = 5;
|
|||||||
|
|
||||||
class goblin final: public character {
|
class goblin final: public character {
|
||||||
public:
|
public:
|
||||||
goblin(RNG &rng,
|
goblin(RNG &rng,
|
||||||
const position_list &available_positions);
|
const position_list &available_positions);
|
||||||
virtual result attack(const direction dir,
|
virtual result attack(const direction dir,
|
||||||
character_list &chlist) override;
|
character_list &chlist) override;
|
||||||
virtual result get_hit(const enum race &race, const int atk,
|
virtual result get_hit(const enum race &race, const int atk,
|
||||||
const float hit_rate) override;
|
const float hit_rate) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
11
src/input.cc
11
src/input.cc
@ -1,15 +1,14 @@
|
|||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
|
||||||
|
|
||||||
const char *COMMANDS[] = {
|
const char *COMMANDS[] = {
|
||||||
"no", "so", "ea", "we", "ne", "nw", "se", "sw"
|
"no", "so", "ea", "we", "ne", "nw", "se", "sw"
|
||||||
};
|
};
|
||||||
const int COMMANDS_CNT = 8;
|
const int COMMANDS_CNT = 8;
|
||||||
|
|
||||||
game_command get_direction(std::string &str) {
|
game_command get_direction(std::string &str) {
|
||||||
for (int i = 0; i < COMMANDS_CNT; ++i)
|
for (int i = 0; i < COMMANDS_CNT; ++i)
|
||||||
if (str == COMMANDS[i])
|
if (str == COMMANDS[i])
|
||||||
return (game_command)i;
|
return (game_command)i;
|
||||||
|
|
||||||
return game_command_panic;
|
return game_command_panic;
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
class input {
|
class input {
|
||||||
public:
|
public:
|
||||||
virtual ~input() = default;
|
virtual ~input() = default;
|
||||||
virtual game_command get_command() = 0;
|
virtual game_command get_command() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
game_command get_direction(std::string &str);
|
game_command get_direction(std::string &str);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
logger::logger(std::ofstream &&new_out):
|
logger::logger(std::ofstream &&new_out):
|
||||||
out{std::move(new_out)} {}
|
out{std::move(new_out)} {}
|
||||||
|
|
||||||
void logger::render() {
|
void logger::render() {
|
||||||
|
|
||||||
|
24
src/log.h
24
src/log.h
@ -9,20 +9,20 @@
|
|||||||
|
|
||||||
class logger final {
|
class logger final {
|
||||||
private:
|
private:
|
||||||
std::ofstream out;
|
std::ofstream out;
|
||||||
std::vector<char> contents;
|
std::vector<char> contents;
|
||||||
public:
|
public:
|
||||||
logger(std::ofstream &&new_out);
|
logger(std::ofstream &&new_out);
|
||||||
|
|
||||||
// called once every turn
|
// called once every turn
|
||||||
void render();
|
void render();
|
||||||
void print_char(const position &pos, const char ch);
|
void print_char(const position &pos, const char ch);
|
||||||
void print_str(const position &pos, const std::string &str);
|
void print_str(const position &pos, const std::string &str);
|
||||||
void print_turn(const unsigned turn);
|
void print_turn(const unsigned turn);
|
||||||
void print_player(const character &player);
|
void print_player(const character &player);
|
||||||
void print_chlist(const character_list &chlist);
|
void print_chlist(const character_list &chlist);
|
||||||
void print_gold(const gold_list &gold_piles);
|
void print_gold(const gold_list &gold_piles);
|
||||||
void print_potions(const potion_list &potions);
|
void print_potions(const potion_list &potions);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
31
src/main.cc
31
src/main.cc
@ -2,27 +2,26 @@
|
|||||||
#include "arguments.h"
|
#include "arguments.h"
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
std::unique_ptr<cursor> curse;
|
std::unique_ptr<cursor> curse;
|
||||||
std::unique_ptr<input> in;
|
std::unique_ptr<input> in;
|
||||||
std::unique_ptr<display> out;
|
std::unique_ptr<display> out;
|
||||||
std::unique_ptr<logger> log;
|
std::unique_ptr<logger> log;
|
||||||
std::unique_ptr<RNG> rng;
|
std::unique_ptr<RNG> rng;
|
||||||
|
|
||||||
|
feature enabled_features = proc_args(argc, argv,
|
||||||
|
curse, in, out, log, rng);
|
||||||
|
|
||||||
feature enabled_features = proc_args(argc, argv,
|
if (enabled_features &
|
||||||
curse, in, out, log, rng);
|
|
||||||
|
|
||||||
if (enabled_features &
|
|
||||||
(FEATURE_PANIC | FEATURE_PANIC_FILE |
|
(FEATURE_PANIC | FEATURE_PANIC_FILE |
|
||||||
FEATURE_CONFLICT | FEATURE_PANIC_SEED)) {
|
FEATURE_CONFLICT | FEATURE_PANIC_SEED)) {
|
||||||
panic_args(enabled_features);
|
panic_args(enabled_features);
|
||||||
return RETURN_PANICKED;
|
return RETURN_PANICKED;
|
||||||
}
|
}
|
||||||
|
|
||||||
game game_proc(enabled_features, *in, *out, *log, *rng);
|
game game_proc(enabled_features, *in, *out, *log, *rng);
|
||||||
|
|
||||||
while (game_proc.run() != game_status::terminated)
|
while (game_proc.run() != game_status::terminated)
|
||||||
out->render();
|
out->render();
|
||||||
|
|
||||||
return RETURN_FINE;
|
return RETURN_FINE;
|
||||||
}
|
}
|
||||||
|
56
src/map.cc
56
src/map.cc
@ -6,63 +6,63 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
game_map::game_map(int lvl) {
|
game_map::game_map(int lvl) {
|
||||||
level = lvl;
|
level = lvl;
|
||||||
// TODO: randomly generate a map
|
// TODO: randomly generate a map
|
||||||
}
|
}
|
||||||
|
|
||||||
game_map::game_map(const std::string &map_data, int lvl) {
|
game_map::game_map(const std::string &map_data, int lvl) {
|
||||||
level = lvl;
|
level = lvl;
|
||||||
std::istringstream iss{map_data};
|
std::istringstream iss{map_data};
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
|
|
||||||
for (int i = 0; i < MAP_HEIGHT; ++i) {
|
for (int i = 0; i < MAP_HEIGHT; ++i) {
|
||||||
getline(iss, line);
|
getline(iss, line);
|
||||||
map[i] = line;
|
map[i] = line;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
game_map::~game_map() {}
|
game_map::~game_map() {}
|
||||||
|
|
||||||
int game_map::get_level() const {
|
int game_map::get_level() const {
|
||||||
return this->level;
|
return this->level;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<position> game_map::get_available_positions() const {
|
std::vector<position> game_map::get_available_positions() const {
|
||||||
std::vector<position> result;
|
std::vector<position> result;
|
||||||
|
|
||||||
for (int line = 0; line < MAP_HEIGHT; ++line)
|
for (int line = 0; line < MAP_HEIGHT; ++line)
|
||||||
for (int x = 0; x < MAP_WIDTH; ++x)
|
for (int x = 0; x < MAP_WIDTH; ++x)
|
||||||
if (map[line][x] == '.' ||
|
if (map[line][x] == '.' ||
|
||||||
map[line][x] == '#' ||
|
map[line][x] == '#' ||
|
||||||
map[line][x] == '+')
|
map[line][x] == '+')
|
||||||
result.push_back(position{x, line});
|
result.push_back(position{x, line});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void game_map::print() const {
|
void game_map::print() const {
|
||||||
|
|
||||||
// TODO: write a print function using ncurses
|
// TODO: write a print function using ncurses
|
||||||
}
|
}
|
||||||
|
|
||||||
void game_map::print(display &display) const {
|
void game_map::print(display &display) const {
|
||||||
for (int i = 0; i < MAP_HEIGHT; ++i)
|
for (int i = 0; i < MAP_HEIGHT; ++i)
|
||||||
display.print_str(position{0, i}, map[i]);
|
display.print_str(position{0, i}, map[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void game_map::apply_potion(character *who, const stat_name statn,
|
void game_map::apply_potion(character *who, const stat_name statn,
|
||||||
const int amount) {
|
const int amount) {
|
||||||
effects.push_back(effect{who, statn, amount});
|
effects.push_back(effect{who, statn, amount});
|
||||||
who->apply_buff(statn, amount);
|
who->apply_buff(statn, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void game_map::enter_level(character *who) {
|
void game_map::enter_level(character *who) {
|
||||||
for (auto eff : effects)
|
for (auto eff : effects)
|
||||||
if (eff.who == who)
|
if (eff.who == who)
|
||||||
who->apply_buff(eff.statn, eff.amount);
|
who->apply_buff(eff.statn, eff.amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void game_map::leave_level(character *who) {
|
void game_map::leave_level(character *who) {
|
||||||
who->set_ATK(STARTING_ATK[who->get_race()]);
|
who->set_ATK(STARTING_ATK[who->get_race()]);
|
||||||
who->set_DEF(STARTING_DEF[who->get_race()]);
|
who->set_DEF(STARTING_DEF[who->get_race()]);
|
||||||
}
|
}
|
||||||
|
56
src/map.h
56
src/map.h
@ -15,46 +15,46 @@
|
|||||||
|
|
||||||
class game_map final {
|
class game_map final {
|
||||||
public:
|
public:
|
||||||
game_map(int lvl = 0); // randomly generate one
|
game_map(int lvl = 0); // randomly generate one
|
||||||
// initialize using stored data
|
// initialize using stored data
|
||||||
game_map(const std::string &map_data, int lvl);
|
game_map(const std::string &map_data, int lvl);
|
||||||
~game_map(); // placeholder
|
~game_map(); // placeholder
|
||||||
|
|
||||||
int get_level() const;
|
int get_level() const;
|
||||||
|
|
||||||
position_list get_available_positions() const;
|
position_list get_available_positions() const;
|
||||||
|
|
||||||
// IMPORTANT: always print a map before anything else
|
// IMPORTANT: always print a map before anything else
|
||||||
|
|
||||||
// prints using ncurses
|
// prints using ncurses
|
||||||
void print() const;
|
void print() const;
|
||||||
|
|
||||||
// prints to a string
|
// prints to a string
|
||||||
void print(display &display) const;
|
void print(display &display) const;
|
||||||
|
|
||||||
// This is implemented this way to do two things:
|
// This is implemented this way to do two things:
|
||||||
// 1. avoid directly accessing heap memory (bonus points)
|
// 1. avoid directly accessing heap memory (bonus points)
|
||||||
// 2. make a level revisitable
|
// 2. make a level revisitable
|
||||||
void apply_potion(character *who, const stat_name statn, const int amount);
|
void apply_potion(character *who, const stat_name statn, const int amount);
|
||||||
|
|
||||||
// just in case you want to retain the potion effects
|
// just in case you want to retain the potion effects
|
||||||
void enter_level(character *who);
|
void enter_level(character *who);
|
||||||
void leave_level(character *who);
|
void leave_level(character *who);
|
||||||
public:
|
public:
|
||||||
struct effect {
|
struct effect {
|
||||||
character *who;
|
character *who;
|
||||||
stat_name statn;
|
stat_name statn;
|
||||||
int amount;
|
int amount;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string map[MAP_HEIGHT];
|
std::string map[MAP_HEIGHT];
|
||||||
int level;
|
int level;
|
||||||
|
|
||||||
// use this to remember every applied potion
|
// use this to remember every applied potion
|
||||||
std::vector<effect> effects;
|
std::vector<effect> effects;
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::string default_map =
|
const std::string default_map =
|
||||||
"|-----------------------------------------------------------------------------|\n| |\n| |--------------------------| |-----------------------| |\n| |..........................| |.......................| |\n| |..........................+########+.......................|-------| |\n| |..........................| # |...............................|--| |\n| |..........................| # |..................................|--| |\n| |----------+---------------| # |----+----------------|...............| |\n| # ############# |...............| |\n| # # |-----+------| |...............| |\n| # # |............| |...............| |\n| ################### |............| ######+...............| |\n| # # |............| # |...............| |\n| # # |-----+------| # |--------+------| |\n| |---------+-----------| # # # # |\n| |.....................| # # # |----+------| |\n| |.....................| ######################## |...........| |\n| |.....................| # # |...........| |\n| |.....................| # |------+--------------------|...........| |\n| |.....................| # |.......................................| |\n| |.....................+##########+.......................................| |\n| |.....................| |.......................................| |\n| |---------------------| |---------------------------------------| |\n| |\n|-----------------------------------------------------------------------------|";
|
"|-----------------------------------------------------------------------------|\n| |\n| |--------------------------| |-----------------------| |\n| |..........................| |.......................| |\n| |..........................+########+.......................|-------| |\n| |..........................| # |...............................|--| |\n| |..........................| # |..................................|--| |\n| |----------+---------------| # |----+----------------|...............| |\n| # ############# |...............| |\n| # # |-----+------| |...............| |\n| # # |............| |...............| |\n| ################### |............| ######+...............| |\n| # # |............| # |...............| |\n| # # |-----+------| # |--------+------| |\n| |---------+-----------| # # # # |\n| |.....................| # # # |----+------| |\n| |.....................| ######################## |...........| |\n| |.....................| # # |...........| |\n| |.....................| # |------+--------------------|...........| |\n| |.....................| # |.......................................| |\n| |.....................+##########+.......................................| |\n| |.....................| |.......................................| |\n| |---------------------| |---------------------------------------| |\n| |\n|-----------------------------------------------------------------------------|";
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,20 +3,20 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
poison_health::poison_health():
|
poison_health::poison_health():
|
||||||
potion{potion_type::poison_health, 1} {}
|
potion{potion_type::poison_health, 1} {}
|
||||||
|
|
||||||
void poison_health::apply(enum race &race, int &HP, int &ATK, int &DEF,
|
void poison_health::apply(enum race &race, int &HP, int &ATK, int &DEF,
|
||||||
float &base_hit_rate) {
|
float &base_hit_rate) {
|
||||||
if (remaining_duration > 0) {
|
if (remaining_duration > 0) {
|
||||||
if (race == rdrow)
|
if (race == rdrow)
|
||||||
HP = std::max(HP - 7, 0);
|
HP = std::max(HP - 7, 0);
|
||||||
else
|
else
|
||||||
HP = std::max(HP - 5, 0);
|
HP = std::max(HP - 5, 0);
|
||||||
|
|
||||||
--remaining_duration;
|
--remaining_duration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int poison_health::get_priority() const {
|
int poison_health::get_priority() const {
|
||||||
return CALC_ADD_BASE;
|
return CALC_ADD_BASE;
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
class poison_health final: public potion {
|
class poison_health final: public potion {
|
||||||
public:
|
public:
|
||||||
poison_health();
|
poison_health();
|
||||||
void apply(enum race &race, int &HP, int &ATK, int &DEF,
|
void apply(enum race &race, int &HP, int &ATK, int &DEF,
|
||||||
float &base_hit_rate) override;
|
float &base_hit_rate) override;
|
||||||
int get_priority() const override;
|
int get_priority() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -5,41 +5,41 @@ position::position(): x{0}, y{0} {}
|
|||||||
position::position(int nx, int ny): x{nx}, y{ny} {}
|
position::position(int nx, int ny): x{nx}, y{ny} {}
|
||||||
|
|
||||||
position position::operator+(const position &other) const {
|
position position::operator+(const position &other) const {
|
||||||
position result{x + other.x, y + other.y};
|
position result{x + other.x, y + other.y};
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
position &position::operator=(const position &other) {
|
position &position::operator=(const position &other) {
|
||||||
x = other.x;
|
x = other.x;
|
||||||
y = other.y;
|
y = other.y;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
position &position::operator+=(const position &other) {
|
position &position::operator+=(const position &other) {
|
||||||
return *this = *this + other;
|
return *this = *this + other;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool position::operator==(const position &other) const {
|
bool position::operator==(const position &other) const {
|
||||||
return x == other.x && y == other.y;
|
return x == other.x && y == other.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool position::operator!=(const position &other) const {
|
bool position::operator!=(const position &other) const {
|
||||||
return x != other.x || y != other.y;
|
return x != other.x || y != other.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool position::operator<(const position &other) const {
|
bool position::operator<(const position &other) const {
|
||||||
return y < other.y || x < other.x;
|
return y < other.y || x < other.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
size_t find(const std::vector<position> &sorted_list,
|
size_t find(const std::vector<position> &sorted_list,
|
||||||
const position &target) {
|
const position &target) {
|
||||||
// TODO: implement binary searching
|
// TODO: implement binary searching
|
||||||
|
|
||||||
for (size_t i = 0; i < sorted_list.size(); ++i)
|
for (size_t i = 0; i < sorted_list.size(); ++i)
|
||||||
if (sorted_list[i] == target)
|
if (sorted_list[i] == target)
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
return sorted_list.size();
|
return sorted_list.size();
|
||||||
}
|
}
|
||||||
|
@ -9,18 +9,18 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
typedef struct position {
|
typedef struct position {
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
position();
|
position();
|
||||||
position(int nx, int ny);
|
position(int nx, int ny);
|
||||||
|
|
||||||
position operator+(const position &other) const;
|
position operator+(const position &other) const;
|
||||||
position &operator=(const position &other);
|
position &operator=(const position &other);
|
||||||
position &operator+=(const position &other);
|
position &operator+=(const position &other);
|
||||||
bool operator==(const position &other) const;
|
bool operator==(const position &other) const;
|
||||||
bool operator!=(const position &other) const;
|
bool operator!=(const position &other) const;
|
||||||
bool operator<(const position &other) const;
|
bool operator<(const position &other) const;
|
||||||
} position;
|
} position;
|
||||||
|
|
||||||
std::size_t find(const std::vector<position> &sorted_list,
|
std::size_t find(const std::vector<position> &sorted_list,
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#include "potion.h"
|
#include "potion.h"
|
||||||
|
|
||||||
potion::potion(const potion_type type, const int duration):
|
potion::potion(const potion_type type, const int duration):
|
||||||
type{type}, remaining_duration{duration} {}
|
type{type}, remaining_duration{duration} {}
|
||||||
|
|
||||||
potion_type potion::get_type() const {
|
potion_type potion::get_type() const {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
int potion::get_duration() const {
|
int potion::get_duration() const {
|
||||||
return remaining_duration;
|
return remaining_duration;
|
||||||
}
|
}
|
||||||
|
26
src/potion.h
26
src/potion.h
@ -9,20 +9,20 @@
|
|||||||
|
|
||||||
class potion {
|
class potion {
|
||||||
protected:
|
protected:
|
||||||
// Use -1 to denote that the effect will last until leaving the level
|
// Use -1 to denote that the effect will last until leaving the level
|
||||||
// Otherwise, use a positive number
|
// Otherwise, use a positive number
|
||||||
// Single use potions have a starting duration of 1
|
// Single use potions have a starting duration of 1
|
||||||
const potion_type type;
|
const potion_type type;
|
||||||
int remaining_duration;
|
int remaining_duration;
|
||||||
public:
|
public:
|
||||||
potion(const potion_type type, const int duration);
|
potion(const potion_type type, const int duration);
|
||||||
// apply decrements remaining_duration if it's positive, and
|
// apply decrements remaining_duration if it's positive, and
|
||||||
// won't do anything if it's non-negative
|
// won't do anything if it's non-negative
|
||||||
virtual void apply(enum race &race, int &HP, int &ATK, int &DEF,
|
virtual void apply(enum race &race, int &HP, int &ATK, int &DEF,
|
||||||
float &base_hit_rate) = 0;
|
float &base_hit_rate) = 0;
|
||||||
virtual int get_priority() const = 0;
|
virtual int get_priority() const = 0;
|
||||||
potion_type get_type() const;
|
potion_type get_type() const;
|
||||||
int get_duration() const;
|
int get_duration() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<potion> potion_list;
|
typedef std::vector<potion> potion_list;
|
||||||
|
@ -3,20 +3,20 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
restore_health::restore_health():
|
restore_health::restore_health():
|
||||||
potion{potion_type::restore_health, 1} {}
|
potion{potion_type::restore_health, 1} {}
|
||||||
|
|
||||||
void restore_health::apply(enum race &race, int &HP, int &ATK, int &DEF,
|
void restore_health::apply(enum race &race, int &HP, int &ATK, int &DEF,
|
||||||
float &base_hit_rate) {
|
float &base_hit_rate) {
|
||||||
if (remaining_duration > 0) {
|
if (remaining_duration > 0) {
|
||||||
if (race == rdrow)
|
if (race == rdrow)
|
||||||
HP = std::min(HP + 7, MAX_HP[race]);
|
HP = std::min(HP + 7, MAX_HP[race]);
|
||||||
else
|
else
|
||||||
HP = std::min(HP + 5, MAX_HP[race]);
|
HP = std::min(HP + 5, MAX_HP[race]);
|
||||||
|
|
||||||
--remaining_duration;
|
--remaining_duration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int restore_health::get_priority() const {
|
int restore_health::get_priority() const {
|
||||||
return CALC_ADD_BASE;
|
return CALC_ADD_BASE;
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
class restore_health final: public potion {
|
class restore_health final: public potion {
|
||||||
public:
|
public:
|
||||||
restore_health();
|
restore_health();
|
||||||
void apply(enum race &race, int &HP, int &ATK, int &DEF,
|
void apply(enum race &race, int &HP, int &ATK, int &DEF,
|
||||||
float &base_hit_rate) override;
|
float &base_hit_rate) override;
|
||||||
int get_priority() const override;
|
int get_priority() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
24
src/rng.cc
24
src/rng.cc
@ -1,43 +1,43 @@
|
|||||||
#include "rng.h"
|
#include "rng.h"
|
||||||
|
|
||||||
RNG::RNG(): init_seed(time(0)), curr_rand_num(0) {
|
RNG::RNG(): init_seed(time(0)), curr_rand_num(0) {
|
||||||
srand(init_seed);
|
srand(init_seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
RNG::RNG(const unsigned int seed): init_seed(seed), curr_rand_num(0) {
|
RNG::RNG(const unsigned int seed): init_seed(seed), curr_rand_num(0) {
|
||||||
srand(init_seed);
|
srand(init_seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
int RNG::rand_num() {
|
int RNG::rand_num() {
|
||||||
return curr_rand_num = rand();
|
return curr_rand_num = rand();
|
||||||
}
|
}
|
||||||
|
|
||||||
int RNG::rand_between(const int lower_bound, const int upper_bound) {
|
int RNG::rand_between(const int lower_bound, const int upper_bound) {
|
||||||
curr_rand_num = rand();
|
curr_rand_num = rand();
|
||||||
|
|
||||||
return lower_bound + (curr_rand_num % (upper_bound - lower_bound));
|
return lower_bound + (curr_rand_num % (upper_bound - lower_bound));
|
||||||
}
|
}
|
||||||
|
|
||||||
int RNG::rand_under(const int upper_bound) {
|
int RNG::rand_under(const int upper_bound) {
|
||||||
curr_rand_num = rand();
|
curr_rand_num = rand();
|
||||||
|
|
||||||
return curr_rand_num % upper_bound;
|
return curr_rand_num % upper_bound;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int RNG::get_init_seed() const {
|
unsigned int RNG::get_init_seed() const {
|
||||||
return init_seed;
|
return init_seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RNG::get_curr_rand_num() const {
|
int RNG::get_curr_rand_num() const {
|
||||||
return curr_rand_num;
|
return curr_rand_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RNG::trial(fraction &psuccess) {
|
bool RNG::trial(fraction &psuccess) {
|
||||||
return (rand() % psuccess.denominator) < psuccess.numerator;
|
return (rand() % psuccess.denominator) < psuccess.numerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> T &RNG::get_rand_in_vector(const std::vector<T> &vec) {
|
template<class T> T &RNG::get_rand_in_vector(const std::vector<T> &vec) {
|
||||||
curr_rand_num = rand();
|
curr_rand_num = rand();
|
||||||
|
|
||||||
return vec[curr_rand_num % vec.size()];
|
return vec[curr_rand_num % vec.size()];
|
||||||
}
|
}
|
||||||
|
26
src/rng.h
26
src/rng.h
@ -11,24 +11,24 @@
|
|||||||
// IMPORTANT: pass all RNG objects as references
|
// IMPORTANT: pass all RNG objects as references
|
||||||
class RNG final {
|
class RNG final {
|
||||||
private:
|
private:
|
||||||
const unsigned int init_seed;
|
const unsigned int init_seed;
|
||||||
int curr_rand_num;
|
int curr_rand_num;
|
||||||
public:
|
public:
|
||||||
RNG(); // use time(0) as the seed
|
RNG(); // use time(0) as the seed
|
||||||
RNG(const unsigned int seed); // use a seed
|
RNG(const unsigned int seed); // use a seed
|
||||||
|
|
||||||
int rand_num(); // returns a random number between 0 and RAND_MAX
|
int rand_num(); // returns a random number between 0 and RAND_MAX
|
||||||
|
|
||||||
// IMPORTANT: all upper bounds are not included, all lower bounds are
|
// IMPORTANT: all upper bounds are not included, all lower bounds are
|
||||||
int rand_between(const int lower_bound, const int upper_bound);
|
int rand_between(const int lower_bound, const int upper_bound);
|
||||||
// returns a random number between 0 and upper_bound
|
// returns a random number between 0 and upper_bound
|
||||||
int rand_under(const int upper_bound);
|
int rand_under(const int upper_bound);
|
||||||
unsigned int get_init_seed() const;
|
unsigned int get_init_seed() const;
|
||||||
int get_curr_rand_num() const;
|
int get_curr_rand_num() const;
|
||||||
|
|
||||||
bool trial(fraction &psuccess);
|
bool trial(fraction &psuccess);
|
||||||
|
|
||||||
template<class T> T &get_rand_in_vector(const std::vector<T> &vec);
|
template<class T> T &get_rand_in_vector(const std::vector<T> &vec);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
#ifndef __ROOM_H__
|
#ifndef __ROOM_H__
|
||||||
#define __ROOM_H__
|
#define __ROOM_H__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
31
src/shade.cc
31
src/shade.cc
@ -4,31 +4,30 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
shade::shade(RNG &rng, const position_list &available_positions):
|
shade::shade(RNG &rng, const position_list &available_positions):
|
||||||
character{rng, race::rshade} {
|
character{rng, race::rshade} {
|
||||||
pos = available_positions[rng.rand_under(available_positions.size())];
|
pos = available_positions[rng.rand_under(available_positions.size())];
|
||||||
gold = 0;
|
gold = 0;
|
||||||
hostile = true;
|
hostile = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
result shade::attack(const direction dir, character_list &chlist) {
|
result shade::attack(const direction dir, character_list &chlist) {
|
||||||
position tmp{pos + MOVE[dir]};
|
position tmp{pos + MOVE[dir]};
|
||||||
|
|
||||||
for (auto &ch : chlist)
|
for (auto &ch : chlist)
|
||||||
if (tmp == ch.get_position()) {
|
if (tmp == ch.get_position()) {
|
||||||
return ch.get_hit(race, ATK, base_hit_rate);
|
return ch.get_hit(race, ATK, base_hit_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result::fine;
|
return result::fine;
|
||||||
}
|
}
|
||||||
|
|
||||||
result shade::get_hit(const enum race &race, const int atk,
|
result shade::get_hit(const enum race &race, const int atk,
|
||||||
const float hitrate) {
|
const float hitrate) {
|
||||||
if (rng.rand_num() <= hitrate * (float)RAND_MAX) // This is a hit!
|
if (rng.rand_num() <= hitrate * (float)RAND_MAX) // This is a hit!
|
||||||
HP = std::max(HP - calc_dmg(atk, DEF), 0);
|
HP = std::max(HP - calc_dmg(atk, DEF), 0);
|
||||||
|
|
||||||
if (HP == 0)
|
if (HP == 0)
|
||||||
return result::died;
|
return result::died;
|
||||||
|
|
||||||
return result::hit;
|
return result::hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
src/shade.h
12
src/shade.h
@ -5,12 +5,12 @@
|
|||||||
|
|
||||||
class shade final: public character {
|
class shade final: public character {
|
||||||
public:
|
public:
|
||||||
shade(RNG &rng, const position_list
|
shade(RNG &rng, const position_list
|
||||||
&available_positions); // spawn at a random place
|
&available_positions); // spawn at a random place
|
||||||
virtual result attack(const direction dir,
|
virtual result attack(const direction dir,
|
||||||
character_list &chlist) override;
|
character_list &chlist) override;
|
||||||
virtual result get_hit(const enum race &race, const int atk,
|
virtual result get_hit(const enum race &race, const int atk,
|
||||||
const float hit_rate) override;
|
const float hit_rate) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,36 +3,36 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
vampire::vampire(RNG &rng, const position_list &available_positions):
|
vampire::vampire(RNG &rng, const position_list &available_positions):
|
||||||
character{rng, race::rvampire} {
|
character{rng, race::rvampire} {
|
||||||
pos = available_positions[rng.rand_under(available_positions.size())];
|
pos = available_positions[rng.rand_under(available_positions.size())];
|
||||||
gold = 0;
|
gold = 0;
|
||||||
hostile = true;
|
hostile = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
result vampire::attack(const direction dir, character_list &chlist) {
|
result vampire::attack(const direction dir, character_list &chlist) {
|
||||||
position tmp{pos + MOVE[dir]};
|
position tmp{pos + MOVE[dir]};
|
||||||
|
|
||||||
for (auto &ch : chlist)
|
for (auto &ch : chlist)
|
||||||
if (tmp == ch.get_position()) {
|
if (tmp == ch.get_position()) {
|
||||||
auto res = ch.get_hit(race, ATK, base_hit_rate);
|
auto res = ch.get_hit(race, ATK, base_hit_rate);
|
||||||
|
|
||||||
if (res != result::miss) {
|
if (res != result::miss) {
|
||||||
HP += GAIN_HP;
|
HP += GAIN_HP;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result::fine;
|
return result::fine;
|
||||||
}
|
}
|
||||||
|
|
||||||
result vampire::get_hit(const enum race &race, const int atk,
|
result vampire::get_hit(const enum race &race, const int atk,
|
||||||
const float hitrate) {
|
const float hitrate) {
|
||||||
if (rng.rand_num() <= hitrate * (float)RAND_MAX)
|
if (rng.rand_num() <= hitrate * (float)RAND_MAX)
|
||||||
HP = std::max(HP - calc_dmg(atk, DEF), 0);
|
HP = std::max(HP - calc_dmg(atk, DEF), 0);
|
||||||
|
|
||||||
if (HP == 0)
|
if (HP == 0)
|
||||||
return result::died;
|
return result::died;
|
||||||
|
|
||||||
return result::hit;
|
return result::hit;
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,12 @@ const int GAIN_HP = 5;
|
|||||||
|
|
||||||
class vampire final: public character {
|
class vampire final: public character {
|
||||||
public:
|
public:
|
||||||
vampire(RNG &rng,
|
vampire(RNG &rng,
|
||||||
const position_list &available_positions);
|
const position_list &available_positions);
|
||||||
virtual result attack(const direction dir,
|
virtual result attack(const direction dir,
|
||||||
character_list &chlist) override;
|
character_list &chlist) override;
|
||||||
virtual result get_hit(const enum race &race, const int atk,
|
virtual result get_hit(const enum race &race, const int atk,
|
||||||
const float hit_rate) override;
|
const float hit_rate) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -6,21 +6,20 @@ const int WOUND_ATK = 5;
|
|||||||
const int WOUND_ATK_DROW = 7;
|
const int WOUND_ATK_DROW = 7;
|
||||||
|
|
||||||
wound_atk::wound_atk():
|
wound_atk::wound_atk():
|
||||||
potion{potion_type::wound_atk, -1} {}
|
potion{potion_type::wound_atk, -1} {}
|
||||||
|
|
||||||
void wound_atk::apply(enum race &race, int &HP, int &ATK, int &DEF,
|
void wound_atk::apply(enum race &race, int &HP, int &ATK, int &DEF,
|
||||||
float &base_hit_rate) {
|
float &base_hit_rate) {
|
||||||
if (remaining_duration > 0) {
|
if (remaining_duration > 0) {
|
||||||
if (race == rdrow)
|
if (race == rdrow)
|
||||||
ATK = std::max(ATK - WOUND_ATK_DROW, 0);
|
ATK = std::max(ATK - WOUND_ATK_DROW, 0);
|
||||||
else
|
else
|
||||||
ATK = std::max(ATK - WOUND_ATK, 0);
|
ATK = std::max(ATK - WOUND_ATK, 0);
|
||||||
|
|
||||||
--remaining_duration;
|
--remaining_duration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int wound_atk::get_priority() const {
|
int wound_atk::get_priority() const {
|
||||||
return CALC_ADD_BASE;
|
return CALC_ADD_BASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
class wound_atk final: public potion {
|
class wound_atk final: public potion {
|
||||||
public:
|
public:
|
||||||
wound_atk();
|
wound_atk();
|
||||||
void apply(enum race &race, int &HP, int &ATK, int &DEF,
|
void apply(enum race &race, int &HP, int &ATK, int &DEF,
|
||||||
float &base_hit_rate) override;
|
float &base_hit_rate) override;
|
||||||
int get_priority() const override;
|
int get_priority() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -6,20 +6,20 @@ const int WOUND_DEF = 5;
|
|||||||
const int WOUND_DEF_DROW = 7;
|
const int WOUND_DEF_DROW = 7;
|
||||||
|
|
||||||
wound_def::wound_def():
|
wound_def::wound_def():
|
||||||
potion{potion_type::wound_def, -1} {}
|
potion{potion_type::wound_def, -1} {}
|
||||||
|
|
||||||
void wound_def::apply(enum race &race, int &HP, int &ATK, int &DEF,
|
void wound_def::apply(enum race &race, int &HP, int &ATK, int &DEF,
|
||||||
float &base_hit_rate) {
|
float &base_hit_rate) {
|
||||||
if (remaining_duration > 0) {
|
if (remaining_duration > 0) {
|
||||||
if (race == rdrow)
|
if (race == rdrow)
|
||||||
DEF = std::max(DEF - WOUND_DEF_DROW, 0);
|
DEF = std::max(DEF - WOUND_DEF_DROW, 0);
|
||||||
else
|
else
|
||||||
DEF = std::max(DEF - WOUND_DEF, 0);
|
DEF = std::max(DEF - WOUND_DEF, 0);
|
||||||
|
|
||||||
--remaining_duration;
|
--remaining_duration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int wound_def::get_priority() const {
|
int wound_def::get_priority() const {
|
||||||
return CALC_ADD_BASE;
|
return CALC_ADD_BASE;
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
class wound_def final: public potion {
|
class wound_def final: public potion {
|
||||||
public:
|
public:
|
||||||
wound_def();
|
wound_def();
|
||||||
void apply(enum race &race, int &HP, int &ATK, int &DEF,
|
void apply(enum race &race, int &HP, int &ATK, int &DEF,
|
||||||
float &base_hit_rate) override;
|
float &base_hit_rate) override;
|
||||||
int get_priority() const override;
|
int get_priority() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user