added: cmdline args handling

This commit is contained in:
2024-07-06 01:39:39 -04:00
parent 116d068765
commit eb773405a6
11 changed files with 206 additions and 21 deletions

View File

@ -1,2 +1,159 @@
#include "arguments.h"
#include <iostream>
#include <utility>
#include <fstream>
#include <string>
#include "file_input.h"
#include "file_output.h"
#include "console_input.h"
#include "console_output.h"
#include "curses_input.h"
#include "curses_output.h"
feature proc_args(int argc, char **argv,
std::unique_ptr<cursor> &curse,
std::unique_ptr<input> &in,
std::unique_ptr<display> &out,
std::unique_ptr<logger> &log) {
feature result = 0;
std::string str;
std::string fn_fin;
std::string fn_fout;
std::string fn_lout;
std::string fn_save;
std::string seed;
for (int i = 1; i < argc; ++i) {
str = argv[i];
if (str == "-n") {
if (result & (FEATURE_IN_FILE | FEATURE_OUT_FILE))
return FEATURE_CONFLICT | i;
result |= FEATURE_NCURSES;
} else if (str == "-r") {
result |= FEATURE_RAND_MAP;
} else if (str == "-m") {
result |= FEATURE_MENU;
} else if (str == "-c") {
result |= FEATURE_ENEMIES_CHASE;
} else if (str == "-i") {
result |= FEATURE_INVENTORY;
} else if (str == "-t") {
result |= FEATURE_THROW;
} else if (str == "-R") {
result |= FEATURE_REVISIT;
} else if (str == "-s") {
++i;
str = argv[i];
if (!seed.empty() && seed != str)
return FEATURE_CONFLICT | i;
seed = str;
result |= FEATURE_SEED;
} else if (str == "-L") {
++i;
str = argv[i];
if (!fn_lout.empty() && fn_lout != str)
return FEATURE_CONFLICT | i;
fn_lout = str;
result |= FEATURE_LOG;
} else if (str == "-I") {
++i;
str = argv[i];
if (!fn_fin.empty() && fn_fin != str)
return FEATURE_CONFLICT | i;
fn_fin = str;
result |= FEATURE_IN_FILE;
} else if (str == "-O") {
++i;
str = argv[i];
if (!fn_fout.empty() && fn_fout != str)
return FEATURE_CONFLICT | i;
fn_fout = str;
result |= FEATURE_OUT_FILE;
} else if (str == "-h" || str == "--help") {
return FEATURE_LIST_ARGS;
} else {
return FEATURE_PANIC | i;
}
}
if (result & FEATURE_IN_FILE) {
std::ifstream fin(fn_fin);
if (!fin.good())
return FEATURE_PANIC_FILE | FEATURE_IN_FILE;
in = std::make_unique<file_input>(std::move(fin));
} else if (!(result & FEATURE_NCURSES))
in = std::make_unique<console_input>(std::cin);
if (result & FEATURE_OUT_FILE) {
std::ofstream fout(fn_fout);
if (!fout.good())
return FEATURE_PANIC_FILE | FEATURE_OUT_FILE;
out = std::make_unique<file_output>(std::move(fout));
} else if (!(result & FEATURE_NCURSES))
out = std::make_unique<console_output>(std::cout);
if (result & FEATURE_LOG) {
std::ofstream lout(fn_lout);
if (!lout.good())
return FEATURE_PANIC_FILE | FEATURE_LOG;
log = std::make_unique<logger>(std::move(lout));
}
if (result & FEATURE_NCURSES) {
curse = std::make_unique<cursor>();
in = std::make_unique<curses_input>(curse);
out = std::make_unique<curses_output>(curse);
}
return result;
}
// IMPORTANT: This is meant for already panicking
void panic_args(feature panic) {
using namespace std;
if (panic & FEATURE_PANIC)
cerr << "Invalid argument No. " << (panic ^ FEATURE_PANIC)
<< " !" << endl;
else if (panic & FEATURE_CONFLICT)
cerr << "Argument No. " << (panic ^ FEATURE_CONFLICT)
<< " conflicts with a previous argument!" << endl;
else if (panic & FEATURE_PANIC_FILE) {
switch (panic ^ FEATURE_PANIC_FILE) {
case FEATURE_IN_FILE:
cerr << "Cannot open specified input file!" << endl;
break;
case FEATURE_OUT_FILE:
cerr << "Cannot open specified output file!" << endl;
break;
case FEATURE_LOG:
cerr << "Cannot open specified log file!" << endl;
break;
default:
cerr << "Something must have went really, really, wrong..."
<< endl;
}
} else
cerr << "Something must have went really, really, wrong..."
<< endl;
}

View File

