#ifndef __MAP_H__ #define __MAP_H__ #include #include #include #include "constants.h" #include "display.h" #include "position.h" #include "rng.h" #include "fraction.h" class game_map final { private: static const int MAX_ROOM_CNT = 20; static const int MIN_ROOM_WIDTH = 3; static const int MIN_ROOM_HEIGHT = 3; static const int MAX_ROOM_WIDTH = 20; static const int MAX_ROOM_HEIGHT = 5; // setup safezones static const int ACTUAL_MAP_WIDTH = MAP_WIDTH - 5; static const int ACTUAL_MAP_HEIGHT = MAP_HEIGHT - 5; static const int MAP_PADDING = 3; static const int MIN_ROOM_SPACING = 3; static const int WIDTH_RESERVED = 6; static const int HEIGHT_RESERVED = 3; const feature enabled_features; std::vector map; // IMPORTANT: keep empty_spots ordered position_list empty_spots; position up_stairs; position down_stairs; public: struct room { int top; int left; int width; int height; position ldoor; position rdoor; position tdoor; position bdoor; bool operator!=(const room &r) { return !(*this == r); } bool operator==(const room &r) { return top == r.top && left == r.left && width == r.width && height == r.height; } }; // randomly generate a map game_map(RNG *rng, const feature enabled_features); // read map from a string game_map(const std::string &map_data, RNG *rng, const feature enabled_features); bool is_available(const position &pos) const; position_list get_available_around(const position &pos) const; position_list get_room_list(int idx) const; std::vector get_room_list() const; // IMPORTANT: always print a map before anything else void print(display *out) const; position get_up_stairs() const; position get_down_stairs() const; int get_up_stairs_room() const; int get_down_stairs_room() const; int get_room_cnt() const; room get_room(std::size_t idx) const; private: std::vector room_data; position remap_index(const int idx) const { return {idx % MAP_WIDTH, idx / MAP_WIDTH}; } int remap_position(const position &pos) const { return pos.y * MAP_WIDTH + pos.x; } position random_size(int min_width, int min_height, int max_width, int max_height, RNG *rng); std::vector> gen_room_dims(RNG *rng); std::vector distr_rooms(RNG *rng, std::vector> &room_dims, std::vector> &layer_data); bool overlap_x(room &room1, room &room2); bool overlap_y(room &room1, room &room2); // has anything between the two bool between_x(room &room1, room &room2); bool between_y(room &room1, room &room2); void jitter(RNG *rng, std::vector &rooms); void fill_room(const room &r, const int num); void fill_outline(); void gen_path(std::vector> &layer_data, RNG *rng); // IMPORTANT: assumes room1 is to the left of room 2 void connect_x(room &room1, room &room2, RNG *rng); // IMPORTANT: assumes room1 is under room2 void connect_y(room &room1, room &room2, RNG *rng); void connect(position s, position t); room hit_room(const position &a); bool hit_room(const position &a, const room &r); }; const std::string default_map = "|-----------------------------------------------------------------------------|\ | |\ | |--------------------------| |-----------------------| |\ | |11111111111111111111111111| |33333333333333333333333| |\ | |11111111111111111111111111+########+33333333333333333333333|-------| |\ | |11111111111111111111111111| # |3333333333333333333333333333333|--| |\ | |11111111111111111111111111| # |3333333333333333333333333333333333|--| |\ | |----------+---------------| # |----+----------------|333333333333333| |\ | # ############# |333333333333333| |\ | # # |-----+------| |333333333333333| |\ | # # |444444444444| |333333333333333| |\ | ################### |444444444444| ######+333333333333333| |\ | # # |444444444444| # |333333333333333| |\ | # # |-----+------| # |--------+------| |\ | |---------+-----------| # # # # |\ | |222222222222222222222| # # # |----+------| |\ | |222222222222222222222| ######################## |00000000000| |\ | |222222222222222222222| # # |00000000000| |\ | |222222222222222222222| # |------+--------------------|00000000000| |\ | |222222222222222222222| # |000000000000000000000000000000000000000| |\ | |222222222222222222222+##########+000000000000000000000000000000000000000| |\ | |222222222222222222222| |000000000000000000000000000000000000000| |\ | |---------------------| |---------------------------------------| |\ | |\ |-----------------------------------------------------------------------------|"; #endif