|
|
|
#pragma once
|
|
|
|
#include <vector>
|
|
|
|
#include <utility>
|
|
|
|
#include <string>
|
|
|
|
#include <random>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <fmt/core.h>
|
|
|
|
|
|
|
|
#define INV_WALL 0
|
|
|
|
#define INV_SPACE 1
|
|
|
|
#define WALL_VALUE 1
|
|
|
|
#define SPACE_VALUE 0
|
|
|
|
#define WALL_TILE "█"
|
|
|
|
#define FLOOR_TILE "#"
|
|
|
|
#define PLAYER_TILE "☺"
|
|
|
|
#define ENEMY_TILE "Ω"
|
|
|
|
|
|
|
|
struct Point {
|
|
|
|
size_t x = 0;
|
|
|
|
size_t y = 0;
|
|
|
|
|
|
|
|
bool operator==(const Point& other) const {
|
|
|
|
return other.x == x && other.y == y;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Room {
|
|
|
|
size_t x = 0;
|
|
|
|
size_t y = 0;
|
|
|
|
size_t width = 0;
|
|
|
|
size_t height = 0;
|
|
|
|
Point entry;
|
|
|
|
Point exit;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef std::vector<Point> PointList;
|
|
|
|
typedef std::vector<int> MatrixRow;
|
|
|
|
typedef std::vector<MatrixRow> Matrix;
|
|
|
|
|
|
|
|
void dump_map(const std::string &msg, Matrix &map);
|
|
|
|
void add_neighbors(Matrix &closed, size_t j, size_t i);
|
|
|
|
|
|
|
|
class Map {
|
|
|
|
Matrix $input_map;
|
|
|
|
Matrix $walls;
|
|
|
|
Matrix $paths;
|
|
|
|
std::vector<Room> $rooms;
|
|
|
|
int $limit = 0;
|
|
|
|
public:
|
|
|
|
|
|
|
|
// make explicit
|
|
|
|
Map(Matrix input_map, Matrix walls_map, int limit) :
|
|
|
|
$input_map(input_map),
|
|
|
|
$walls(walls_map), $limit(limit) {
|
|
|
|
}
|
|
|
|
|
|
|
|
// make random
|
|
|
|
Map(size_t width, size_t height);
|
|
|
|
|
|
|
|
// disable copying
|
|
|
|
Map(Map &map) = delete;
|
|
|
|
|
|
|
|
Matrix& paths() { return $paths; }
|
|
|
|
Matrix& input_map() { return $input_map; }
|
|
|
|
Matrix& walls() { return $walls; }
|
|
|
|
int limit() { return $limit; }
|
|
|
|
size_t width() { return $walls[0].size(); }
|
|
|
|
size_t height() { return $walls.size(); }
|
|
|
|
Room &room(size_t at) {
|
|
|
|
return $rooms[at];
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t room_count() {
|
|
|
|
return $rooms.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
void make_room(size_t origin_y, size_t origin_x, size_t width, size_t height);
|
|
|
|
|
|
|
|
void add_door(Room &room);
|
|
|
|
bool inmap(size_t x, size_t y);
|
|
|
|
bool iswall(size_t x, size_t y);
|
|
|
|
bool neighbors(Point &out, bool up);
|
|
|
|
void generate();
|
|
|
|
void place_rooms(Room &root);
|
|
|
|
void make_paths();
|
|
|
|
void partition_map(Room &cur, int depth);
|
|
|
|
void set_target(const Point &at, int value=0);
|
|
|
|
void clear_target(const Point &at);
|
|
|
|
bool walk(Point &src, Point &target);
|
|
|
|
void set_door(Room &room, int value);
|
|
|
|
void dump();
|
|
|
|
Point place_entity(size_t room_index);
|
|
|
|
|
|
|
|
Point map_to_camera(const Point &loc, const Point &cam_orig) {
|
|
|
|
return {loc.x - cam_orig.x, loc.y - cam_orig.y};
|
|
|
|
}
|
|
|
|
|
|
|
|
Point center_camera(const Point &around, size_t view_x, size_t view_y) {
|
|
|
|
size_t start_x = std::clamp(int(around.x - view_x / 2), 0, int(width() - view_x));
|
|
|
|
size_t start_y = std::clamp(int(around.y - view_y / 2), 0, int(height() - view_y));
|
|
|
|
return {start_x, start_y};
|
|
|
|
}
|
|
|
|
};
|