@ -16,17 +16,20 @@
-i : Enable inventory
-t : Enable throw
-R : Enable revisiting levels
-S [seed] : Sets initial seed to seed
-s [file] : Enable saves
-s [seed] : Sets initial seed to seed
-L [file] : Enable logging to file
-I [file] : Reads commands from file. CANNOT BE USED WITH -n.
-O [file] : Outputs to file. CANNOT BE USED WITH -n.
-h/--help : Displays options list (doesn't start a game)
*/
// IMPORTANT: Errors include the index that caused them (or'ed into them)
feature proc_args(int argc, char **argv,
std::unique_ptr<cursor> &curse,
std::unique_ptr<input> &in,
std::unique_ptr<display> &out,
std::unique_ptr<logger> &log);
void panic_args(feature panic);
#endif

View File

@ -103,8 +103,8 @@ void character_list::print() const {
void character_list::print(display &display) const {
for (auto &ch : characters)
display.print_position(ch->get_position(),
CHARACTER_REP[ch->get_race()]);
display.print_char(ch->get_position(),
CHARACTER_REP[ch->get_race()]);
}
std::vector<std::unique_ptr<character>>::const_iterator character_list::begin()

View File

@ -5,7 +5,7 @@
#include <ncurses.h>
console_output::console_output(std::ostream &new_out): out{new_out} {}
console_output::console_output(std::ostream &cout): out{cout} {}
/* Attributes
black 30 40

View File

@ -9,7 +9,7 @@ private:
std::ostream &out;
std::string get_code(const int attr);
public:
console_output(std::ostream &new_out);
console_output(std::ostream &cout);
void render() override;
void clear() override;

View File

@ -77,9 +77,17 @@ const feature FEATURE_INVENTORY = 1 << 3;
const feature FEATURE_THROW = 1 << 4;
const feature FEATURE_REVISIT = 1 << 5;
const feature FEATURE_LOG = 1 << 6;
const feature FEATURE_SAVE = 1 << 7;
const feature FEATURE_SEED = 1 << 7;
const feature FEATURE_MENU = 1 << 8;
const feature FEATURE_IN_FILE = 1 << 9;
const feature FEATURE_OUT_FILE = 1 << 10;
const feature FEATURE_PANIC_FILE = 1 << 28;
const feature FEATURE_PANIC = 1 << 29;
const feature FEATURE_CONFLICT = 1 << 30;
const feature FEATURE_LIST_ARGS = 1 << 31;
const int RETURN_FINE = 0;
const int RETURN_PANICKED = 1;
typedef std::vector<position> position_list;
typedef std::vector<direction> direction_list;

View File

@ -2,8 +2,8 @@
#include <utility>
file_output::file_output(std::ofstream &&new_out):
out{std::move(new_out)} {}
file_output::file_output(std::ofstream &&ofs):
out{std::move(ofs)} {}
void file_output::render() {
for (std::size_t idx = 0; idx < contents.size(); ++idx) {

View File

@ -8,7 +8,7 @@ class file_output final : public display {
private:
std::ofstream out;
public:
file_output(std::ofstream &&new_out);
file_output(std::ofstream &&ofs);
void render() override;
void clear() override;

View File

@ -1,6 +1,26 @@
#ifndef __LOG_H__
#define __LOG_H__
#include <fstream>
#include <string>
#include <memory>
#include "constants.h"
#include "characters.h"
#include "objects.h"
class logger;
class logger final {
private:
std::ofstream out;
public:
logger(std::ofstream &&new_out);
// called once every turn
void render();
void print_char(const position &pos, const char ch);
void print_str(const position &pos, const std::string &str);
void print_turn(const unsigned turn);
void print_player(std::unique_ptr<character> &player);
void print_chlist(const character_list &chlist);
void print_potions(const potion_list &potions);
};
#endif

View File

@ -1,12 +1,6 @@
#include "game.h"
#include "cursor.h"
#include "display.h"
#include "input.h"
#include "arguments.h"
// The way things are designed to work:
// to be filled...
int main(int argc, char **argv) {
std::unique_ptr<cursor> curse;
std::unique_ptr<input> in;
@ -15,13 +9,16 @@ int main(int argc, char **argv) {
feature enabled_features = proc_args(argc, argv, curse, in, out, log);
if (enabled_features & FEATURE_PANIC)
std::cerr << "Wrong arguments you dumbass :)" << std::endl;
if (enabled_features &
(FEATURE_PANIC | FEATURE_PANIC_FILE | FEATURE_CONFLICT)) {
panic_args(enabled_features);
return RETURN_PANICKED;
}
game game_proc(enabled_features, in, out, log);
while (game_proc.run() != game_status::terminated)
out->render();
return 0;
return RETURN_FINE;
}

View File

@ -49,7 +49,7 @@ void game_map::print() const {
void game_map::print(display &display) const {
for (int i = 0; i < MAP_HEIGHT; ++i)
display.print_line(map[i] + "\n", i);
display.print_str(position{0, i}, map[i]);
}
void game_map::apply_potion(character *who, const stat_name statn,